about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes6
-rw-r--r--Cargo.lock5
-rw-r--r--compiler/rustc_ast/src/ast.rs98
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs263
-rw-r--r--compiler/rustc_ast/src/entry.rs4
-rw-r--r--compiler/rustc_ast/src/lib.rs12
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs22
-rw-r--r--compiler/rustc_ast/src/util/classify.rs6
-rw-r--r--compiler/rustc_ast/src/util/comments/tests.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs12
-rw-r--r--compiler/rustc_ast_lowering/src/block.rs19
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs63
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs4
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs6
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs25
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs19
-rw-r--r--compiler/rustc_attr/src/builtin.rs266
-rw-r--r--compiler/rustc_borrowck/src/borrow_set.rs50
-rw-r--r--compiler/rustc_borrowck/src/consumers.rs4
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs93
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs69
-rw-r--r--compiler/rustc_borrowck/src/lib.rs59
-rw-r--r--compiler/rustc_borrowck/src/nll.rs2
-rw-r--r--compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs (renamed from compiler/rustc_borrowck/src/polonius/loan_invalidations.rs)0
-rw-r--r--compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs (renamed from compiler/rustc_borrowck/src/polonius/loan_kills.rs)0
-rw-r--r--compiler/rustc_borrowck/src/polonius/legacy/mod.rs184
-rw-r--r--compiler/rustc_borrowck/src/polonius/mod.rs185
-rw-r--r--compiler/rustc_borrowck/src/type_check/canonical.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/polonius.rs143
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_gcc/messages.ftl2
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs7
-rw-r--r--compiler/rustc_codegen_gcc/src/errors.rs1
-rw-r--r--compiler/rustc_codegen_gcc/src/gcc_util.rs20
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs15
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs29
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs23
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs67
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs59
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs34
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/src/assert_module_sources.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs38
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs96
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs70
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/naked_asm.rs266
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs57
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/asm.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs25
-rw-r--r--compiler/rustc_const_eval/src/check_consts/resolver.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs35
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs37
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/stack.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs13
-rw-r--r--compiler/rustc_data_structures/src/jobserver.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs42
-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/emitter.rs15
-rw-r--r--compiler/rustc_errors/src/lib.rs7
-rw-r--r--compiler/rustc_expand/src/base.rs18
-rw-r--r--compiler/rustc_expand/src/expand.rs32
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs4
-rw-r--r--compiler/rustc_expand/src/module.rs10
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/removed.rs3
-rw-r--r--compiler/rustc_feature/src/unstable.rs10
-rw-r--r--compiler/rustc_hir/Cargo.toml1
-rw-r--r--compiler/rustc_hir/src/arena.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs310
-rw-r--r--compiler/rustc_hir/src/intravisit.rs13
-rw-r--r--compiler/rustc_hir/src/lang_items.rs8
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs10
-rw-r--r--compiler/rustc_hir/src/tests.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl14
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs118
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs47
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs216
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs45
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs52
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs249
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs33
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs148
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs25
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs45
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs34
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs17
-rw-r--r--compiler/rustc_hir_typeck/src/gather_locals.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs560
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs30
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs2
-rw-r--r--compiler/rustc_incremental/src/assert_dep_graph.rs4
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs6
-rw-r--r--compiler/rustc_interface/src/interface.rs8
-rw-r--r--compiler/rustc_interface/src/passes.rs14
-rw-r--r--compiler/rustc_interface/src/queries.rs12
-rw-r--r--compiler/rustc_interface/src/util.rs4
-rw-r--r--compiler/rustc_lint/messages.ftl4
-rw-r--r--compiler/rustc_lint/src/async_closures.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs8
-rw-r--r--compiler/rustc_lint/src/context.rs36
-rw-r--r--compiler/rustc_lint/src/dangling.rs2
-rw-r--r--compiler/rustc_lint/src/early.rs119
-rw-r--r--compiler/rustc_lint/src/early/diagnostics.rs (renamed from compiler/rustc_lint/src/context/diagnostics.rs)12
-rw-r--r--compiler/rustc_lint/src/early/diagnostics/check_cfg.rs (renamed from compiler/rustc_lint/src/context/diagnostics/check_cfg.rs)74
-rw-r--r--compiler/rustc_lint/src/if_let_rescope.rs1
-rw-r--r--compiler/rustc_lint/src/levels.rs15
-rw-r--r--compiler/rustc_lint/src/lints.rs97
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs63
-rw-r--r--compiler/rustc_lint/src/passes.rs6
-rw-r--r--compiler/rustc_lint/src/tests.rs2
-rw-r--r--compiler/rustc_lint/src/types.rs39
-rw-r--r--compiler/rustc_lint/src/unqualified_local_imports.rs2
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs7
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp2
-rw-r--r--compiler/rustc_metadata/src/creader.rs9
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs22
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/arena.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs6
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/middle/dependency_format.rs3
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs32
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs3
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs17
-rw-r--r--compiler/rustc_middle/src/query/keys.rs11
-rw-r--r--compiler/rustc_middle/src/query/mod.rs9
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs2
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs10
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs23
-rw-r--r--compiler/rustc_middle/src/traits/query.rs12
-rw-r--r--compiler/rustc_middle/src/ty/context.rs21
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs39
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs52
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs3
-rw-r--r--compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs95
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs43
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
-rw-r--r--compiler/rustc_middle/src/values.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/custom/mod.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs92
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs16
-rw-r--r--compiler/rustc_mir_build/src/build/matches/match_pair.rs5
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs16
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs18
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/cursor.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs88
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/lattice.rs63
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/mod.rs82
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/results.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs48
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/visitor.rs21
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs12
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/initialized.rs102
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs44
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/mod.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs78
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs2
-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_dataflow/src/points.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs12
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs32
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs13
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs56
-rw-r--r--compiler/rustc_mir_transform/src/strip_debuginfo.rs34
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs8
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs5
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs40
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs100
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs5
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs6
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs35
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs8
-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_parse/src/parser/ty.rs19
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs8
-rw-r--r--compiler/rustc_passes/src/abi_test.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs27
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs5
-rw-r--r--compiler/rustc_passes/src/input_stats.rs44
-rw-r--r--compiler/rustc_passes/src/layout_test.rs2
-rw-r--r--compiler/rustc_passes/src/lib_features.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs3
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs1
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs4
-rw-r--r--compiler/rustc_query_system/src/ich/impls_syntax.rs28
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs6
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs6
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs9
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/ident.rs82
-rw-r--r--compiler/rustc_resolve/src/imports.rs8
-rw-r--r--compiler/rustc_resolve/src/late.rs29
-rw-r--r--compiler/rustc_resolve/src/lib.rs7
-rw-r--r--compiler/rustc_resolve/src/macros.rs6
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs39
-rw-r--r--compiler/rustc_session/src/config.rs16
-rw-r--r--compiler/rustc_session/src/config/cfg.rs2
-rw-r--r--compiler/rustc_session/src/options.rs14
-rw-r--r--compiler/rustc_session/src/session.rs10
-rw-r--r--compiler/rustc_smir/Cargo.toml2
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs11
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs7
-rw-r--r--compiler/rustc_span/src/edit_distance/tests.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_span/src/lib.rs7
-rw-r--r--compiler/rustc_span/src/symbol.rs13
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs29
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs2
-rw-r--r--compiler/rustc_target/src/callconv/powerpc64.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs12
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/target_features.rs857
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs115
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs7
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs59
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs58
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs14
-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--compiler/stable_mir/src/mir/body.rs8
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs4
-rw-r--r--compiler/stable_mir/src/ty.rs11
-rw-r--r--compiler/stable_mir/src/visitor.rs1
-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/collections/vec_deque/mod.rs23
-rw-r--r--library/alloc/src/ffi/c_str.rs3
-rw-r--r--library/alloc/src/lib.rs4
-rw-r--r--library/alloc/src/rc.rs253
-rw-r--r--library/alloc/src/string.rs69
-rw-r--r--library/alloc/src/sync.rs3
-rw-r--r--library/alloc/src/vec/mod.rs28
-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/convert/mod.rs2
-rw-r--r--library/core/src/error.rs4
-rw-r--r--library/core/src/fmt/rt.rs34
-rw-r--r--library/core/src/hint.rs92
-rw-r--r--library/core/src/iter/traits/collect.rs63
-rw-r--r--library/core/src/lib.rs2
-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/mod.rs9
-rw-r--r--library/core/src/ptr/mut_ptr.rs9
-rw-r--r--library/core/src/slice/mod.rs24
-rw-r--r--library/core/src/unsafe_binder.rs25
-rw-r--r--library/proc_macro/src/bridge/symbol.rs6
-rw-r--r--library/proc_macro/src/lib.rs77
-rw-r--r--library/std/src/lib.rs4
-rw-r--r--library/std/src/os/fd/owned.rs8
-rw-r--r--library/std/src/os/fd/raw.rs8
-rw-r--r--library/std/src/os/hurd/mod.rs1
-rw-r--r--library/std/src/os/windows/io/handle.rs8
-rw-r--r--library/std/src/os/windows/io/socket.rs8
-rw-r--r--library/std/src/path.rs4
-rw-r--r--library/std/src/pipe.rs140
-rw-r--r--library/std/src/prelude/common.rs3
-rw-r--r--library/std/src/prelude/mod.rs21
-rw-r--r--library/std/src/sync/mutex.rs110
-rw-r--r--library/std/src/sync/mutex/tests.rs161
-rw-r--r--library/std/src/sync/poison.rs35
-rw-r--r--library/std/src/sync/rwlock.rs128
-rw-r--r--library/std/src/sync/rwlock/tests.rs169
-rw-r--r--library/std/src/sys/pal/hermit/fs.rs6
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs2
-rw-r--r--library/std/src/sys/pal/hermit/os.rs4
-rw-r--r--library/std/src/sys/pal/unix/net.rs1
-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.rs4
-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.rs10
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs14
-rw-r--r--src/bootstrap/src/core/builder/mod.rs14
-rw-r--r--src/bootstrap/src/core/config/config.rs86
-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.rs20
-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
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/test-various/Dockerfile4
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile9
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile9
-rwxr-xr-xsrc/ci/docker/scripts/add_dummy_commit.sh19
-rwxr-xr-xsrc/ci/docker/scripts/x86_64-gnu-llvm.sh37
-rwxr-xr-xsrc/ci/docker/scripts/x86_64-gnu-llvm1.sh12
-rwxr-xr-xsrc/ci/docker/scripts/x86_64-gnu-llvm2.sh25
-rwxr-xr-xsrc/ci/docker/scripts/x86_64-gnu-llvm3.sh25
-rw-r--r--src/ci/github-actions/jobs.yml51
-rw-r--r--src/doc/rustc/src/SUMMARY.md2
-rw-r--r--src/doc/rustc/src/platform-support.md6
-rw-r--r--src/doc/rustc/src/platform-support/solaris.md32
-rw-r--r--src/doc/rustdoc/src/read-documentation/search.md25
-rw-r--r--src/librustdoc/clean/inline.rs22
-rw-r--r--src/librustdoc/clean/mod.rs37
-rw-r--r--src/librustdoc/clean/types.rs48
-rw-r--r--src/librustdoc/clean/utils.rs2
-rw-r--r--src/librustdoc/doctest.rs4
-rw-r--r--src/librustdoc/doctest/make.rs60
-rw-r--r--src/librustdoc/doctest/rust.rs2
-rw-r--r--src/librustdoc/html/format.rs5
-rw-r--r--src/librustdoc/html/render/print_item.rs6
-rw-r--r--src/librustdoc/html/render/search_index.rs10
-rw-r--r--src/librustdoc/html/static/js/search.js7
-rw-r--r--src/librustdoc/json/conversions.rs8
-rw-r--r--src/librustdoc/lib.rs4
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/inline_always.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/duplicate_mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_nesting.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_to_string.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_include_file.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_float_methods.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs58
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs31
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs16
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr3
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr1
-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.stderr13
-rw-r--r--src/tools/clippy/tests/ui/author/blocks.rs1
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr1
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr6
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.stderr10
-rw-r--r--src/tools/clippy/tests/ui/copy_iterator.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-360.stderr8
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr3
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.stderr1
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr3
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr3
-rw-r--r--src/tools/clippy/tests/ui/entry.stderr5
-rw-r--r--src/tools/clippy/tests/ui/enum_variants.stderr3
-rw-r--r--src/tools/clippy/tests/ui/fallible_impl_from.stderr3
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.rs1
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.stderr55
-rw-r--r--src/tools/clippy/tests/ui/into_iter_without_iter.stderr8
-rw-r--r--src/tools/clippy/tests/ui/manual_find.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_find_fixable.stderr36
-rw-r--r--src/tools/clippy/tests/ui/manual_flatten.stderr1
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.stderr4
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.stderr2
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.stderr3
-rw-r--r--src/tools/clippy/tests/ui/match_bool.stderr3
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr3
-rw-r--r--src/tools/clippy/tests/ui/missing_doc.stderr1
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr4
-rw-r--r--src/tools/clippy/tests/ui/missing_fields_in_debug.stderr3
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr1
-rw-r--r--src/tools/clippy/tests/ui/needless_if.stderr1
-rw-r--r--src/tools/clippy/tests/ui/never_loop.stderr5
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.stderr3
-rw-r--r--src/tools/clippy/tests/ui/question_mark.stderr3
-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/clippy/tests/ui/significant_drop_tightening.stderr3
-rw-r--r--src/tools/clippy/tests/ui/single_match.stderr5
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr6
-rw-r--r--src/tools/clippy/tests/ui/temporary_assignment.stderr3
-rw-r--r--src/tools/clippy/tests/ui/to_string_trait_impl.rs43
-rw-r--r--src/tools/clippy/tests/ui/to_string_trait_impl.stderr14
-rw-r--r--src/tools/clippy/tests/ui/unit_cmp.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_wraps.stderr3
-rw-r--r--src/tools/clippy/tests/ui/unwrap_in_result.stderr1
-rw-r--r--src/tools/clippy/tests/ui/vec_init_then_push.stderr3
-rw-r--r--src/tools/clippy/tests/ui/while_let_loop.stderr2
-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.rs95
-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/run_make.rs13
-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/src/helpers.rs5
-rw-r--r--src/tools/miri/src/machine.rs8
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr3
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr1
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr1
-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--src/tools/run-make-support/src/assertion_helpers.rs58
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs6
-rw-r--r--src/tools/rust-analyzer/.github/workflows/ci.yaml2
-rw-r--r--src/tools/rust-analyzer/.typos.toml7
-rw-r--r--src/tools/rust-analyzer/Cargo.lock6
-rw-r--r--src/tools/rust-analyzer/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/edition/Cargo.toml13
-rw-r--r--src/tools/rust-analyzer/crates/edition/src/lib.rs (renamed from src/tools/rust-analyzer/crates/parser/src/edition.rs)3
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/interner.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs100
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs35
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs1402
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs44
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs34
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests.rs319
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs36
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs44
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs7414
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs37
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs111
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/search.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs45
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs65
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs39
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/interpret.rs35
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs10
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs1
-rw-r--r--src/tools/rust-analyzer/crates/load-cargo/src/lib.rs46
-rw-r--r--src/tools/rust-analyzer/crates/parser/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs49
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs29
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs58
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs86
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs34
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs44
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs5
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs34
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs6
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs45
-rw-r--r--src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs11
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs24
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs67
-rw-r--r--src/tools/rust-analyzer/docs/user/manual.adoc2
-rw-r--r--src/tools/rust-analyzer/editors/code/src/client.ts2
-rw-r--r--src/tools/rust-analyzer/xtask/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/lints.rs380
-rw-r--r--src/tools/rustfmt/src/expr.rs3
-rw-r--r--src/tools/rustfmt/src/items.rs2
-rw-r--r--src/tools/rustfmt/src/modules.rs7
-rw-r--r--src/tools/rustfmt/src/types.rs25
-rw-r--r--src/tools/rustfmt/src/utils.rs1
-rw-r--r--src/tools/rustfmt/src/visitor.rs2
-rw-r--r--src/tools/rustfmt/tests/source/unsafe-binders.rs11
-rw-r--r--src/tools/rustfmt/tests/target/unsafe-binders.rs9
-rw-r--r--tests/codegen/async-closure-debug.rs2
-rw-r--r--tests/codegen/bounds-checking/gep-issue-133979.rs22
-rw-r--r--tests/codegen/gep-index.rs37
-rw-r--r--tests/codegen/mem-replace-big-type.rs5
-rw-r--r--tests/codegen/naked-asan.rs11
-rw-r--r--tests/codegen/naked-fn/aligned.rs9
-rw-r--r--tests/codegen/naked-fn/generics.rs116
-rw-r--r--tests/codegen/naked-fn/instruction-set.rs59
-rw-r--r--tests/codegen/naked-fn/naked-functions.rs150
-rw-r--r--tests/codegen/naked-fn/naked-nocoverage.rs19
-rw-r--r--tests/codegen/naked-fn/naked-noinline.rs31
-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/123862.rs14
-rw-r--r--tests/crashes/124375.rs11
-rw-r--r--tests/crashes/130395.rs10
-rw-r--r--tests/crashes/130797.rs23
-rw-r--r--tests/crashes/132103.rs21
-rw-r--r--tests/crashes/132765.rs12
-rw-r--r--tests/crashes/132766.rs9
-rw-r--r--tests/crashes/132882.rs13
-rw-r--r--tests/crashes/132960.rs36
-rw-r--r--tests/crashes/132981.rs7
-rw-r--r--tests/crashes/133063.rs8
-rw-r--r--tests/crashes/133066.rs12
-rw-r--r--tests/crashes/133117.rs8
-rw-r--r--tests/crashes/133199.rs11
-rw-r--r--tests/crashes/133252.rs43
-rw-r--r--tests/crashes/133275-1.rs13
-rw-r--r--tests/crashes/133275-2.rs15
-rw-r--r--tests/crashes/133426.rs12
-rw-r--r--tests/crashes/133597.rs11
-rw-r--r--tests/crashes/133613.rs7
-rw-r--r--tests/crashes/133639.rs33
-rw-r--r--tests/crashes/133808.rs15
-rw-r--r--tests/crashes/133868.rs13
-rw-r--r--tests/crashes/133965.rs9
-rw-r--r--tests/crashes/133966.rs3
-rw-r--r--tests/crashes/134005.rs5
-rw-r--r--tests/crashes/134061.rs4
-rw-r--r--tests/crashes/134174.rs17
-rw-r--r--tests/crashes/134217.rs9
-rw-r--r--tests/crashes/134334.rs9
-rw-r--r--tests/crashes/134335.rs12
-rw-r--r--tests/crashes/auxiliary/aux133199.rs13
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir8
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir8
-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/mir-opt/building/index_array_and_slice.index_array.built.after.mir31
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir31
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir34
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir34
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir32
-rw-r--r--tests/mir-opt/building/index_array_and_slice.rs71
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff13
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff13
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff13
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff13
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff7
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff7
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff7
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff7
-rw-r--r--tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff12
-rw-r--r--tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff12
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.rs3
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.rs2
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.rs3
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.rs34
-rw-r--r--tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff4
-rw-r--r--tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff4
-rw-r--r--tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff72
-rw-r--r--tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff72
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff48
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff48
-rw-r--r--tests/mir-opt/gvn.rs20
-rw-r--r--tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff302
-rw-r--r--tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff302
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff1
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff1
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff77
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff77
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.rs15
-rw-r--r--tests/mir-opt/issue_72181.foo.built.after.mir9
-rw-r--r--tests/mir-opt/issue_72181.main.built.after.mir9
-rw-r--r--tests/mir-opt/issue_91633.foo.built.after.mir12
-rw-r--r--tests/mir-opt/issue_91633.fun.built.after.mir2
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff20
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff20
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff43
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff43
-rw-r--r--tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff2
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir47
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir47
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.rs2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir30
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir30
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir79
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir79
-rw-r--r--tests/mir-opt/strip_debuginfo.rs39
-rw-r--r--tests/run-make/link-args-order/rmake.rs6
-rw-r--r--tests/run-make/link-dedup/rmake.rs12
-rw-r--r--tests/run-make/linker-warning/fake-linker.rs13
-rw-r--r--tests/run-make/linker-warning/main.rs1
-rw-r--r--tests/run-make/linker-warning/rmake.rs28
-rw-r--r--tests/run-make/musl-default-linking/rmake.rs62
-rw-r--r--tests/rustdoc-js-std/osstring-to-string.js2
-rw-r--r--tests/rustdoc-js/impl-trait-inlining.js35
-rw-r--r--tests/rustdoc-js/impl-trait-inlining.rs11
-rw-r--r--tests/rustdoc-js/reexport.js9
-rw-r--r--tests/rustdoc-js/reexport.rs9
-rw-r--r--tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr2
-rw-r--r--tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs15
-rw-r--r--tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout31
-rw-r--r--tests/rustdoc-ui/doctest/comment-in-attr-134221.rs27
-rw-r--r--tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout50
-rw-r--r--tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr7
-rw-r--r--tests/rustdoc-ui/lints/check-attr.stderr36
-rw-r--r--tests/rustdoc-ui/lints/check.stderr1
-rw-r--r--tests/rustdoc-ui/unescaped_backticks.stderr12
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs2
-rw-r--r--tests/ui/alias-uninit-value.rs19
-rw-r--r--tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr6
-rw-r--r--tests/ui/allow-non-lint-warnings.rs8
-rw-r--r--tests/ui/artificial-block.rs5
-rw-r--r--tests/ui/as-precedence.rs10
-rw-r--r--tests/ui/asm/aarch64/srcloc.new.stderr320
-rw-r--r--tests/ui/asm/aarch64/srcloc.old.stderr (renamed from tests/ui/asm/aarch64/srcloc.stderr)48
-rw-r--r--tests/ui/asm/aarch64/srcloc.rs3
-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/inline-syntax.arm.stderr24
-rw-r--r--tests/ui/asm/inline-syntax.arm_llvm_18.stderr90
-rw-r--r--tests/ui/asm/inline-syntax.rs16
-rw-r--r--tests/ui/asm/inline-syntax.x86_64.stderr14
-rw-r--r--tests/ui/asm/naked-functions-instruction-set.rs2
-rw-r--r--tests/ui/asm/named_const_simd_vec_len.rs22
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr64
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr194
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr64
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr194
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr64
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr194
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.rs14
-rw-r--r--tests/ui/asm/x86_64/srcloc.new.stderr332
-rw-r--r--tests/ui/asm/x86_64/srcloc.old.stderr (renamed from tests/ui/asm/x86_64/srcloc.stderr)50
-rw-r--r--tests/ui/asm/x86_64/srcloc.rs3
-rw-r--r--tests/ui/associated-consts/issue-93775.rs4
-rw-r--r--tests/ui/associated-types/associated-types-eq-2.stderr6
-rw-r--r--tests/ui/associated-types/issue-59324.stderr4
-rw-r--r--tests/ui/associated-types/missing-associated-types.stderr4
-rw-r--r--tests/ui/async-await/async-block-control-flow-static-semantics.stderr1
-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/dont-ice-for-type-mismatch-in-closure-in-async.stderr1
-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/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/issue-84841.stderr3
-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/issues/issue-72312.stderr5
-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.afn.stderr3
-rw-r--r--tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr3
-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/attributes/collapse-debuginfo-invalid.stderr1
-rw-r--r--tests/ui/attributes/dump_def_parents.stderr4
-rw-r--r--tests/ui/borrowck/borrowck-describe-lvalue.rs1
-rw-r--r--tests/ui/borrowck/borrowck-describe-lvalue.stderr25
-rw-r--r--tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr2
-rw-r--r--tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.rs8
-rw-r--r--tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr9
-rw-r--r--tests/ui/check-cfg/auxiliary/cfg_macro.rs16
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.cargo.stderr42
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.rs11
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.rustc.stderr41
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.stderr14
-rw-r--r--tests/ui/check-cfg/target_feature.stderr10
-rw-r--r--tests/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/by_value.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/capture-analysis-1.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/capture-analysis-2.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/capture-analysis-3.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/capture-analysis-4.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/capture-enums.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs6
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr40
-rw-r--r--tests/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/issue-118144.stderr5
-rw-r--r--tests/ui/closures/2229_closure_analysis/issue-87378.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/issue-88476.stderr16
-rw-r--r--tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr15
-rw-r--r--tests/ui/closures/2229_closure_analysis/move_closure.stderr48
-rw-r--r--tests/ui/closures/2229_closure_analysis/multilevel-path-2.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/nested-closure.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/path-with-array-access.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/repr_packed.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr6
-rw-r--r--tests/ui/closures/2229_closure_analysis/wild_patterns.stderr24
-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/codegen/alias-uninit-value.rs26
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg80
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg80
-rw-r--r--tests/ui/coercion/coerce-loop-issue-122561.stderr3
-rw-r--r--tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr5
-rw-r--r--tests/ui/const-generics/issues/issue-67945-2.full.stderr3
-rw-r--r--tests/ui/const-generics/issues/issue-71202.stderr1
-rw-r--r--tests/ui/const-generics/nested-type.min.stderr1
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr1
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.no_ice.stderr1
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr5
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr15
-rw-r--r--tests/ui/consts/const-eval/stable-metric/evade-deduplication-issue-118612.stderr20
-rw-r--r--tests/ui/consts/issue-65348.rs4
-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/coroutine/drop-tracking-parent-expression.stderr6
-rw-r--r--tests/ui/coroutine/issue-88653.stderr3
-rw-r--r--tests/ui/coroutine/match-bindings.stderr1
-rw-r--r--tests/ui/coroutine/parent-expression.stderr6
-rw-r--r--tests/ui/coroutine/too-live-local-in-immovable-gen.stderr3
-rw-r--r--tests/ui/coroutine/yield-in-initializer.stderr3
-rw-r--r--tests/ui/coverage-attr/name-value.stderr2
-rw-r--r--tests/ui/coverage-attr/word-only.stderr2
-rw-r--r--tests/ui/diagnostic-flags/allow-non-lint-warnings.rs27
-rw-r--r--tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr8
-rw-r--r--tests/ui/diagnostic-width/E0271.ascii.stderr1
-rw-r--r--tests/ui/diagnostic-width/E0271.unicode.stderr1
-rw-r--r--tests/ui/drop/lint-tail-expr-drop-order.stderr48
-rw-r--r--tests/ui/dyn-compatibility/assoc_type_bounds.rs4
-rw-r--r--tests/ui/dyn-compatibility/assoc_type_bounds.stderr4
-rw-r--r--tests/ui/dyn-compatibility/assoc_type_bounds2.rs4
-rw-r--r--tests/ui/dyn-compatibility/assoc_type_bounds2.stderr4
-rw-r--r--tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.rs15
-rw-r--r--tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr12
-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/errors/issue-89280-emitter-overflow-splice-lines.stderr3
-rw-r--r--tests/ui/expr/if/if-let-arm-types.stderr3
-rw-r--r--tests/ui/extern/issue-116203.stderr3
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.default.stderr (renamed from tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr)12
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.feature.stderr36
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs3
-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-impl-trait-in-bindings.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-impl-trait-in-bindings.stderr14
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-binders.rs7
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-binders.stderr13
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr10
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr6
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-derive.stderr2
-rw-r--r--tests/ui/for/for-else-err.stderr3
-rw-r--r--tests/ui/for/for-else-let-else-err.stderr3
-rw-r--r--tests/ui/generic-associated-types/collectivity-regression.stderr5
-rw-r--r--tests/ui/generics/overlapping-errors-span-issue-123861.rs8
-rw-r--r--tests/ui/generics/overlapping-errors-span-issue-123861.stderr52
-rw-r--r--tests/ui/higher-ranked/anonymous-higher-ranked-lifetime.rs (renamed from tests/ui/anonymous-higher-ranked-lifetime.rs)6
-rw-r--r--tests/ui/higher-ranked/anonymous-higher-ranked-lifetime.stderr (renamed from tests/ui/anonymous-higher-ranked-lifetime.stderr)44
-rw-r--r--tests/ui/impl-trait/in-bindings/bad-nesting.rs10
-rw-r--r--tests/ui/impl-trait/in-bindings/bad-nesting.stderr12
-rw-r--r--tests/ui/impl-trait/in-bindings/dont-make-def-id.rs10
-rw-r--r--tests/ui/impl-trait/in-bindings/escaping-bound-var.rs14
-rw-r--r--tests/ui/impl-trait/in-bindings/escaping-bound-var.stderr8
-rw-r--r--tests/ui/impl-trait/in-bindings/lifetime-failure.rs12
-rw-r--r--tests/ui/impl-trait/in-bindings/lifetime-failure.stderr16
-rw-r--r--tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.rs10
-rw-r--r--tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.stderr16
-rw-r--r--tests/ui/impl-trait/in-bindings/nesting.rs7
-rw-r--r--tests/ui/impl-trait/in-bindings/simple.rs10
-rw-r--r--tests/ui/impl-trait/in-bindings/trait-failure.rs13
-rw-r--r--tests/ui/impl-trait/in-bindings/trait-failure.stderr24
-rw-r--r--tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs13
-rw-r--r--tests/ui/impl-trait/issues/issue-54600.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-54840.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-58504.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-58956.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-70971.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-79099.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-84919.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-87295.stderr3
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr3
-rw-r--r--tests/ui/issues/auxiliary/issue-111011.rs2
-rw-r--r--tests/ui/issues/issue-18611.stderr3
-rw-r--r--tests/ui/issues/issue-28344.stderr4
-rw-r--r--tests/ui/issues/issue-51714.stderr20
-rw-r--r--tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr36
-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/let-else/let-else-deref-coercion.stderr10
-rw-r--r--tests/ui/lifetimes/could-not-resolve-issue-121503.stderr2
-rw-r--r--tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr9
-rw-r--r--tests/ui/lifetimes/issue-97194.stderr5
-rw-r--r--tests/ui/lint/fn-ptr-comparisons-134345.rs16
-rw-r--r--tests/ui/lint/lints-in-foreign-macros.stderr1
-rw-r--r--tests/ui/lint/non-local-defs/consts.stderr1
-rw-r--r--tests/ui/lint/non-local-defs/weird-exprs.stderr5
-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/loops/dont-suggest-break-thru-item.stderr6
-rw-r--r--tests/ui/loops/loop-else-err.stderr3
-rw-r--r--tests/ui/loops/loop-else-let-else-err.stderr3
-rw-r--r--tests/ui/lub-glb/old-lub-glb-hr-noteq1.leak.stderr3
-rw-r--r--tests/ui/macros/genercs-in-path-with-prettry-hir.stdout4
-rw-r--r--tests/ui/macros/stringify.rs1
-rw-r--r--tests/ui/match/match-incompat-type-semi.stderr3
-rw-r--r--tests/ui/match/match-type-err-first-arm.stderr9
-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/diverging-place-match.stderr3
-rw-r--r--tests/ui/never_type/fallback-closure-ret.nofallback.stderr4
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr5
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr5
-rw-r--r--tests/ui/nll/snocat-regression.stderr5
-rw-r--r--tests/ui/or-patterns/missing-bindings.stderr1
-rw-r--r--tests/ui/parser/as-precedence.rs18
-rw-r--r--tests/ui/parser/bad-name.stderr12
-rw-r--r--tests/ui/parser/brace-in-let-chain.rs4
-rw-r--r--tests/ui/parser/brace-in-let-chain.stderr30
-rw-r--r--tests/ui/parser/circular_modules_main.stderr19
-rw-r--r--tests/ui/parser/diff-markers/unclosed-delims-in-macro.rs6
-rw-r--r--tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr27
-rw-r--r--tests/ui/parser/diff-markers/unclosed-delims.rs14
-rw-r--r--tests/ui/parser/diff-markers/unclosed-delims.stderr27
-rw-r--r--tests/ui/parser/fn-arg-doc-comment.stderr8
-rw-r--r--tests/ui/privacy/effective_visibilities.stderr1
-rw-r--r--tests/ui/privacy/effective_visibilities_invariants.stderr1
-rw-r--r--tests/ui/privacy/issue-113860-1.stderr1
-rw-r--r--tests/ui/privacy/issue-113860-2.stderr1
-rw-r--r--tests/ui/privacy/issue-113860.stderr1
-rw-r--r--tests/ui/raw-ref-op/amp-raw-without-mut-const-is-a-normal-borrow.rs30
-rw-r--r--tests/ui/raw-ref-op/never-place-isnt-diverging.stderr3
-rw-r--r--tests/ui/reachable/artificial-block.rs30
-rw-r--r--tests/ui/resolve/parse-error-resolve.rs7
-rw-r--r--tests/ui/resolve/parse-error-resolve.stderr22
-rw-r--r--tests/ui/resolve/parse_error.rs5
-rw-r--r--tests/ui/resolve/parse_error.stderr13
-rw-r--r--tests/ui/return/issue-86188-return-not-in-fn-body.stderr6
-rw-r--r--tests/ui/return/return-match-array-const.stderr13
-rw-r--r--tests/ui/return/tail-expr-as-potential-return.stderr9
-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/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr4
-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_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_nonnull.rs13
-rw-r--r--tests/ui/self/arbitrary_self_types_nonnull.stderr23
-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/arbitrary_self_types_weak.rs13
-rw-r--r--tests/ui/self/arbitrary_self_types_weak.stderr23
-rw-r--r--tests/ui/self/conflicting_inner.rs38
-rw-r--r--tests/ui/self/conflicting_inner2.rs63
-rw-r--r--tests/ui/specialization/min_specialization/issue-79224.rs10
-rw-r--r--tests/ui/specialization/min_specialization/issue-79224.stderr13
-rw-r--r--tests/ui/stability-attribute/missing-stability-attr-at-top-level.stderr3
-rw-r--r--tests/ui/stability-attribute/stability-attribute-trait-impl.stderr1
-rw-r--r--tests/ui/stable-mir-print/async-closure.rs12
-rw-r--r--tests/ui/stable-mir-print/async-closure.stdout90
-rw-r--r--tests/ui/stable-mir-print/operands.stdout294
-rw-r--r--tests/ui/static/issue-24446.stderr10
-rw-r--r--tests/ui/structs/default-field-values/auxiliary/struct_field_default.rs (renamed from tests/ui/structs/auxiliary/struct_field_default.rs)0
-rw-r--r--tests/ui/structs/default-field-values/failures.rs (renamed from tests/ui/structs/default-field-values-failures.rs)0
-rw-r--r--tests/ui/structs/default-field-values/failures.stderr (renamed from tests/ui/structs/default-field-values-failures.stderr)30
-rw-r--r--tests/ui/structs/default-field-values/invalid-const.rs (renamed from tests/ui/structs/default-field-values-invalid-const.rs)0
-rw-r--r--tests/ui/structs/default-field-values/invalid-const.stderr (renamed from tests/ui/structs/default-field-values-invalid-const.stderr)6
-rw-r--r--tests/ui/structs/default-field-values/support.rs (renamed from tests/ui/structs/default-field-values-support.rs)0
-rw-r--r--tests/ui/structs/default-field-values/use-normalized-ty-for-default-struct-value.rs17
-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/if-then-neeing-semi.stderr17
-rw-r--r--tests/ui/suggestions/match-prev-arm-needing-semi.stderr14
-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-deref-in-match-issue-132784.rs84
-rw-r--r--tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr259
-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/suggestions/try-operator-dont-suggest-semicolon.stderr4
-rw-r--r--tests/ui/symbol-names/types.legacy.stderr20
-rw-r--r--tests/ui/symbol-names/types.rs11
-rw-r--r--tests/ui/symbol-names/types.v0.stderr20
-rw-r--r--tests/ui/symbol-names/types.verbose-legacy.stderr20
-rw-r--r--tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs11
-rw-r--r--tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs9
-rw-r--r--tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr6
-rw-r--r--tests/ui/target-feature/feature-hierarchy.aarch64-sve2.stderr7
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs11
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr8
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs14
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs10
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr7
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs10
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr7
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-attribute.rs1
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-attribute.stderr2
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-cfg.rs1
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag-disable.rs1
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag.rs1
-rw-r--r--tests/ui/target-feature/gate.rs2
-rw-r--r--tests/ui/target-feature/gate.stderr2
-rw-r--r--tests/ui/traits/const-traits/effects/auxiliary/minicore.rs10
-rw-r--r--tests/ui/traits/const-traits/ice-120503-async-const-method.stderr8
-rw-r--r--tests/ui/transmutability/alignment/align-fail.stderr1
-rw-r--r--tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr20
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr1
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr1
-rw-r--r--tests/ui/transmutability/references/unit-to-u8.stderr1
-rw-r--r--tests/ui/transmutability/uninhabited.stderr5
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr5
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr3
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr6
-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/typeck/issue-100285.stderr1
-rw-r--r--tests/ui/typeck/issue-104513-ice.stderr3
-rw-r--r--tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr11
-rw-r--r--tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr11
-rw-r--r--tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr11
-rw-r--r--tests/ui/typeck/rhs-ty-hint-134162.rs18
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.rs1
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.stdout1
-rw-r--r--tests/ui/unsafe-binders/expr.rs13
-rw-r--r--tests/ui/unsafe-binders/expr.stderr29
-rw-r--r--tests/ui/unsafe-binders/lifetime-resolution.rs19
-rw-r--r--tests/ui/unsafe-binders/lifetime-resolution.stderr65
-rw-r--r--tests/ui/unsafe-binders/simple.rs7
-rw-r--r--tests/ui/unsafe-binders/simple.stderr17
-rw-r--r--tests/ui/while/while-else-err.stderr3
-rw-r--r--tests/ui/while/while-else-let-else-err.stderr3
-rw-r--r--triagebot.toml10
1258 files changed, 24953 insertions, 9802 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/Cargo.lock b/Cargo.lock
index 38b009bfc70..5eeb855aacb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3507,7 +3507,6 @@ dependencies = [
  "cc",
  "either",
  "itertools",
- "jobserver",
  "libc",
  "object 0.36.5",
  "pathdiff",
@@ -3522,6 +3521,7 @@ dependencies = [
  "rustc_fluent_macro",
  "rustc_fs_util",
  "rustc_hir",
+ "rustc_hir_pretty",
  "rustc_incremental",
  "rustc_index",
  "rustc_macros",
@@ -3787,6 +3787,7 @@ dependencies = [
  "rustc_span",
  "rustc_target",
  "smallvec",
+ "thin-vec",
  "tracing",
 ]
 
@@ -4455,9 +4456,9 @@ version = "0.0.0"
 dependencies = [
  "rustc_abi",
  "rustc_ast",
- "rustc_ast_pretty",
  "rustc_data_structures",
  "rustc_hir",
+ "rustc_hir_pretty",
  "rustc_middle",
  "rustc_session",
  "rustc_span",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 57f1ac63353..c0b96f50b60 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -19,7 +19,7 @@
 //! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
 
 use std::borrow::Cow;
-use std::{cmp, fmt, mem};
+use std::{cmp, fmt};
 
 pub use GenericArgs::*;
 pub use UnsafeSource::*;
@@ -1384,6 +1384,7 @@ impl Expr {
             | ExprKind::Tup(_)
             | ExprKind::Type(..)
             | ExprKind::Underscore
+            | ExprKind::UnsafeBinderCast(..)
             | ExprKind::While(..)
             | ExprKind::Err(_)
             | ExprKind::Dummy => ExprPrecedence::Unambiguous,
@@ -1511,7 +1512,13 @@ pub enum ExprKind {
     /// `'label: for await? pat in iter { block }`
     ///
     /// This is desugared to a combination of `loop` and `match` expressions.
-    ForLoop { pat: P<Pat>, iter: P<Expr>, body: P<Block>, label: Option<Label>, kind: ForLoopKind },
+    ForLoop {
+        pat: P<Pat>,
+        iter: P<Expr>,
+        body: P<Block>,
+        label: Option<Label>,
+        kind: ForLoopKind,
+    },
     /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
     ///
     /// `'label: loop { block }`
@@ -1616,6 +1623,8 @@ pub enum ExprKind {
     /// A `format_args!()` expression.
     FormatArgs(P<FormatArgs>),
 
+    UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
+
     /// Placeholder for an expression that wasn't syntactically well formed in some way.
     Err(ErrorGuaranteed),
 
@@ -1654,6 +1663,16 @@ impl GenBlockKind {
     }
 }
 
+/// Whether we're unwrapping or wrapping an unsafe binder
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
+pub enum UnsafeBinderCastKind {
+    // e.g. `&i32` -> `unsafe<'a> &'a i32`
+    Wrap,
+    // e.g. `unsafe<'a> &'a i32` -> `&i32`
+    Unwrap,
+}
+
 /// The explicit `Self` type in a "qualified path". The actual
 /// path, including the trait and the associated item, is stored
 /// separately. `position` represents the index of the associated
@@ -1741,53 +1760,16 @@ pub enum AttrArgs {
     Eq {
         /// Span of the `=` token.
         eq_span: Span,
-
-        value: AttrArgsEq,
+        expr: P<Expr>,
     },
 }
 
-// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
-// expansion is completed, all cases end up either as a meta item literal,
-// which is the form used after lowering to HIR, or as an error.
-#[derive(Clone, Encodable, Decodable, Debug)]
-pub enum AttrArgsEq {
-    Ast(P<Expr>),
-    Hir(MetaItemLit),
-}
-
-impl AttrArgsEq {
-    pub fn span(&self) -> Span {
-        match self {
-            AttrArgsEq::Ast(p) => p.span,
-            AttrArgsEq::Hir(lit) => lit.span,
-        }
-    }
-
-    pub fn unwrap_ast(&self) -> &Expr {
-        match self {
-            AttrArgsEq::Ast(p) => p,
-            AttrArgsEq::Hir(lit) => {
-                unreachable!("in literal form when getting inner tokens: {lit:?}")
-            }
-        }
-    }
-
-    pub fn unwrap_ast_mut(&mut self) -> &mut P<Expr> {
-        match self {
-            AttrArgsEq::Ast(p) => p,
-            AttrArgsEq::Hir(lit) => {
-                unreachable!("in literal form when getting inner tokens: {lit:?}")
-            }
-        }
-    }
-}
-
 impl AttrArgs {
     pub fn span(&self) -> Option<Span> {
         match self {
             AttrArgs::Empty => None,
             AttrArgs::Delimited(args) => Some(args.dspan.entire()),
-            AttrArgs::Eq { eq_span, value } => Some(eq_span.to(value.span())),
+            AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
         }
     }
 
@@ -1797,27 +1779,7 @@ impl AttrArgs {
         match self {
             AttrArgs::Empty => TokenStream::default(),
             AttrArgs::Delimited(args) => args.tokens.clone(),
-            AttrArgs::Eq { value, .. } => TokenStream::from_ast(value.unwrap_ast()),
-        }
-    }
-}
-
-impl<CTX> HashStable<CTX> for AttrArgs
-where
-    CTX: crate::HashStableContext,
-{
-    fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
-        mem::discriminant(self).hash_stable(ctx, hasher);
-        match self {
-            AttrArgs::Empty => {}
-            AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher),
-            AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => {
-                unreachable!("hash_stable {:?}", expr);
-            }
-            AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } => {
-                eq_span.hash_stable(ctx, hasher);
-                lit.hash_stable(ctx, hasher);
-            }
+            AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
         }
     }
 }
@@ -2225,6 +2187,12 @@ pub struct BareFnTy {
     pub decl_span: Span,
 }
 
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct UnsafeBinderTy {
+    pub generic_params: ThinVec<GenericParam>,
+    pub inner_ty: P<Ty>,
+}
+
 /// The various kinds of type recognized by the compiler.
 //
 // Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
@@ -2244,6 +2212,8 @@ pub enum TyKind {
     PinnedRef(Option<Lifetime>, MutTy),
     /// A bare function (e.g., `fn(usize) -> bool`).
     BareFn(P<BareFnTy>),
+    /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
+    UnsafeBinder(P<UnsafeBinderTy>),
     /// The never type (`!`).
     Never,
     /// A tuple (`(A, B, C, D,...)`).
@@ -2879,7 +2849,7 @@ pub enum ModKind {
     /// or with definition outlined to a separate file `mod foo;` and already loaded from it.
     /// The inner span is from the first token past `{` to the last token until `}`,
     /// or from the first to the last token in the loaded file.
-    Loaded(ThinVec<P<Item>>, Inline, ModSpans),
+    Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
     /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
     Unloaded,
 }
@@ -3026,7 +2996,7 @@ impl NormalAttr {
     }
 }
 
-#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct AttrItem {
     pub unsafety: Safety,
     pub path: Path,
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 0d79cadef34..8ee3d4d590c 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -1,5 +1,6 @@
 //! Functions dealing with attributes and meta items.
 
+use std::fmt::Debug;
 use std::iter;
 use std::sync::atomic::{AtomicU32, Ordering};
 
@@ -10,9 +11,9 @@ use smallvec::{SmallVec, smallvec};
 use thin_vec::{ThinVec, thin_vec};
 
 use crate::ast::{
-    AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID,
-    DelimArgs, Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit,
-    NormalAttr, Path, PathSegment, Safety,
+    AttrArgs, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID, DelimArgs,
+    Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NormalAttr, Path,
+    PathSegment, Safety,
 };
 use crate::ptr::P;
 use crate::token::{self, CommentKind, Delimiter, Token};
@@ -66,11 +67,27 @@ impl Attribute {
             AttrKind::DocComment(..) => panic!("unexpected doc comment"),
         }
     }
+}
+
+impl AttributeExt for Attribute {
+    fn id(&self) -> AttrId {
+        self.id
+    }
+
+    fn value_span(&self) -> Option<Span> {
+        match &self.kind {
+            AttrKind::Normal(normal) => match &normal.item.args {
+                AttrArgs::Eq { expr, .. } => Some(expr.span),
+                _ => None,
+            },
+            AttrKind::DocComment(..) => None,
+        }
+    }
 
     /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example).
     /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not
     /// a doc comment) will return `false`.
-    pub fn is_doc_comment(&self) -> bool {
+    fn is_doc_comment(&self) -> bool {
         match self.kind {
             AttrKind::Normal(..) => false,
             AttrKind::DocComment(..) => true,
@@ -78,7 +95,7 @@ impl Attribute {
     }
 
     /// For a single-segment attribute, returns its name; otherwise, returns `None`.
-    pub fn ident(&self) -> Option<Ident> {
+    fn ident(&self) -> Option<Ident> {
         match &self.kind {
             AttrKind::Normal(normal) => {
                 if let [ident] = &*normal.item.path.segments {
@@ -91,28 +108,14 @@ impl Attribute {
         }
     }
 
-    pub fn name_or_empty(&self) -> Symbol {
-        self.ident().unwrap_or_else(Ident::empty).name
-    }
-
-    pub fn path(&self) -> SmallVec<[Symbol; 1]> {
-        match &self.kind {
-            AttrKind::Normal(normal) => {
-                normal.item.path.segments.iter().map(|s| s.ident.name).collect()
-            }
-            AttrKind::DocComment(..) => smallvec![sym::doc],
-        }
-    }
-
-    #[inline]
-    pub fn has_name(&self, name: Symbol) -> bool {
+    fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
         match &self.kind {
-            AttrKind::Normal(normal) => normal.item.path == name,
-            AttrKind::DocComment(..) => false,
+            AttrKind::Normal(p) => Some(p.item.path.segments.iter().map(|i| i.ident).collect()),
+            AttrKind::DocComment(_, _) => None,
         }
     }
 
-    pub fn path_matches(&self, name: &[Symbol]) -> bool {
+    fn path_matches(&self, name: &[Symbol]) -> bool {
         match &self.kind {
             AttrKind::Normal(normal) => {
                 normal.item.path.segments.len() == name.len()
@@ -128,7 +131,11 @@ impl Attribute {
         }
     }
 
-    pub fn is_word(&self) -> bool {
+    fn span(&self) -> Span {
+        self.span
+    }
+
+    fn is_word(&self) -> bool {
         if let AttrKind::Normal(normal) = &self.kind {
             matches!(normal.item.args, AttrArgs::Empty)
         } else {
@@ -143,7 +150,7 @@ impl Attribute {
     /// #[attr = ""] // Returns `None`.
     /// #[attr] // Returns `None`.
     /// ```
-    pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
+    fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
         match &self.kind {
             AttrKind::Normal(normal) => normal.item.meta_item_list(),
             AttrKind::DocComment(..) => None,
@@ -165,7 +172,7 @@ impl Attribute {
     /// ```text
     /// #[attr("value")]
     /// ```
-    pub fn value_str(&self) -> Option<Symbol> {
+    fn value_str(&self) -> Option<Symbol> {
         match &self.kind {
             AttrKind::Normal(normal) => normal.item.value_str(),
             AttrKind::DocComment(..) => None,
@@ -177,7 +184,7 @@ impl Attribute {
     /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`.
     /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`.
     /// * `#[doc(...)]` returns `None`.
-    pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
+    fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
         match &self.kind {
             AttrKind::DocComment(kind, data) => Some((*data, *kind)),
             AttrKind::Normal(normal) if normal.item.path == sym::doc => {
@@ -191,7 +198,7 @@ impl Attribute {
     /// * `///doc` returns `Some("doc")`.
     /// * `#[doc = "doc"]` returns `Some("doc")`.
     /// * `#[doc(...)]` returns `None`.
-    pub fn doc_str(&self) -> Option<Symbol> {
+    fn doc_str(&self) -> Option<Symbol> {
         match &self.kind {
             AttrKind::DocComment(.., data) => Some(*data),
             AttrKind::Normal(normal) if normal.item.path == sym::doc => normal.item.value_str(),
@@ -199,14 +206,14 @@ impl Attribute {
         }
     }
 
-    pub fn may_have_doc_links(&self) -> bool {
-        self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
+    fn style(&self) -> AttrStyle {
+        self.style
     }
+}
 
-    pub fn is_proc_macro_attr(&self) -> bool {
-        [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
-            .iter()
-            .any(|kind| self.has_name(*kind))
+impl Attribute {
+    pub fn may_have_doc_links(&self) -> bool {
+        self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
     }
 
     /// Extracts the MetaItem from inside this Attribute.
@@ -268,7 +275,12 @@ impl AttrItem {
     /// ```
     fn value_str(&self) -> Option<Symbol> {
         match &self.args {
-            AttrArgs::Eq { value, .. } => value.value_str(),
+            AttrArgs::Eq { expr, .. } => match expr.kind {
+                ExprKind::Lit(token_lit) => {
+                    LitKind::from_token_lit(token_lit).ok().and_then(|lit| lit.str())
+                }
+                _ => None,
+            },
             AttrArgs::Delimited(_) | AttrArgs::Empty => None,
         }
     }
@@ -287,20 +299,6 @@ impl AttrItem {
     }
 }
 
-impl AttrArgsEq {
-    fn value_str(&self) -> Option<Symbol> {
-        match self {
-            AttrArgsEq::Ast(expr) => match expr.kind {
-                ExprKind::Lit(token_lit) => {
-                    LitKind::from_token_lit(token_lit).ok().and_then(|lit| lit.str())
-                }
-                _ => None,
-            },
-            AttrArgsEq::Hir(lit) => lit.kind.str(),
-        }
-    }
-}
-
 impl MetaItem {
     /// For a single-segment meta item, returns its name; otherwise, returns `None`.
     pub fn ident(&self) -> Option<Ident> {
@@ -439,7 +437,8 @@ impl MetaItem {
 }
 
 impl MetaItemKind {
-    fn list_from_tokens(tokens: TokenStream) -> Option<ThinVec<MetaItemInner>> {
+    // public because it can be called in the hir
+    pub fn list_from_tokens(tokens: TokenStream) -> Option<ThinVec<MetaItemInner>> {
         let mut tokens = tokens.trees().peekable();
         let mut result = ThinVec::new();
         while tokens.peek().is_some() {
@@ -492,7 +491,7 @@ impl MetaItemKind {
                 MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List)
             }
             AttrArgs::Delimited(..) => None,
-            AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => match expr.kind {
+            AttrArgs::Eq { expr, .. } => match expr.kind {
                 ExprKind::Lit(token_lit) => {
                     // Turn failures to `None`, we'll get parse errors elsewhere.
                     MetaItemLit::from_token_lit(token_lit, expr.span)
@@ -501,9 +500,6 @@ impl MetaItemKind {
                 }
                 _ => None,
             },
-            AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => {
-                Some(MetaItemKind::NameValue(lit.clone()))
-            }
         }
     }
 }
@@ -704,26 +700,175 @@ pub fn mk_attr_name_value_str(
         tokens: None,
     });
     let path = Path::from_ident(Ident::new(name, span));
-    let args = AttrArgs::Eq { eq_span: span, value: AttrArgsEq::Ast(expr) };
+    let args = AttrArgs::Eq { eq_span: span, expr };
     mk_attr(g, style, unsafety, path, args, span)
 }
 
-pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator<Item = &Attribute> {
+pub fn filter_by_name<A: AttributeExt>(attrs: &[A], name: Symbol) -> impl Iterator<Item = &A> {
     attrs.iter().filter(move |attr| attr.has_name(name))
 }
 
-pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> {
+pub fn find_by_name<A: AttributeExt>(attrs: &[A], name: Symbol) -> Option<&A> {
     filter_by_name(attrs, name).next()
 }
 
-pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option<Symbol> {
+pub fn first_attr_value_str_by_name(attrs: &[impl AttributeExt], name: Symbol) -> Option<Symbol> {
     find_by_name(attrs, name).and_then(|attr| attr.value_str())
 }
 
-pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
+pub fn contains_name(attrs: &[impl AttributeExt], name: Symbol) -> bool {
     find_by_name(attrs, name).is_some()
 }
 
 pub fn list_contains_name(items: &[MetaItemInner], name: Symbol) -> bool {
     items.iter().any(|item| item.has_name(name))
 }
+
+impl MetaItemLit {
+    pub fn value_str(&self) -> Option<Symbol> {
+        LitKind::from_token_lit(self.as_token_lit()).ok().and_then(|lit| lit.str())
+    }
+}
+
+pub trait AttributeExt: Debug {
+    fn id(&self) -> AttrId;
+
+    fn name_or_empty(&self) -> Symbol {
+        self.ident().unwrap_or_else(Ident::empty).name
+    }
+
+    /// Get the meta item list, `#[attr(meta item list)]`
+    fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>>;
+
+    /// Gets the value literal, as string, when using `#[attr = value]`
+    fn value_str(&self) -> Option<Symbol>;
+
+    /// Gets the span of the value literal, as string, when using `#[attr = value]`
+    fn value_span(&self) -> Option<Span>;
+
+    /// For a single-segment attribute, returns its name; otherwise, returns `None`.
+    fn ident(&self) -> Option<Ident>;
+
+    /// Checks whether the path of this attribute matches the name.
+    ///
+    /// Matches one segment of the path to each element in `name`
+    fn path_matches(&self, name: &[Symbol]) -> bool;
+
+    /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example).
+    /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not
+    /// a doc comment) will return `false`.
+    fn is_doc_comment(&self) -> bool;
+
+    #[inline]
+    fn has_name(&self, name: Symbol) -> bool {
+        self.ident().map(|x| x.name == name).unwrap_or(false)
+    }
+
+    /// get the span of the entire attribute
+    fn span(&self) -> Span;
+
+    fn is_word(&self) -> bool;
+
+    fn path(&self) -> SmallVec<[Symbol; 1]> {
+        self.ident_path()
+            .map(|i| i.into_iter().map(|i| i.name).collect())
+            .unwrap_or(smallvec![sym::doc])
+    }
+
+    /// Returns None for doc comments
+    fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>>;
+
+    /// Returns the documentation if this is a doc comment or a sugared doc comment.
+    /// * `///doc` returns `Some("doc")`.
+    /// * `#[doc = "doc"]` returns `Some("doc")`.
+    /// * `#[doc(...)]` returns `None`.
+    fn doc_str(&self) -> Option<Symbol>;
+
+    fn is_proc_macro_attr(&self) -> bool {
+        [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
+            .iter()
+            .any(|kind| self.has_name(*kind))
+    }
+
+    /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
+    /// * `///doc` returns `Some(("doc", CommentKind::Line))`.
+    /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`.
+    /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`.
+    /// * `#[doc(...)]` returns `None`.
+    fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)>;
+
+    fn style(&self) -> AttrStyle;
+}
+
+// FIXME(fn_delegation): use function delegation instead of manually forwarding
+
+impl Attribute {
+    pub fn id(&self) -> AttrId {
+        AttributeExt::id(self)
+    }
+
+    pub fn name_or_empty(&self) -> Symbol {
+        AttributeExt::name_or_empty(self)
+    }
+
+    pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
+        AttributeExt::meta_item_list(self)
+    }
+
+    pub fn value_str(&self) -> Option<Symbol> {
+        AttributeExt::value_str(self)
+    }
+
+    pub fn value_span(&self) -> Option<Span> {
+        AttributeExt::value_span(self)
+    }
+
+    pub fn ident(&self) -> Option<Ident> {
+        AttributeExt::ident(self)
+    }
+
+    pub fn path_matches(&self, name: &[Symbol]) -> bool {
+        AttributeExt::path_matches(self, name)
+    }
+
+    pub fn is_doc_comment(&self) -> bool {
+        AttributeExt::is_doc_comment(self)
+    }
+
+    #[inline]
+    pub fn has_name(&self, name: Symbol) -> bool {
+        AttributeExt::has_name(self, name)
+    }
+
+    pub fn span(&self) -> Span {
+        AttributeExt::span(self)
+    }
+
+    pub fn is_word(&self) -> bool {
+        AttributeExt::is_word(self)
+    }
+
+    pub fn path(&self) -> SmallVec<[Symbol; 1]> {
+        AttributeExt::path(self)
+    }
+
+    pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
+        AttributeExt::ident_path(self)
+    }
+
+    pub fn doc_str(&self) -> Option<Symbol> {
+        AttributeExt::doc_str(self)
+    }
+
+    pub fn is_proc_macro_attr(&self) -> bool {
+        AttributeExt::is_proc_macro_attr(self)
+    }
+
+    pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
+        AttributeExt::doc_str_and_comment_kind(self)
+    }
+
+    pub fn style(&self) -> AttrStyle {
+        AttributeExt::style(self)
+    }
+}
diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs
index 45c4caca6e9..fffcb3ef988 100644
--- a/compiler/rustc_ast/src/entry.rs
+++ b/compiler/rustc_ast/src/entry.rs
@@ -1,7 +1,7 @@
 use rustc_span::Symbol;
 use rustc_span::symbol::sym;
 
-use crate::{Attribute, attr};
+use crate::attr::{self, AttributeExt};
 
 #[derive(Debug)]
 pub enum EntryPointType {
@@ -37,7 +37,7 @@ pub enum EntryPointType {
 }
 
 pub fn entry_point_type(
-    attrs: &[Attribute],
+    attrs: &[impl AttributeExt],
     at_root: bool,
     name: Option<Symbol>,
 ) -> EntryPointType {
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 7730d0b4b78..6372c66050e 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -44,20 +44,10 @@ pub mod token;
 pub mod tokenstream;
 pub mod visit;
 
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-
 pub use self::ast::*;
 pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTokens};
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
 /// instead of implementing everything in `rustc_middle`.
-pub trait HashStableContext: rustc_span::HashStableContext {
-    fn hash_attr(&mut self, _: &ast::Attribute, hasher: &mut StableHasher);
-}
-
-impl<AstCtx: crate::HashStableContext> HashStable<AstCtx> for ast::Attribute {
-    fn hash_stable(&self, hcx: &mut AstCtx, hasher: &mut StableHasher) {
-        hcx.hash_attr(self, hasher)
-    }
-}
+pub trait HashStableContext: rustc_span::HashStableContext {}
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 2c09059fe19..f07266a3e2d 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -451,8 +451,8 @@ fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
     match args {
         AttrArgs::Empty => {}
         AttrArgs::Delimited(args) => visit_delim_args(vis, args),
-        AttrArgs::Eq { eq_span, value } => {
-            vis.visit_expr(value.unwrap_ast_mut());
+        AttrArgs::Eq { eq_span, expr } => {
+            vis.visit_expr(expr);
             vis.visit_span(eq_span);
         }
     }
@@ -558,6 +558,11 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
             vis.visit_fn_decl(decl);
             vis.visit_span(decl_span);
         }
+        TyKind::UnsafeBinder(binder) => {
+            let UnsafeBinderTy { generic_params, inner_ty } = binder.deref_mut();
+            generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
+            vis.visit_ty(inner_ty);
+        }
         TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)),
         TyKind::Paren(ty) => vis.visit_ty(ty),
         TyKind::Pat(ty, pat) => {
@@ -1212,7 +1217,12 @@ impl WalkItemKind for ItemKind {
             ItemKind::Mod(safety, mod_kind) => {
                 visit_safety(vis, safety);
                 match mod_kind {
-                    ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => {
+                    ModKind::Loaded(
+                        items,
+                        _inline,
+                        ModSpans { inner_span, inject_use_span },
+                        _,
+                    ) => {
                         items.flat_map_in_place(|item| vis.flat_map_item(item));
                         vis.visit_span(inner_span);
                         vis.visit_span(inject_use_span);
@@ -1775,6 +1785,12 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
         ExprKind::TryBlock(body) => vis.visit_block(body),
         ExprKind::Lit(_token) => {}
         ExprKind::IncludedBytes(_bytes) => {}
+        ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
+            vis.visit_expr(expr);
+            if let Some(ty) = ty {
+                vis.visit_ty(ty);
+            }
+        }
         ExprKind::Err(_guar) => {}
         ExprKind::Dummy => {}
     }
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index ae1ca36a3ba..64f2a98b8a6 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -152,6 +152,7 @@ pub fn leading_labeled_expr(mut expr: &ast::Expr) -> bool {
             | Underscore
             | Yeet(..)
             | Yield(..)
+            | UnsafeBinderCast(..)
             | Err(..)
             | Dummy => return false,
         }
@@ -232,6 +233,7 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
             | Paren(_)
             | Try(_)
             | Yeet(None)
+            | UnsafeBinderCast(..)
             | Err(_)
             | Dummy => break None,
         }
@@ -253,6 +255,10 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
                 ty = &mut_ty.ty;
             }
 
+            ast::TyKind::UnsafeBinder(binder) => {
+                ty = &binder.inner_ty;
+            }
+
             ast::TyKind::BareFn(fn_ty) => match &fn_ty.decl.output {
                 ast::FnRetTy::Default(_) => break None,
                 ast::FnRetTy::Ty(ret) => ty = ret,
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/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index a7f7c37693a..211d13659ee 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -380,7 +380,7 @@ impl WalkItemKind for ItemKind {
                 try_visit!(visitor.visit_fn(kind, span, id));
             }
             ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
-                ModKind::Loaded(items, _inline, _inner_span) => {
+                ModKind::Loaded(items, _inline, _inner_span, _) => {
                     walk_list!(visitor, visit_item, items);
                 }
                 ModKind::Unloaded => {}
@@ -522,6 +522,10 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
             walk_list!(visitor, visit_generic_param, generic_params);
             try_visit!(visitor.visit_fn_decl(decl));
         }
+        TyKind::UnsafeBinder(binder) => {
+            walk_list!(visitor, visit_generic_param, &binder.generic_params);
+            try_visit!(visitor.visit_ty(&binder.inner_ty));
+        }
         TyKind::Path(maybe_qself, path) => {
             try_visit!(visitor.visit_qself(maybe_qself));
             try_visit!(visitor.visit_path(path, *id));
@@ -1226,6 +1230,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
         ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),
         ExprKind::Lit(_token) => {}
         ExprKind::IncludedBytes(_bytes) => {}
+        ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
+            try_visit!(visitor.visit_expr(expr));
+            visit_opt!(visitor, visit_ty, ty);
+        }
         ExprKind::Err(_guar) => {}
         ExprKind::Dummy => {}
     }
@@ -1279,7 +1287,7 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -
     match args {
         AttrArgs::Empty => {}
         AttrArgs::Delimited(_args) => {}
-        AttrArgs::Eq { value, .. } => try_visit!(visitor.visit_expr(value.unwrap_ast())),
+        AttrArgs::Eq { expr, .. } => try_visit!(visitor.visit_expr(expr)),
     }
     V::Result::output()
 }
diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs
index 20d3ce65fac..88ce6f80e10 100644
--- a/compiler/rustc_ast_lowering/src/block.rs
+++ b/compiler/rustc_ast_lowering/src/block.rs
@@ -1,5 +1,6 @@
 use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};
 use rustc_hir as hir;
+use rustc_span::sym;
 use smallvec::SmallVec;
 
 use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
@@ -82,11 +83,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         (self.arena.alloc_from_iter(stmts), expr)
     }
 
+    /// Return an `ImplTraitContext` that allows impl trait in bindings if
+    /// the feature gate is enabled, or issues a feature error if it is not.
+    fn impl_trait_in_bindings_ctxt(&self, position: ImplTraitPosition) -> ImplTraitContext {
+        if self.tcx.features().impl_trait_in_bindings() {
+            ImplTraitContext::InBinding
+        } else {
+            ImplTraitContext::FeatureGated(position, sym::impl_trait_in_bindings)
+        }
+    }
+
     fn lower_local(&mut self, l: &Local) -> &'hir hir::LetStmt<'hir> {
-        let ty = l
-            .ty
-            .as_ref()
-            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
+        // Let statements are allowed to have impl trait in bindings.
+        let ty = l.ty.as_ref().map(|t| {
+            self.lower_ty(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable))
+        });
         let init = l.kind.init().map(|init| self.lower_expr(init));
         let hir_id = self.lower_node_id(l.id);
         let pat = self.lower_pat(&l.pat);
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 2ad0ff3200e..32905806343 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -379,6 +379,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
                 ExprKind::Err(guar) => hir::ExprKind::Err(*guar),
 
+                ExprKind::UnsafeBinderCast(kind, expr, ty) => hir::ExprKind::UnsafeBinderCast(
+                    *kind,
+                    self.lower_expr(expr),
+                    ty.as_ref().map(|ty| {
+                        self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast))
+                    }),
+                ),
+
                 ExprKind::Dummy => {
                     span_bug!(e.span, "lowered ExprKind::Dummy")
                 }
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 7d6c41992eb..ad4410c57dd 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -176,7 +176,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         id: NodeId,
         hir_id: hir::HirId,
         ident: &mut Ident,
-        attrs: &'hir [Attribute],
+        attrs: &'hir [hir::Attribute],
         vis_span: Span,
         i: &ItemKind,
     ) -> hir::ItemKind<'hir> {
@@ -238,7 +238,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 })
             }
             ItemKind::Mod(_, mod_kind) => match mod_kind {
-                ModKind::Loaded(items, _, spans) => {
+                ModKind::Loaded(items, _, spans, _) => {
                     hir::ItemKind::Mod(self.lower_mod(items, spans))
                 }
                 ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
@@ -467,7 +467,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         id: NodeId,
         vis_span: Span,
         ident: &mut Ident,
-        attrs: &'hir [Attribute],
+        attrs: &'hir [hir::Attribute],
     ) -> hir::ItemKind<'hir> {
         let path = &tree.prefix;
         let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
@@ -1392,7 +1392,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    pub(super) fn lower_safety(&mut self, s: Safety, default: hir::Safety) -> hir::Safety {
+    pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety {
         match s {
             Safety::Unsafe(_) => hir::Safety::Unsafe,
             Safety::Default => default,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index bac3f974cca..41fa4c13442 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -41,7 +41,6 @@
 // tidy-alphabetical-end
 
 use rustc_ast::node_id::NodeMap;
-use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, *};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -96,7 +95,7 @@ struct LoweringContext<'a, 'hir> {
     /// Bodies inside the owner being lowered.
     bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
     /// Attributes inside the owner being lowered.
-    attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
+    attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
     /// Collect items that were created by lowering the current owner.
     children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,
 
@@ -260,6 +259,13 @@ enum ImplTraitContext {
     /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
     ///
     OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },
+
+    /// Treat `impl Trait` as a "trait ascription", which is like a type
+    /// variable but that also enforces that a set of trait goals hold.
+    ///
+    /// This is useful to guide inference for unnameable types.
+    InBinding,
+
     /// `impl Trait` is unstably accepted in this position.
     FeatureGated(ImplTraitPosition, Symbol),
     /// `impl Trait` is not accepted in this position.
@@ -840,7 +846,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         ret
     }
 
-    fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> &'hir [Attribute] {
+    fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> &'hir [hir::Attribute] {
         if attrs.is_empty() {
             &[]
         } else {
@@ -852,25 +858,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn lower_attr(&self, attr: &Attribute) -> Attribute {
+    fn lower_attr(&self, attr: &Attribute) -> hir::Attribute {
         // Note that we explicitly do not walk the path. Since we don't really
         // lower attributes (we use the AST version) there is nowhere to keep
         // the `HirId`s. We don't actually need HIR version of attributes anyway.
         // Tokens are also not needed after macro expansion and parsing.
         let kind = match attr.kind {
-            AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
-                item: AttrItem {
-                    unsafety: normal.item.unsafety,
-                    path: normal.item.path.clone(),
-                    args: self.lower_attr_args(&normal.item.args),
-                    tokens: None,
+            AttrKind::Normal(ref normal) => hir::AttrKind::Normal(Box::new(hir::AttrItem {
+                unsafety: self.lower_safety(normal.item.unsafety, hir::Safety::Safe),
+                path: hir::AttrPath {
+                    segments: normal
+                        .item
+                        .path
+                        .segments
+                        .iter()
+                        .map(|i| i.ident)
+                        .collect::<Vec<_>>()
+                        .into_boxed_slice(),
+                    span: normal.item.path.span,
                 },
-                tokens: None,
+                args: self.lower_attr_args(&normal.item.args),
             })),
-            AttrKind::DocComment(comment_kind, data) => AttrKind::DocComment(comment_kind, data),
+            AttrKind::DocComment(comment_kind, data) => {
+                hir::AttrKind::DocComment(comment_kind, data)
+            }
         };
 
-        Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
+        hir::Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
     }
 
     fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
@@ -882,15 +896,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs {
+    fn lower_attr_args(&self, args: &AttrArgs) -> hir::AttrArgs {
         match args {
-            AttrArgs::Empty => AttrArgs::Empty,
-            AttrArgs::Delimited(args) => AttrArgs::Delimited(self.lower_delim_args(args)),
+            AttrArgs::Empty => hir::AttrArgs::Empty,
+            AttrArgs::Delimited(args) => hir::AttrArgs::Delimited(self.lower_delim_args(args)),
             // This is an inert key-value attribute - it will never be visible to macros
             // after it gets lowered to HIR. Therefore, we can extract literals to handle
             // nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
-            &AttrArgs::Eq { eq_span, ref value } => {
-                let expr = value.unwrap_ast();
+            &AttrArgs::Eq { eq_span, ref expr } => {
                 // In valid code the value always ends up as a single literal. Otherwise, a dummy
                 // literal suffices because the error is handled elsewhere.
                 let lit = if let ExprKind::Lit(token_lit) = expr.kind
@@ -906,7 +919,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         span: DUMMY_SP,
                     }
                 };
-                AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) }
+                hir::AttrArgs::Eq { eq_span, expr: lit }
             }
         }
     }
@@ -1228,6 +1241,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     param_names: self.lower_fn_params_to_names(&f.decl),
                 }))
             }
+            TyKind::UnsafeBinder(f) => {
+                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
+                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
+                    generic_params,
+                    inner_ty: self.lower_ty(&f.inner_ty, itctx),
+                }))
+            }
             TyKind::Never => hir::TyKind::Never,
             TyKind::Tup(tys) => hir::TyKind::Tup(
                 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
@@ -1320,6 +1340,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         }
                         path
                     }
+                    ImplTraitContext::InBinding => {
+                        hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
+                    }
                     ImplTraitContext::FeatureGated(position, feature) => {
                         let guar = self
                             .tcx
@@ -2184,7 +2207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
     fn stmt_let_pat(
         &mut self,
-        attrs: Option<&'hir [Attribute]>,
+        attrs: Option<&'hir [hir::Attribute]>,
         span: Span,
         init: Option<&'hir hir::Expr<'hir>>,
         pat: &'hir hir::Pat<'hir>,
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 64e91c91e2c..a42e3445c8d 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -342,7 +342,7 @@ impl<'a> AstValidator<'a> {
                     sym::forbid,
                     sym::warn,
                 ];
-                !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(attr)
+                !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(*attr)
             })
             .for_each(|attr| {
                 if attr.is_doc_comment() {
@@ -1029,7 +1029,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
                 }
                 // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
-                if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
+                if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _))
                     && !attr::contains_name(&item.attrs, sym::path)
                 {
                     self.check_mod_file_item_asciionly(item.ident);
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index aa3b772efb1..c10b3296497 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`"
@@ -565,6 +560,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(return_type_notation, "return type notation is experimental");
     gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
     gate_all!(unsafe_fields, "`unsafe` fields are experimental");
+    gate_all!(unsafe_binders, "unsafe binder types are experimental");
 
     if !visitor.features.never_patterns() {
         if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index c6f106c3388..cbb92c8c30f 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -17,9 +17,9 @@ use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
 use rustc_ast::util::classify;
 use rustc_ast::util::comments::{Comment, CommentStyle};
 use rustc_ast::{
-    self as ast, AttrArgs, AttrArgsEq, BindingMode, BlockCheckMode, ByRef, DelimArgs, GenericArg,
-    GenericBound, InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass,
-    InlineAsmTemplatePiece, PatKind, RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr,
+    self as ast, AttrArgs, BindingMode, BlockCheckMode, ByRef, DelimArgs, GenericArg, GenericBound,
+    InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece, PatKind,
+    RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr,
 };
 use rustc_data_structures::sync::Lrc;
 use rustc_span::edition::Edition;
@@ -359,7 +359,7 @@ fn binop_to_string(op: BinOpToken) -> &'static str {
     }
 }
 
-fn doc_comment_to_string(
+pub fn doc_comment_to_string(
     comment_kind: CommentKind,
     attr_style: ast::AttrStyle,
     data: Symbol,
@@ -648,20 +648,13 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
             AttrArgs::Empty => {
                 self.print_path(&item.path, false, 0);
             }
-            AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => {
+            AttrArgs::Eq { expr, .. } => {
                 self.print_path(&item.path, false, 0);
                 self.space();
                 self.word_space("=");
                 let token_str = self.expr_to_string(expr);
                 self.word(token_str);
             }
-            AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => {
-                self.print_path(&item.path, false, 0);
-                self.space();
-                self.word_space("=");
-                let token_str = self.meta_item_lit_to_string(lit);
-                self.word(token_str);
-            }
         }
         match item.unsafety {
             ast::Safety::Unsafe(_) => self.pclose(),
@@ -1198,6 +1191,14 @@ impl<'a> State<'a> {
             ast::TyKind::BareFn(f) => {
                 self.print_ty_fn(f.ext, f.safety, &f.decl, None, &f.generic_params);
             }
+            ast::TyKind::UnsafeBinder(f) => {
+                self.ibox(INDENT_UNIT);
+                self.word("unsafe");
+                self.print_generic_params(&f.generic_params);
+                self.nbsp();
+                self.print_type(&f.inner_ty);
+                self.end();
+            }
             ast::TyKind::Path(None, path) => {
                 self.print_path(path, false, 0);
             }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index c239cb249c3..dce76fb1e77 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -772,6 +772,25 @@ impl<'a> State<'a> {
                 self.word_nbsp("try");
                 self.print_block_with_attrs(blk, attrs)
             }
+            ast::ExprKind::UnsafeBinderCast(kind, expr, ty) => {
+                self.word("builtin # ");
+                match kind {
+                    ast::UnsafeBinderCastKind::Wrap => self.word("wrap_binder"),
+                    ast::UnsafeBinderCastKind::Unwrap => self.word("unwrap_binder"),
+                }
+                self.popen();
+                self.ibox(0);
+                self.print_expr(expr, FixupContext::default());
+
+                if let Some(ty) = ty {
+                    self.word(",");
+                    self.space();
+                    self.print_type(ty);
+                }
+
+                self.end();
+                self.pclose();
+            }
             ast::ExprKind::Err(_) => {
                 self.popen();
                 self.word("/*ERROR*/");
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 94f9727eb7f..d5ee03d2b68 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -3,10 +3,8 @@
 use std::num::NonZero;
 
 use rustc_abi::Align;
-use rustc_ast::{
-    self as ast, Attribute, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId,
-    attr,
-};
+use rustc_ast::attr::AttributeExt;
+use rustc_ast::{self as ast, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId};
 use rustc_ast_pretty::pprust;
 use rustc_errors::ErrorGuaranteed;
 use rustc_feature::{Features, GatedCfg, find_gated_cfg, is_builtin_attr_name};
@@ -20,8 +18,8 @@ use rustc_span::Span;
 use rustc_span::hygiene::Transparency;
 use rustc_span::symbol::{Symbol, kw, sym};
 
-use crate::fluent_generated;
 use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
+use crate::{filter_by_name, first_attr_value_str_by_name, fluent_generated};
 
 /// The version placeholder that recently stabilized features contain inside the
 /// `since` field of the `#[stable]` attribute.
@@ -29,7 +27,7 @@ use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
 /// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591).
 pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
 
-pub fn is_builtin_attr(attr: &Attribute) -> bool {
+pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool {
     attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name))
 }
 
@@ -215,7 +213,7 @@ impl UnstableReason {
 /// attributes in `attrs`. Returns `None` if no stability attributes are found.
 pub fn find_stability(
     sess: &Session,
-    attrs: &[Attribute],
+    attrs: &[impl AttributeExt],
     item_sp: Span,
 ) -> Option<(Stability, Span)> {
     let mut stab: Option<(Stability, Span)> = None;
@@ -226,23 +224,25 @@ pub fn find_stability(
             sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true,
             sym::unstable => {
                 if stab.is_some() {
-                    sess.dcx()
-                        .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
+                    sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
+                        span: attr.span(),
+                    });
                     break;
                 }
 
                 if let Some((feature, level)) = parse_unstability(sess, attr) {
-                    stab = Some((Stability { level, feature }, attr.span));
+                    stab = Some((Stability { level, feature }, attr.span()));
                 }
             }
             sym::stable => {
                 if stab.is_some() {
-                    sess.dcx()
-                        .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
+                    sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
+                        span: attr.span(),
+                    });
                     break;
                 }
                 if let Some((feature, level)) = parse_stability(sess, attr) {
-                    stab = Some((Stability { level, feature }, attr.span));
+                    stab = Some((Stability { level, feature }, attr.span()));
                 }
             }
             _ => {}
@@ -272,7 +272,7 @@ pub fn find_stability(
 /// attributes in `attrs`. Returns `None` if no stability attributes are found.
 pub fn find_const_stability(
     sess: &Session,
-    attrs: &[Attribute],
+    attrs: &[impl AttributeExt],
     item_sp: Span,
 ) -> Option<(ConstStability, Span)> {
     let mut const_stab: Option<(ConstStability, Span)> = None;
@@ -285,8 +285,9 @@ pub fn find_const_stability(
             sym::rustc_const_stable_indirect => const_stable_indirect = true,
             sym::rustc_const_unstable => {
                 if const_stab.is_some() {
-                    sess.dcx()
-                        .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
+                    sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
+                        span: attr.span(),
+                    });
                     break;
                 }
 
@@ -298,14 +299,15 @@ pub fn find_const_stability(
                             const_stable_indirect: false,
                             promotable: false,
                         },
-                        attr.span,
+                        attr.span(),
                     ));
                 }
             }
             sym::rustc_const_stable => {
                 if const_stab.is_some() {
-                    sess.dcx()
-                        .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
+                    sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
+                        span: attr.span(),
+                    });
                     break;
                 }
                 if let Some((feature, level)) = parse_stability(sess, attr) {
@@ -316,7 +318,7 @@ pub fn find_const_stability(
                             const_stable_indirect: false,
                             promotable: false,
                         },
-                        attr.span,
+                        attr.span(),
                     ));
                 }
             }
@@ -361,7 +363,7 @@ pub fn find_const_stability(
 /// without the `staged_api` feature.
 pub fn unmarked_crate_const_stab(
     _sess: &Session,
-    attrs: &[Attribute],
+    attrs: &[impl AttributeExt],
     regular_stab: Stability,
 ) -> ConstStability {
     assert!(regular_stab.level.is_unstable());
@@ -381,7 +383,7 @@ pub fn unmarked_crate_const_stab(
 /// Returns `None` if no stability attributes are found.
 pub fn find_body_stability(
     sess: &Session,
-    attrs: &[Attribute],
+    attrs: &[impl AttributeExt],
 ) -> Option<(DefaultBodyStability, Span)> {
     let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
 
@@ -389,12 +391,12 @@ pub fn find_body_stability(
         if attr.has_name(sym::rustc_default_body_unstable) {
             if body_stab.is_some() {
                 sess.dcx()
-                    .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
+                    .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span() });
                 break;
             }
 
             if let Some((feature, level)) = parse_unstability(sess, attr) {
-                body_stab = Some((DefaultBodyStability { level, feature }, attr.span));
+                body_stab = Some((DefaultBodyStability { level, feature }, attr.span()));
             }
         }
     }
@@ -420,9 +422,8 @@ fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -
 
 /// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and
 /// its stability information.
-fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> {
-    let meta = attr.meta()?;
-    let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None };
+fn parse_stability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> {
+    let metas = attr.meta_item_list()?;
 
     let mut feature = None;
     let mut since = None;
@@ -454,9 +455,9 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
     let feature = match feature {
         Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
         Some(_bad_feature) => {
-            Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span }))
+            Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() }))
         }
-        None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span })),
+        None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })),
     };
 
     let since = if let Some(since) = since {
@@ -465,11 +466,11 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
         } else if let Some(version) = parse_version(since) {
             StableSince::Version(version)
         } else {
-            sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span });
+            sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() });
             StableSince::Err
         }
     } else {
-        sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span });
+        sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() });
         StableSince::Err
     };
 
@@ -484,9 +485,8 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
 
 /// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
 /// attribute, and return the feature name and its stability information.
-fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> {
-    let meta = attr.meta()?;
-    let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None };
+fn parse_unstability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> {
+    let metas = attr.meta_item_list()?;
 
     let mut feature = None;
     let mut reason = None;
@@ -553,13 +553,14 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
     let feature = match feature {
         Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
         Some(_bad_feature) => {
-            Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span }))
+            Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() }))
         }
-        None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span })),
+        None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })),
     };
 
-    let issue = issue
-        .ok_or_else(|| sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span }));
+    let issue = issue.ok_or_else(|| {
+        sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span() })
+    });
 
     match (feature, issue) {
         (Ok(feature), Ok(_)) => {
@@ -575,8 +576,8 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
     }
 }
 
-pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
-    attr::first_attr_value_str_by_name(attrs, sym::crate_name)
+pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option<Symbol> {
+    first_attr_value_str_by_name(attrs, sym::crate_name)
 }
 
 #[derive(Clone, Debug)]
@@ -884,7 +885,7 @@ impl Deprecation {
 pub fn find_deprecation(
     sess: &Session,
     features: &Features,
-    attrs: &[Attribute],
+    attrs: &[impl AttributeExt],
 ) -> Option<(Deprecation, Span)> {
     let mut depr: Option<(Deprecation, Span)> = None;
     let is_rustc = features.staged_api();
@@ -894,98 +895,97 @@ pub fn find_deprecation(
             continue;
         }
 
-        let Some(meta) = attr.meta() else {
-            continue;
-        };
         let mut since = None;
         let mut note = None;
         let mut suggestion = None;
-        match &meta.kind {
-            MetaItemKind::Word => {}
-            MetaItemKind::NameValue(..) => note = meta.value_str(),
-            MetaItemKind::List(list) => {
-                let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
-                    if item.is_some() {
-                        sess.dcx().emit_err(session_diagnostics::MultipleItem {
-                            span: meta.span,
-                            item: pprust::path_to_string(&meta.path),
+
+        if attr.is_doc_comment() {
+            continue;
+        } else if attr.is_word() {
+        } else if let Some(value) = attr.value_str() {
+            note = Some(value)
+        } else if let Some(list) = attr.meta_item_list() {
+            let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
+                if item.is_some() {
+                    sess.dcx().emit_err(session_diagnostics::MultipleItem {
+                        span: meta.span,
+                        item: pprust::path_to_string(&meta.path),
+                    });
+                    return false;
+                }
+                if let Some(v) = meta.value_str() {
+                    *item = Some(v);
+                    true
+                } else {
+                    if let Some(lit) = meta.name_value_literal() {
+                        sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
+                            span: lit.span,
+                            reason: UnsupportedLiteralReason::DeprecatedString,
+                            is_bytestr: lit.kind.is_bytestr(),
+                            start_point_span: sess.source_map().start_point(lit.span),
                         });
-                        return false;
-                    }
-                    if let Some(v) = meta.value_str() {
-                        *item = Some(v);
-                        true
                     } else {
-                        if let Some(lit) = meta.name_value_literal() {
-                            sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
-                                span: lit.span,
-                                reason: UnsupportedLiteralReason::DeprecatedString,
-                                is_bytestr: lit.kind.is_bytestr(),
-                                start_point_span: sess.source_map().start_point(lit.span),
-                            });
-                        } else {
-                            sess.dcx().emit_err(session_diagnostics::IncorrectMetaItem {
-                                span: meta.span,
-                            });
-                        }
-
-                        false
+                        sess.dcx()
+                            .emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span });
                     }
-                };
+                    false
+                }
+            };
 
-                for meta in list {
-                    match meta {
-                        MetaItemInner::MetaItem(mi) => match mi.name_or_empty() {
-                            sym::since => {
-                                if !get(mi, &mut since) {
-                                    continue 'outer;
-                                }
-                            }
-                            sym::note => {
-                                if !get(mi, &mut note) {
-                                    continue 'outer;
-                                }
+            for meta in &list {
+                match meta {
+                    MetaItemInner::MetaItem(mi) => match mi.name_or_empty() {
+                        sym::since => {
+                            if !get(mi, &mut since) {
+                                continue 'outer;
                             }
-                            sym::suggestion => {
-                                if !features.deprecated_suggestion() {
-                                    sess.dcx().emit_err(
-                                        session_diagnostics::DeprecatedItemSuggestion {
-                                            span: mi.span,
-                                            is_nightly: sess.is_nightly_build(),
-                                            details: (),
-                                        },
-                                    );
-                                }
-
-                                if !get(mi, &mut suggestion) {
-                                    continue 'outer;
-                                }
+                        }
+                        sym::note => {
+                            if !get(mi, &mut note) {
+                                continue 'outer;
                             }
-                            _ => {
-                                sess.dcx().emit_err(session_diagnostics::UnknownMetaItem {
-                                    span: meta.span(),
-                                    item: pprust::path_to_string(&mi.path),
-                                    expected: if features.deprecated_suggestion() {
-                                        &["since", "note", "suggestion"]
-                                    } else {
-                                        &["since", "note"]
+                        }
+                        sym::suggestion => {
+                            if !features.deprecated_suggestion() {
+                                sess.dcx().emit_err(
+                                    session_diagnostics::DeprecatedItemSuggestion {
+                                        span: mi.span,
+                                        is_nightly: sess.is_nightly_build(),
+                                        details: (),
                                     },
-                                });
+                                );
+                            }
+
+                            if !get(mi, &mut suggestion) {
                                 continue 'outer;
                             }
-                        },
-                        MetaItemInner::Lit(lit) => {
-                            sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
-                                span: lit.span,
-                                reason: UnsupportedLiteralReason::DeprecatedKvPair,
-                                is_bytestr: false,
-                                start_point_span: sess.source_map().start_point(lit.span),
+                        }
+                        _ => {
+                            sess.dcx().emit_err(session_diagnostics::UnknownMetaItem {
+                                span: meta.span(),
+                                item: pprust::path_to_string(&mi.path),
+                                expected: if features.deprecated_suggestion() {
+                                    &["since", "note", "suggestion"]
+                                } else {
+                                    &["since", "note"]
+                                },
                             });
                             continue 'outer;
                         }
+                    },
+                    MetaItemInner::Lit(lit) => {
+                        sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
+                            span: lit.span,
+                            reason: UnsupportedLiteralReason::DeprecatedKvPair,
+                            is_bytestr: false,
+                            start_point_span: sess.source_map().start_point(lit.span),
+                        });
+                        continue 'outer;
                     }
                 }
             }
+        } else {
+            continue;
         }
 
         let since = if let Some(since) = since {
@@ -996,22 +996,22 @@ pub fn find_deprecation(
             } else if let Some(version) = parse_version(since) {
                 DeprecatedSince::RustcVersion(version)
             } else {
-                sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span });
+                sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() });
                 DeprecatedSince::Err
             }
         } else if is_rustc {
-            sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span });
+            sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() });
             DeprecatedSince::Err
         } else {
             DeprecatedSince::Unspecified
         };
 
         if is_rustc && note.is_none() {
-            sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span });
+            sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span() });
             continue;
         }
 
-        depr = Some((Deprecation { since, note, suggestion }, attr.span));
+        depr = Some((Deprecation { since, note, suggestion }, attr.span()));
     }
 
     depr
@@ -1054,11 +1054,11 @@ impl IntType {
 /// the same discriminant size that the corresponding C enum would or C
 /// structure layout, `packed` to remove padding, and `transparent` to delegate representation
 /// concerns to the only non-ZST field.
-pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
+pub fn find_repr_attrs(sess: &Session, attr: &impl AttributeExt) -> Vec<ReprAttr> {
     if attr.has_name(sym::repr) { parse_repr_attr(sess, attr) } else { Vec::new() }
 }
 
-pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
+pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec<ReprAttr> {
     assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}");
     use ReprAttr::*;
     let mut acc = Vec::new();
@@ -1238,7 +1238,7 @@ pub enum TransparencyError {
 }
 
 pub fn find_transparency(
-    attrs: &[Attribute],
+    attrs: &[impl AttributeExt],
     macro_rules: bool,
 ) -> (Transparency, Option<TransparencyError>) {
     let mut transparency = None;
@@ -1246,7 +1246,7 @@ pub fn find_transparency(
     for attr in attrs {
         if attr.has_name(sym::rustc_macro_transparency) {
             if let Some((_, old_span)) = transparency {
-                error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span));
+                error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span()));
                 break;
             } else if let Some(value) = attr.value_str() {
                 transparency = Some((
@@ -1255,11 +1255,12 @@ pub fn find_transparency(
                         sym::semitransparent => Transparency::SemiTransparent,
                         sym::opaque => Transparency::Opaque,
                         _ => {
-                            error = Some(TransparencyError::UnknownTransparency(value, attr.span));
+                            error =
+                                Some(TransparencyError::UnknownTransparency(value, attr.span()));
                             continue;
                         }
                     },
-                    attr.span,
+                    attr.span(),
                 ));
             }
         }
@@ -1270,29 +1271,29 @@ pub fn find_transparency(
 
 pub fn allow_internal_unstable<'a>(
     sess: &'a Session,
-    attrs: &'a [Attribute],
+    attrs: &'a [impl AttributeExt],
 ) -> impl Iterator<Item = Symbol> + 'a {
     allow_unstable(sess, attrs, sym::allow_internal_unstable)
 }
 
 pub fn rustc_allow_const_fn_unstable<'a>(
     sess: &'a Session,
-    attrs: &'a [Attribute],
+    attrs: &'a [impl AttributeExt],
 ) -> impl Iterator<Item = Symbol> + 'a {
     allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable)
 }
 
 fn allow_unstable<'a>(
     sess: &'a Session,
-    attrs: &'a [Attribute],
+    attrs: &'a [impl AttributeExt],
     symbol: Symbol,
 ) -> impl Iterator<Item = Symbol> + 'a {
-    let attrs = attr::filter_by_name(attrs, symbol);
+    let attrs = filter_by_name(attrs, symbol);
     let list = attrs
         .filter_map(move |attr| {
             attr.meta_item_list().or_else(|| {
                 sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList {
-                    span: attr.span,
+                    span: attr.span(),
                     name: symbol.to_ident_string(),
                 });
                 None
@@ -1332,9 +1333,8 @@ pub fn parse_alignment(node: &ast::LitKind) -> Result<Align, &'static str> {
 }
 
 /// Read the content of a `rustc_confusables` attribute, and return the list of candidate names.
-pub fn parse_confusables(attr: &Attribute) -> Option<Vec<Symbol>> {
-    let meta = attr.meta()?;
-    let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None };
+pub fn parse_confusables(attr: &impl AttributeExt) -> Option<Vec<Symbol>> {
+    let metas = attr.meta_item_list()?;
 
     let mut candidates = Vec::new();
 
diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs
index 16b3d901956..ff838fbbb88 100644
--- a/compiler/rustc_borrowck/src/borrow_set.rs
+++ b/compiler/rustc_borrowck/src/borrow_set.rs
@@ -34,6 +34,25 @@ pub struct BorrowSet<'tcx> {
     pub(crate) locals_state_at_exit: LocalsStateAtExit,
 }
 
+// These methods are public to support borrowck consumers.
+impl<'tcx> BorrowSet<'tcx> {
+    pub fn location_map(&self) -> &FxIndexMap<Location, BorrowData<'tcx>> {
+        &self.location_map
+    }
+
+    pub fn activation_map(&self) -> &FxIndexMap<Location, Vec<BorrowIndex>> {
+        &self.activation_map
+    }
+
+    pub fn local_map(&self) -> &FxIndexMap<mir::Local, FxIndexSet<BorrowIndex>> {
+        &self.local_map
+    }
+
+    pub fn locals_state_at_exit(&self) -> &LocalsStateAtExit {
+        &self.locals_state_at_exit
+    }
+}
+
 impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
     type Output = BorrowData<'tcx>;
 
@@ -45,7 +64,7 @@ impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
 /// Location where a two-phase borrow is activated, if a borrow
 /// is in fact a two-phase borrow.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub(crate) enum TwoPhaseActivation {
+pub enum TwoPhaseActivation {
     NotTwoPhase,
     NotActivated,
     ActivatedAt(Location),
@@ -68,6 +87,33 @@ pub struct BorrowData<'tcx> {
     pub(crate) assigned_place: mir::Place<'tcx>,
 }
 
+// These methods are public to support borrowck consumers.
+impl<'tcx> BorrowData<'tcx> {
+    pub fn reserve_location(&self) -> Location {
+        self.reserve_location
+    }
+
+    pub fn activation_location(&self) -> TwoPhaseActivation {
+        self.activation_location
+    }
+
+    pub fn kind(&self) -> mir::BorrowKind {
+        self.kind
+    }
+
+    pub fn region(&self) -> RegionVid {
+        self.region
+    }
+
+    pub fn borrowed_place(&self) -> mir::Place<'tcx> {
+        self.borrowed_place
+    }
+
+    pub fn assigned_place(&self) -> mir::Place<'tcx> {
+        self.assigned_place
+    }
+}
+
 impl<'tcx> fmt::Display for BorrowData<'tcx> {
     fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
         let kind = match self.kind {
@@ -120,7 +166,7 @@ impl LocalsStateAtExit {
 }
 
 impl<'tcx> BorrowSet<'tcx> {
-    pub(crate) fn build(
+    pub fn build(
         tcx: TyCtxt<'tcx>,
         body: &Body<'tcx>,
         locals_are_invalidated_at_exit: bool,
diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs
index 7ace38c3e85..74de766ba23 100644
--- a/compiler/rustc_borrowck/src/consumers.rs
+++ b/compiler/rustc_borrowck/src/consumers.rs
@@ -5,15 +5,15 @@ use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::mir::{Body, Promoted};
 use rustc_middle::ty::TyCtxt;
 
+pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
 pub use super::constraints::OutlivesConstraint;
 pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location};
-pub use super::facts::{AllFacts as PoloniusInput, RustcFacts};
+pub use super::facts::{AllFacts as PoloniusInput, PoloniusRegionVid, RustcFacts};
 pub use super::location::{LocationTable, RichLocation};
 pub use super::nll::PoloniusOutput;
 pub use super::place_ext::PlaceExt;
 pub use super::places_conflict::{PlaceConflictBias, places_conflict};
 pub use super::region_infer::RegionInferenceContext;
-use crate::borrow_set::BorrowSet;
 
 /// Options determining the output behavior of [`get_body_with_borrowck_facts`].
 ///
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 452038bc328..dc4eab766c9 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -8,7 +8,10 @@ use rustc_middle::mir::{
 };
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_mir_dataflow::fmt::DebugWithContext;
-use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
+use rustc_mir_dataflow::impls::{
+    EverInitializedPlaces, EverInitializedPlacesDomain, MaybeUninitializedPlaces,
+    MaybeUninitializedPlacesDomain,
+};
 use rustc_mir_dataflow::{Analysis, GenKill, JoinSemiLattice, SwitchIntEdgeEffects};
 use tracing::debug;
 
@@ -24,7 +27,7 @@ pub(crate) struct Borrowck<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
-    type Domain = BorrowckDomain<'a, 'tcx>;
+    type Domain = BorrowckDomain;
 
     const NAME: &'static str = "borrowck";
 
@@ -41,48 +44,48 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
         unreachable!();
     }
 
-    fn apply_before_statement_effect(
+    fn apply_early_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
-        self.borrows.apply_before_statement_effect(&mut state.borrows, stmt, loc);
-        self.uninits.apply_before_statement_effect(&mut state.uninits, stmt, loc);
-        self.ever_inits.apply_before_statement_effect(&mut state.ever_inits, stmt, loc);
+        self.borrows.apply_early_statement_effect(&mut state.borrows, stmt, loc);
+        self.uninits.apply_early_statement_effect(&mut state.uninits, stmt, loc);
+        self.ever_inits.apply_early_statement_effect(&mut state.ever_inits, stmt, loc);
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
-        self.borrows.apply_statement_effect(&mut state.borrows, stmt, loc);
-        self.uninits.apply_statement_effect(&mut state.uninits, stmt, loc);
-        self.ever_inits.apply_statement_effect(&mut state.ever_inits, stmt, loc);
+        self.borrows.apply_primary_statement_effect(&mut state.borrows, stmt, loc);
+        self.uninits.apply_primary_statement_effect(&mut state.uninits, stmt, loc);
+        self.ever_inits.apply_primary_statement_effect(&mut state.ever_inits, stmt, loc);
     }
 
-    fn apply_before_terminator_effect(
+    fn apply_early_terminator_effect(
         &mut self,
         state: &mut Self::Domain,
         term: &mir::Terminator<'tcx>,
         loc: Location,
     ) {
-        self.borrows.apply_before_terminator_effect(&mut state.borrows, term, loc);
-        self.uninits.apply_before_terminator_effect(&mut state.uninits, term, loc);
-        self.ever_inits.apply_before_terminator_effect(&mut state.ever_inits, term, loc);
+        self.borrows.apply_early_terminator_effect(&mut state.borrows, term, loc);
+        self.uninits.apply_early_terminator_effect(&mut state.uninits, term, loc);
+        self.ever_inits.apply_early_terminator_effect(&mut state.ever_inits, term, loc);
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
         state: &mut Self::Domain,
         term: &'mir mir::Terminator<'tcx>,
         loc: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
-        self.borrows.apply_terminator_effect(&mut state.borrows, term, loc);
-        self.uninits.apply_terminator_effect(&mut state.uninits, term, loc);
-        self.ever_inits.apply_terminator_effect(&mut state.ever_inits, term, loc);
+        self.borrows.apply_primary_terminator_effect(&mut state.borrows, term, loc);
+        self.uninits.apply_primary_terminator_effect(&mut state.uninits, term, loc);
+        self.ever_inits.apply_primary_terminator_effect(&mut state.ever_inits, term, loc);
 
         // This return value doesn't matter. It's only used by `iterate_to_fixpoint`, which this
         // analysis doesn't use.
@@ -110,14 +113,14 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
     }
 }
 
-impl JoinSemiLattice for BorrowckDomain<'_, '_> {
+impl JoinSemiLattice for BorrowckDomain {
     fn join(&mut self, _other: &Self) -> bool {
         // This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
         unreachable!();
     }
 }
 
-impl<'tcx, C> DebugWithContext<C> for BorrowckDomain<'_, 'tcx>
+impl<'tcx, C> DebugWithContext<C> for BorrowckDomain
 where
     C: rustc_mir_dataflow::move_paths::HasMoveData<'tcx>,
 {
@@ -160,10 +163,10 @@ where
 
 /// The transient state of the dataflow analyses used by the borrow checker.
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub(crate) struct BorrowckDomain<'a, 'tcx> {
-    pub(crate) borrows: <Borrows<'a, 'tcx> as Analysis<'tcx>>::Domain,
-    pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
-    pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
+pub(crate) struct BorrowckDomain {
+    pub(crate) borrows: BorrowsDomain,
+    pub(crate) uninits: MaybeUninitializedPlacesDomain,
+    pub(crate) ever_inits: EverInitializedPlacesDomain,
 }
 
 rustc_index::newtype_index! {
@@ -503,7 +506,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
     /// That means they went out of a nonlexical scope
     fn kill_loans_out_of_scope_at_location(
         &self,
-        trans: &mut <Self as Analysis<'tcx>>::Domain,
+        state: &mut <Self as Analysis<'tcx>>::Domain,
         location: Location,
     ) {
         // NOTE: The state associated with a given `location`
@@ -518,14 +521,14 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
         // region, then setting that gen-bit will override any
         // potential kill introduced here.
         if let Some(indices) = self.borrows_out_of_scope_at_location.get(&location) {
-            trans.kill_all(indices.iter().copied());
+            state.kill_all(indices.iter().copied());
         }
     }
 
     /// Kill any borrows that conflict with `place`.
     fn kill_borrows_on_place(
         &self,
-        trans: &mut <Self as Analysis<'tcx>>::Domain,
+        state: &mut <Self as Analysis<'tcx>>::Domain,
         place: Place<'tcx>,
     ) {
         debug!("kill_borrows_on_place: place={:?}", place);
@@ -543,7 +546,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
         // `places_conflict` for every borrow.
         if place.projection.is_empty() {
             if !self.body.local_decls[place.local].is_ref_to_static() {
-                trans.kill_all(other_borrows_of_local);
+                state.kill_all(other_borrows_of_local);
             }
             return;
         }
@@ -562,10 +565,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
             )
         });
 
-        trans.kill_all(definitely_conflicting_borrows);
+        state.kill_all(definitely_conflicting_borrows);
     }
 }
 
+type BorrowsDomain = BitSet<BorrowIndex>;
+
 /// Forward dataflow computation of the set of borrows that are in scope at a particular location.
 /// - we gen the introduced loans
 /// - we kill loans on locals going out of (regular) scope
@@ -574,7 +579,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
 /// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
 ///   `a.b.c` when `a` is overwritten.
 impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
-    type Domain = BitSet<BorrowIndex>;
+    type Domain = BorrowsDomain;
 
     const NAME: &'static str = "borrows";
 
@@ -588,18 +593,18 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
         // function execution, so this method has no effect.
     }
 
-    fn apply_before_statement_effect(
+    fn apply_early_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _statement: &mir::Statement<'tcx>,
         location: Location,
     ) {
-        self.kill_loans_out_of_scope_at_location(trans, location);
+        self.kill_loans_out_of_scope_at_location(state, location);
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         location: Location,
     ) {
@@ -617,18 +622,18 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
                         panic!("could not find BorrowIndex for location {location:?}");
                     });
 
-                    trans.gen_(index);
+                    state.gen_(index);
                 }
 
                 // Make sure there are no remaining borrows for variables
                 // that are assigned over.
-                self.kill_borrows_on_place(trans, *lhs);
+                self.kill_borrows_on_place(state, *lhs);
             }
 
             mir::StatementKind::StorageDead(local) => {
                 // Make sure there are no remaining borrows for locals that
                 // are gone out of scope.
-                self.kill_borrows_on_place(trans, Place::from(*local));
+                self.kill_borrows_on_place(state, Place::from(*local));
             }
 
             mir::StatementKind::FakeRead(..)
@@ -646,18 +651,18 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
         }
     }
 
-    fn apply_before_terminator_effect(
+    fn apply_early_terminator_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _terminator: &mir::Terminator<'tcx>,
         location: Location,
     ) {
-        self.kill_loans_out_of_scope_at_location(trans, location);
+        self.kill_loans_out_of_scope_at_location(state, location);
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
         _location: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
@@ -666,7 +671,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
                 if let mir::InlineAsmOperand::Out { place: Some(place), .. }
                 | mir::InlineAsmOperand::InOut { out_place: Some(place), .. } = *op
                 {
-                    self.kill_borrows_on_place(trans, place);
+                    self.kill_borrows_on_place(state, place);
                 }
             }
         }
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index c5ebf3c547e..4fb7b22f289 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1100,12 +1100,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         }
         let decl_span = local_decl.source_info.span;
 
-        let label = match *local_decl.local_info() {
+        let amp_mut_sugg = match *local_decl.local_info() {
             LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
                 let suggestion = suggest_ampmut_self(self.infcx.tcx, decl_span);
                 let additional =
                     local_trait.map(|span| (span, suggest_ampmut_self(self.infcx.tcx, span)));
-                Some((true, decl_span, suggestion, additional))
+                Some(AmpMutSugg { has_sugg: true, span: decl_span, suggestion, additional })
             }
 
             LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
@@ -1150,7 +1150,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         None
                     }
                     None => {
-                        let (has_sugg, decl_span, sugg) = if name != kw::SelfLower {
+                        if name != kw::SelfLower {
                             suggest_ampmut(
                                 self.infcx.tcx,
                                 local_decl.ty,
@@ -1165,7 +1165,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                                     ..
                                 })) => {
                                     let sugg = suggest_ampmut_self(self.infcx.tcx, decl_span);
-                                    (true, decl_span, sugg)
+                                    Some(AmpMutSugg {
+                                        has_sugg: true,
+                                        span: decl_span,
+                                        suggestion: sugg,
+                                        additional: None,
+                                    })
                                 }
                                 // explicit self (eg `self: &'a Self`)
                                 _ => suggest_ampmut(
@@ -1176,8 +1181,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                                     opt_ty_info,
                                 ),
                             }
-                        };
-                        Some((has_sugg, decl_span, sugg, None))
+                        }
                     }
                 }
             }
@@ -1187,15 +1191,24 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 ..
             })) => {
                 let pattern_span: Span = local_decl.source_info.span;
-                suggest_ref_mut(self.infcx.tcx, pattern_span)
-                    .map(|span| (true, span, "mut ".to_owned(), None))
+                suggest_ref_mut(self.infcx.tcx, pattern_span).map(|span| AmpMutSugg {
+                    has_sugg: true,
+                    span,
+                    suggestion: "mut ".to_owned(),
+                    additional: None,
+                })
             }
 
             _ => unreachable!(),
         };
 
-        match label {
-            Some((true, err_help_span, suggested_code, additional)) => {
+        match amp_mut_sugg {
+            Some(AmpMutSugg {
+                has_sugg: true,
+                span: err_help_span,
+                suggestion: suggested_code,
+                additional,
+            }) => {
                 let mut sugg = vec![(err_help_span, suggested_code)];
                 if let Some(s) = additional {
                     sugg.push(s);
@@ -1217,7 +1230,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     );
                 }
             }
-            Some((false, err_label_span, message, _)) => {
+            Some(AmpMutSugg {
+                has_sugg: false, span: err_label_span, suggestion: message, ..
+            }) => {
                 let def_id = self.body.source.def_id();
                 let hir_id = if let Some(local_def_id) = def_id.as_local()
                     && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
@@ -1422,6 +1437,13 @@ fn suggest_ampmut_self<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String {
     }
 }
 
+struct AmpMutSugg {
+    has_sugg: bool,
+    span: Span,
+    suggestion: String,
+    additional: Option<(Span, String)>,
+}
+
 // When we want to suggest a user change a local variable to be a `&mut`, there
 // are three potential "obvious" things to highlight:
 //
@@ -1443,7 +1465,7 @@ fn suggest_ampmut<'tcx>(
     decl_span: Span,
     opt_assignment_rhs_span: Option<Span>,
     opt_ty_info: Option<Span>,
-) -> (bool, Span, String) {
+) -> Option<AmpMutSugg> {
     // if there is a RHS and it starts with a `&` from it, then check if it is
     // mutable, and if not, put suggest putting `mut ` to make it mutable.
     // we don't have to worry about lifetime annotations here because they are
@@ -1456,6 +1478,11 @@ fn suggest_ampmut<'tcx>(
         && let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span)
         && let Some(stripped) = src.strip_prefix('&')
     {
+        let is_raw_ref = stripped.trim_start().starts_with("raw ");
+        // We don't support raw refs yet
+        if is_raw_ref {
+            return None;
+        }
         let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") {
             match rest.chars().next() {
                 // e.g. `&mut x`
@@ -1479,7 +1506,12 @@ fn suggest_ampmut<'tcx>(
 
             // FIXME(Ezrashaw): returning is bad because we still might want to
             // update the annotated type, see #106857.
-            return (true, span, "mut ".to_owned());
+            return Some(AmpMutSugg {
+                has_sugg: true,
+                span,
+                suggestion: "mut ".to_owned(),
+                additional: None,
+            });
         }
     }
 
@@ -1504,18 +1536,23 @@ fn suggest_ampmut<'tcx>(
         && let Some(ws_pos) = src.find(char::is_whitespace)
     {
         let span = span.with_lo(span.lo() + BytePos(ws_pos as u32)).shrink_to_lo();
-        (true, span, " mut".to_owned())
+        Some(AmpMutSugg { has_sugg: true, span, suggestion: " mut".to_owned(), additional: None })
     // if there is already a binding, we modify it to be `mut`
     } else if binding_exists {
         // shrink the span to just after the `&` in `&variable`
         let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
-        (true, span, "mut ".to_owned())
+        Some(AmpMutSugg { has_sugg: true, span, suggestion: "mut ".to_owned(), additional: None })
     } else {
         // otherwise, suggest that the user annotates the binding; we provide the
         // type of the local.
         let ty = decl_ty.builtin_deref(true).unwrap();
 
-        (false, span, format!("{}mut {}", if decl_ty.is_ref() { "&" } else { "*" }, ty))
+        Some(AmpMutSugg {
+            has_sugg: false,
+            span,
+            suggestion: format!("{}mut {}", if decl_ty.is_ref() { "&" } else { "*" }, ty),
+            additional: None,
+        })
     }
 }
 
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index d7db92da18f..18b7984e90d 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -43,7 +43,7 @@ use rustc_mir_dataflow::impls::{
 use rustc_mir_dataflow::move_paths::{
     InitIndex, InitLocation, LookupResult, MoveData, MoveOutIndex, MovePathIndex,
 };
-use rustc_mir_dataflow::{Analysis, EntrySets, Results, ResultsVisitor, visit_results};
+use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
 use rustc_session::lint::builtin::UNUSED_MUT;
 use rustc_span::{Span, Symbol};
 use smallvec::SmallVec;
@@ -426,14 +426,14 @@ fn get_flow_results<'a, 'tcx>(
         ever_inits: ever_inits.analysis,
     };
 
-    assert_eq!(borrows.entry_sets.len(), uninits.entry_sets.len());
-    assert_eq!(borrows.entry_sets.len(), ever_inits.entry_sets.len());
-    let entry_sets: EntrySets<'_, Borrowck<'_, '_>> =
-        itertools::izip!(borrows.entry_sets, uninits.entry_sets, ever_inits.entry_sets)
+    assert_eq!(borrows.entry_states.len(), uninits.entry_states.len());
+    assert_eq!(borrows.entry_states.len(), ever_inits.entry_states.len());
+    let entry_states: EntryStates<'_, Borrowck<'_, '_>> =
+        itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states)
             .map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
             .collect();
 
-    Results { analysis, entry_sets }
+    Results { analysis, entry_states }
 }
 
 pub(crate) struct BorrowckInferCtxt<'tcx> {
@@ -600,10 +600,10 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
 // 3. assignments do not affect things loaned out as immutable
 // 4. moves do not affect things loaned out in any way
 impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> {
-    fn visit_statement_before_primary_effect(
+    fn visit_after_early_statement_effect(
         &mut self,
         _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
         stmt: &'a Statement<'tcx>,
         location: Location,
     ) {
@@ -674,10 +674,10 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
         }
     }
 
-    fn visit_terminator_before_primary_effect(
+    fn visit_after_early_terminator_effect(
         &mut self,
         _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
         term: &'a Terminator<'tcx>,
         loc: Location,
     ) {
@@ -787,10 +787,10 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
         }
     }
 
-    fn visit_terminator_after_primary_effect(
+    fn visit_after_primary_terminator_effect(
         &mut self,
         _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
         term: &'a Terminator<'tcx>,
         loc: Location,
     ) {
@@ -983,7 +983,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         place_span: (Place<'tcx>, Span),
         kind: (AccessDepth, ReadOrWrite),
         is_local_mutation_allowed: LocalMutationIsAllowed,
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) {
         let (sd, rw) = kind;
 
@@ -1032,7 +1032,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         place_span: (Place<'tcx>, Span),
         sd: AccessDepth,
         rw: ReadOrWrite,
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) -> bool {
         let mut error_reported = false;
 
@@ -1172,7 +1172,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         location: Location,
         place_span: (Place<'tcx>, Span),
         kind: AccessDepth,
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) {
         // Write of P[i] or *P requires P init'd.
         self.check_if_assigned_path_is_moved(location, place_span, state);
@@ -1190,7 +1190,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         &mut self,
         location: Location,
         (rvalue, span): (&'a Rvalue<'tcx>, Span),
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) {
         match rvalue {
             &Rvalue::Ref(_ /*rgn*/, bk, place) => {
@@ -1448,7 +1448,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         &mut self,
         location: Location,
         (operand, span): (&'a Operand<'tcx>, Span),
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) {
         match *operand {
             Operand::Copy(place) => {
@@ -1568,12 +1568,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         }
     }
 
-    fn check_activations(
-        &mut self,
-        location: Location,
-        span: Span,
-        state: &BorrowckDomain<'a, 'tcx>,
-    ) {
+    fn check_activations(&mut self, location: Location, span: Span, state: &BorrowckDomain) {
         // Two-phase borrow support: For each activation that is newly
         // generated at this statement, check if it interferes with
         // another borrow.
@@ -1731,7 +1726,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         location: Location,
         desired_action: InitializationRequiringAction,
         place_span: (PlaceRef<'tcx>, Span),
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) {
         let maybe_uninits = &state.uninits;
 
@@ -1836,7 +1831,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         location: Location,
         desired_action: InitializationRequiringAction,
         place_span: (PlaceRef<'tcx>, Span),
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) {
         let maybe_uninits = &state.uninits;
 
@@ -1935,7 +1930,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         &mut self,
         location: Location,
         (place, span): (Place<'tcx>, Span),
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
     ) {
         debug!("check_if_assigned_path_is_moved place: {:?}", place);
 
@@ -2001,7 +1996,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             location: Location,
             base: PlaceRef<'tcx>,
             span: Span,
-            state: &BorrowckDomain<'a, 'tcx>,
+            state: &BorrowckDomain,
         ) {
             // rust-lang/rust#21232: Until Rust allows reads from the
             // initialized parts of partially initialized structs, we
@@ -2092,7 +2087,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         (place, span): (Place<'tcx>, Span),
         kind: ReadOrWrite,
         is_local_mutation_allowed: LocalMutationIsAllowed,
-        state: &BorrowckDomain<'a, 'tcx>,
+        state: &BorrowckDomain,
         location: Location,
     ) -> bool {
         debug!(
@@ -2206,18 +2201,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         }
     }
 
-    fn is_local_ever_initialized(
-        &self,
-        local: Local,
-        state: &BorrowckDomain<'a, 'tcx>,
-    ) -> Option<InitIndex> {
+    fn is_local_ever_initialized(&self, local: Local, state: &BorrowckDomain) -> Option<InitIndex> {
         let mpi = self.move_data.rev_lookup.find_local(local)?;
         let ii = &self.move_data.init_path_map[mpi];
         ii.into_iter().find(|&&index| state.ever_inits.contains(index)).copied()
     }
 
     /// Adds the place into the used mutable variables set
-    fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain<'a, 'tcx>) {
+    fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain) {
         match root_place {
             RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
                 // If the local may have been initialized, and it is now currently being
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index be02e2f48df..d7ea8e1bcc2 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -116,7 +116,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
     let var_origins = infcx.get_region_var_origins();
 
     // If requested, emit legacy polonius facts.
-    polonius::emit_facts(
+    polonius::legacy::emit_facts(
         &mut all_facts,
         infcx.tcx,
         location_table,
diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
index f646beeecf7..f646beeecf7 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
diff --git a/compiler/rustc_borrowck/src/polonius/loan_kills.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs
index 68e0865ab82..68e0865ab82 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_kills.rs
+++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs
diff --git a/compiler/rustc_borrowck/src/polonius/legacy/mod.rs b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs
new file mode 100644
index 00000000000..9fccc00bdaf
--- /dev/null
+++ b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs
@@ -0,0 +1,184 @@
+//! Functions dedicated to fact generation for the `-Zpolonius=legacy` datalog implementation.
+//!
+//! Will be removed in the future, once the in-tree `-Zpolonius=next` implementation reaches feature
+//! parity.
+
+use rustc_middle::mir::{Body, LocalKind, Location, START_BLOCK};
+use rustc_middle::ty::TyCtxt;
+use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData};
+use tracing::debug;
+
+use crate::borrow_set::BorrowSet;
+use crate::facts::{AllFacts, PoloniusRegionVid};
+use crate::location::LocationTable;
+use crate::type_check::free_region_relations::UniversalRegionRelations;
+
+mod loan_invalidations;
+mod loan_kills;
+
+/// When requested, emit most of the facts needed by polonius:
+/// - moves and assignments
+/// - universal regions and their relations
+/// - CFG points and edges
+/// - loan kills
+/// - loan invalidations
+///
+/// The rest of the facts are emitted during typeck and liveness.
+pub(crate) fn emit_facts<'tcx>(
+    all_facts: &mut Option<AllFacts>,
+    tcx: TyCtxt<'tcx>,
+    location_table: &LocationTable,
+    body: &Body<'tcx>,
+    borrow_set: &BorrowSet<'tcx>,
+    move_data: &MoveData<'_>,
+    universal_region_relations: &UniversalRegionRelations<'_>,
+) {
+    let Some(all_facts) = all_facts else {
+        // We don't do anything if there are no facts to fill.
+        return;
+    };
+    let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
+    emit_move_facts(all_facts, move_data, location_table, body);
+    emit_universal_region_facts(all_facts, borrow_set, universal_region_relations);
+    emit_cfg_and_loan_kills_facts(all_facts, tcx, location_table, body, borrow_set);
+    emit_loan_invalidations_facts(all_facts, tcx, location_table, body, borrow_set);
+}
+
+/// Emit facts needed for move/init analysis: moves and assignments.
+fn emit_move_facts(
+    all_facts: &mut AllFacts,
+    move_data: &MoveData<'_>,
+    location_table: &LocationTable,
+    body: &Body<'_>,
+) {
+    all_facts
+        .path_is_var
+        .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l)));
+
+    for (child, move_path) in move_data.move_paths.iter_enumerated() {
+        if let Some(parent) = move_path.parent {
+            all_facts.child_path.push((child, parent));
+        }
+    }
+
+    let fn_entry_start =
+        location_table.start_index(Location { block: START_BLOCK, statement_index: 0 });
+
+    // initialized_at
+    for init in move_data.inits.iter() {
+        match init.location {
+            InitLocation::Statement(location) => {
+                let block_data = &body[location.block];
+                let is_terminator = location.statement_index == block_data.statements.len();
+
+                if is_terminator && init.kind == InitKind::NonPanicPathOnly {
+                    // We are at the terminator of an init that has a panic path,
+                    // and where the init should not happen on panic
+
+                    for successor in block_data.terminator().successors() {
+                        if body[successor].is_cleanup {
+                            continue;
+                        }
+
+                        // The initialization happened in (or rather, when arriving at)
+                        // the successors, but not in the unwind block.
+                        let first_statement = Location { block: successor, statement_index: 0 };
+                        all_facts
+                            .path_assigned_at_base
+                            .push((init.path, location_table.start_index(first_statement)));
+                    }
+                } else {
+                    // In all other cases, the initialization just happens at the
+                    // midpoint, like any other effect.
+                    all_facts
+                        .path_assigned_at_base
+                        .push((init.path, location_table.mid_index(location)));
+                }
+            }
+            // Arguments are initialized on function entry
+            InitLocation::Argument(local) => {
+                assert!(body.local_kind(local) == LocalKind::Arg);
+                all_facts.path_assigned_at_base.push((init.path, fn_entry_start));
+            }
+        }
+    }
+
+    for (local, path) in move_data.rev_lookup.iter_locals_enumerated() {
+        if body.local_kind(local) != LocalKind::Arg {
+            // Non-arguments start out deinitialised; we simulate this with an
+            // initial move:
+            all_facts.path_moved_at_base.push((path, fn_entry_start));
+        }
+    }
+
+    // moved_out_at
+    // deinitialisation is assumed to always happen!
+    all_facts
+        .path_moved_at_base
+        .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source))));
+}
+
+/// Emit universal regions facts, and their relations.
+fn emit_universal_region_facts(
+    all_facts: &mut AllFacts,
+    borrow_set: &BorrowSet<'_>,
+    universal_region_relations: &UniversalRegionRelations<'_>,
+) {
+    // 1: universal regions are modeled in Polonius as a pair:
+    // - the universal region vid itself.
+    // - a "placeholder loan" associated to this universal region. Since they don't exist in
+    //   the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
+    //   added to the existing number of loans, as if they succeeded them in the set.
+    //
+    let universal_regions = &universal_region_relations.universal_regions;
+    all_facts
+        .universal_region
+        .extend(universal_regions.universal_regions_iter().map(PoloniusRegionVid::from));
+    let borrow_count = borrow_set.len();
+    debug!(
+        "emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}",
+        universal_regions.len(),
+        borrow_count
+    );
+
+    for universal_region in universal_regions.universal_regions_iter() {
+        let universal_region_idx = universal_region.index();
+        let placeholder_loan_idx = borrow_count + universal_region_idx;
+        all_facts.placeholder.push((universal_region.into(), placeholder_loan_idx.into()));
+    }
+
+    // 2: the universal region relations `outlives` constraints are emitted as
+    //  `known_placeholder_subset` facts.
+    for (fr1, fr2) in universal_region_relations.known_outlives() {
+        if fr1 != fr2 {
+            debug!(
+                "emit_universal_region_facts: emitting polonius `known_placeholder_subset` \
+                     fr1={:?}, fr2={:?}",
+                fr1, fr2
+            );
+            all_facts.known_placeholder_subset.push((fr1.into(), fr2.into()));
+        }
+    }
+}
+
+/// Emit facts about loan invalidations.
+fn emit_loan_invalidations_facts<'tcx>(
+    all_facts: &mut AllFacts,
+    tcx: TyCtxt<'tcx>,
+    location_table: &LocationTable,
+    body: &Body<'tcx>,
+    borrow_set: &BorrowSet<'tcx>,
+) {
+    loan_invalidations::emit_loan_invalidations(tcx, all_facts, location_table, body, borrow_set);
+}
+
+/// Emit facts about CFG points and edges, as well as locations where loans are killed.
+fn emit_cfg_and_loan_kills_facts<'tcx>(
+    all_facts: &mut AllFacts,
+    tcx: TyCtxt<'tcx>,
+    location_table: &LocationTable,
+    body: &Body<'tcx>,
+    borrow_set: &BorrowSet<'tcx>,
+) {
+    loan_kills::emit_loan_kills(tcx, all_facts, location_table, body, borrow_set);
+}
diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs
index 9fccc00bdaf..9c1583f1988 100644
--- a/compiler/rustc_borrowck/src/polonius/mod.rs
+++ b/compiler/rustc_borrowck/src/polonius/mod.rs
@@ -1,184 +1 @@
-//! Functions dedicated to fact generation for the `-Zpolonius=legacy` datalog implementation.
-//!
-//! Will be removed in the future, once the in-tree `-Zpolonius=next` implementation reaches feature
-//! parity.
-
-use rustc_middle::mir::{Body, LocalKind, Location, START_BLOCK};
-use rustc_middle::ty::TyCtxt;
-use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData};
-use tracing::debug;
-
-use crate::borrow_set::BorrowSet;
-use crate::facts::{AllFacts, PoloniusRegionVid};
-use crate::location::LocationTable;
-use crate::type_check::free_region_relations::UniversalRegionRelations;
-
-mod loan_invalidations;
-mod loan_kills;
-
-/// When requested, emit most of the facts needed by polonius:
-/// - moves and assignments
-/// - universal regions and their relations
-/// - CFG points and edges
-/// - loan kills
-/// - loan invalidations
-///
-/// The rest of the facts are emitted during typeck and liveness.
-pub(crate) fn emit_facts<'tcx>(
-    all_facts: &mut Option<AllFacts>,
-    tcx: TyCtxt<'tcx>,
-    location_table: &LocationTable,
-    body: &Body<'tcx>,
-    borrow_set: &BorrowSet<'tcx>,
-    move_data: &MoveData<'_>,
-    universal_region_relations: &UniversalRegionRelations<'_>,
-) {
-    let Some(all_facts) = all_facts else {
-        // We don't do anything if there are no facts to fill.
-        return;
-    };
-    let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
-    emit_move_facts(all_facts, move_data, location_table, body);
-    emit_universal_region_facts(all_facts, borrow_set, universal_region_relations);
-    emit_cfg_and_loan_kills_facts(all_facts, tcx, location_table, body, borrow_set);
-    emit_loan_invalidations_facts(all_facts, tcx, location_table, body, borrow_set);
-}
-
-/// Emit facts needed for move/init analysis: moves and assignments.
-fn emit_move_facts(
-    all_facts: &mut AllFacts,
-    move_data: &MoveData<'_>,
-    location_table: &LocationTable,
-    body: &Body<'_>,
-) {
-    all_facts
-        .path_is_var
-        .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l)));
-
-    for (child, move_path) in move_data.move_paths.iter_enumerated() {
-        if let Some(parent) = move_path.parent {
-            all_facts.child_path.push((child, parent));
-        }
-    }
-
-    let fn_entry_start =
-        location_table.start_index(Location { block: START_BLOCK, statement_index: 0 });
-
-    // initialized_at
-    for init in move_data.inits.iter() {
-        match init.location {
-            InitLocation::Statement(location) => {
-                let block_data = &body[location.block];
-                let is_terminator = location.statement_index == block_data.statements.len();
-
-                if is_terminator && init.kind == InitKind::NonPanicPathOnly {
-                    // We are at the terminator of an init that has a panic path,
-                    // and where the init should not happen on panic
-
-                    for successor in block_data.terminator().successors() {
-                        if body[successor].is_cleanup {
-                            continue;
-                        }
-
-                        // The initialization happened in (or rather, when arriving at)
-                        // the successors, but not in the unwind block.
-                        let first_statement = Location { block: successor, statement_index: 0 };
-                        all_facts
-                            .path_assigned_at_base
-                            .push((init.path, location_table.start_index(first_statement)));
-                    }
-                } else {
-                    // In all other cases, the initialization just happens at the
-                    // midpoint, like any other effect.
-                    all_facts
-                        .path_assigned_at_base
-                        .push((init.path, location_table.mid_index(location)));
-                }
-            }
-            // Arguments are initialized on function entry
-            InitLocation::Argument(local) => {
-                assert!(body.local_kind(local) == LocalKind::Arg);
-                all_facts.path_assigned_at_base.push((init.path, fn_entry_start));
-            }
-        }
-    }
-
-    for (local, path) in move_data.rev_lookup.iter_locals_enumerated() {
-        if body.local_kind(local) != LocalKind::Arg {
-            // Non-arguments start out deinitialised; we simulate this with an
-            // initial move:
-            all_facts.path_moved_at_base.push((path, fn_entry_start));
-        }
-    }
-
-    // moved_out_at
-    // deinitialisation is assumed to always happen!
-    all_facts
-        .path_moved_at_base
-        .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source))));
-}
-
-/// Emit universal regions facts, and their relations.
-fn emit_universal_region_facts(
-    all_facts: &mut AllFacts,
-    borrow_set: &BorrowSet<'_>,
-    universal_region_relations: &UniversalRegionRelations<'_>,
-) {
-    // 1: universal regions are modeled in Polonius as a pair:
-    // - the universal region vid itself.
-    // - a "placeholder loan" associated to this universal region. Since they don't exist in
-    //   the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
-    //   added to the existing number of loans, as if they succeeded them in the set.
-    //
-    let universal_regions = &universal_region_relations.universal_regions;
-    all_facts
-        .universal_region
-        .extend(universal_regions.universal_regions_iter().map(PoloniusRegionVid::from));
-    let borrow_count = borrow_set.len();
-    debug!(
-        "emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}",
-        universal_regions.len(),
-        borrow_count
-    );
-
-    for universal_region in universal_regions.universal_regions_iter() {
-        let universal_region_idx = universal_region.index();
-        let placeholder_loan_idx = borrow_count + universal_region_idx;
-        all_facts.placeholder.push((universal_region.into(), placeholder_loan_idx.into()));
-    }
-
-    // 2: the universal region relations `outlives` constraints are emitted as
-    //  `known_placeholder_subset` facts.
-    for (fr1, fr2) in universal_region_relations.known_outlives() {
-        if fr1 != fr2 {
-            debug!(
-                "emit_universal_region_facts: emitting polonius `known_placeholder_subset` \
-                     fr1={:?}, fr2={:?}",
-                fr1, fr2
-            );
-            all_facts.known_placeholder_subset.push((fr1.into(), fr2.into()));
-        }
-    }
-}
-
-/// Emit facts about loan invalidations.
-fn emit_loan_invalidations_facts<'tcx>(
-    all_facts: &mut AllFacts,
-    tcx: TyCtxt<'tcx>,
-    location_table: &LocationTable,
-    body: &Body<'tcx>,
-    borrow_set: &BorrowSet<'tcx>,
-) {
-    loan_invalidations::emit_loan_invalidations(tcx, all_facts, location_table, body, borrow_set);
-}
-
-/// Emit facts about CFG points and edges, as well as locations where loans are killed.
-fn emit_cfg_and_loan_kills_facts<'tcx>(
-    all_facts: &mut AllFacts,
-    tcx: TyCtxt<'tcx>,
-    location_table: &LocationTable,
-    body: &Body<'tcx>,
-    borrow_set: &BorrowSet<'tcx>,
-) {
-    loan_kills::emit_loan_kills(tcx, all_facts, location_table, body, borrow_set);
-}
+pub(crate) mod legacy;
diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index 585d0eabf5b..3903c45fda5 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -275,7 +275,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         user_ty: ty::UserType<'tcx>,
         span: Span,
     ) {
-        let ty::UserType::Ty(user_ty) = user_ty else { bug!() };
+        let ty::UserTypeKind::Ty(user_ty) = user_ty.kind else { bug!() };
 
         // A fast path for a common case with closure input/output types.
         if let ty::Infer(_) = user_ty.kind() {
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index bbe2b55d8c4..1f2ec168f03 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -110,7 +110,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         ) {
             self.ascribe_user_type_skip_wf(
                 arg_decl.ty,
-                ty::UserType::Ty(user_ty),
+                ty::UserType::new(ty::UserTypeKind::Ty(user_ty)),
                 arg_decl.source_info.span,
             );
         }
@@ -119,7 +119,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         let output_decl = &body.local_decls[RETURN_PLACE];
         self.ascribe_user_type_skip_wf(
             output_decl.ty,
-            ty::UserType::Ty(user_provided_sig.output()),
+            ty::UserType::new(ty::UserTypeKind::Ty(user_provided_sig.output())),
             output_decl.source_info.span,
         );
     }
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
index 20d19a53752..05e4a176a6d 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
@@ -45,7 +45,7 @@ pub(super) fn generate<'a, 'tcx>(
     let (relevant_live_locals, boring_locals) =
         compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
 
-    polonius::populate_access_facts(typeck, body, move_data);
+    polonius::emit_access_facts(typeck, body, move_data);
 
     trace::trace(
         typeck,
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
index e8d8ae0850b..5ffba94ee68 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
@@ -11,88 +11,19 @@ use crate::location::{LocationIndex, LocationTable};
 type VarPointRelation = Vec<(Local, LocationIndex)>;
 type PathPointRelation = Vec<(MovePathIndex, LocationIndex)>;
 
-struct UseFactsExtractor<'a, 'tcx> {
-    var_defined_at: &'a mut VarPointRelation,
-    var_used_at: &'a mut VarPointRelation,
-    location_table: &'a LocationTable,
-    var_dropped_at: &'a mut VarPointRelation,
-    move_data: &'a MoveData<'tcx>,
-    path_accessed_at_base: &'a mut PathPointRelation,
-}
-
-// A Visitor to walk through the MIR and extract point-wise facts
-impl<'tcx> UseFactsExtractor<'_, 'tcx> {
-    fn location_to_index(&self, location: Location) -> LocationIndex {
-        self.location_table.mid_index(location)
-    }
-
-    fn insert_def(&mut self, local: Local, location: Location) {
-        debug!("UseFactsExtractor::insert_def()");
-        self.var_defined_at.push((local, self.location_to_index(location)));
-    }
-
-    fn insert_use(&mut self, local: Local, location: Location) {
-        debug!("UseFactsExtractor::insert_use()");
-        self.var_used_at.push((local, self.location_to_index(location)));
-    }
-
-    fn insert_drop_use(&mut self, local: Local, location: Location) {
-        debug!("UseFactsExtractor::insert_drop_use()");
-        self.var_dropped_at.push((local, self.location_to_index(location)));
-    }
-
-    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
-        debug!("UseFactsExtractor::insert_path_access({:?}, {:?})", path, location);
-        self.path_accessed_at_base.push((path, self.location_to_index(location)));
-    }
-
-    fn place_to_mpi(&self, place: &Place<'tcx>) -> Option<MovePathIndex> {
-        match self.move_data.rev_lookup.find(place.as_ref()) {
-            LookupResult::Exact(mpi) => Some(mpi),
-            LookupResult::Parent(mmpi) => mmpi,
-        }
-    }
-}
-
-impl<'a, 'tcx> Visitor<'tcx> for UseFactsExtractor<'a, 'tcx> {
-    fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
-        match def_use::categorize(context) {
-            Some(DefUse::Def) => self.insert_def(local, location),
-            Some(DefUse::Use) => self.insert_use(local, location),
-            Some(DefUse::Drop) => self.insert_drop_use(local, location),
-            _ => (),
-        }
-    }
-
-    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
-        self.super_place(place, context, location);
-        match context {
-            PlaceContext::NonMutatingUse(_) => {
-                if let Some(mpi) = self.place_to_mpi(place) {
-                    self.insert_path_access(mpi, location);
-                }
-            }
-
-            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
-                if let Some(mpi) = self.place_to_mpi(place) {
-                    self.insert_path_access(mpi, location);
-                }
-            }
-            _ => (),
-        }
-    }
-}
-
-pub(super) fn populate_access_facts<'a, 'tcx>(
+/// Emit polonius facts for variable defs, uses, drops, and path accesses.
+pub(super) fn emit_access_facts<'a, 'tcx>(
     typeck: &mut TypeChecker<'a, 'tcx>,
     body: &Body<'tcx>,
     move_data: &MoveData<'tcx>,
 ) {
     if let Some(facts) = typeck.all_facts.as_mut() {
-        debug!("populate_access_facts()");
+        debug!("emit_access_facts()");
+
+        let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation");
         let location_table = typeck.location_table;
 
-        let mut extractor = UseFactsExtractor {
+        let mut extractor = AccessFactsExtractor {
             var_defined_at: &mut facts.var_defined_at,
             var_used_at: &mut facts.var_used_at,
             var_dropped_at: &mut facts.var_dropped_at,
@@ -107,7 +38,6 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
                 "add use_of_var_derefs_origin facts - local={:?}, type={:?}",
                 local, local_decl.ty
             );
-            let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation");
             let universal_regions = &typeck.universal_regions;
             typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| {
                 let region_vid = universal_regions.to_region_vid(region);
@@ -119,12 +49,12 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
 
 /// For every potentially drop()-touched region `region` in `local`'s type
 /// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
-pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
+pub(super) fn emit_drop_facts<'tcx>(
     typeck: &mut TypeChecker<'_, 'tcx>,
     local: Local,
     kind: &GenericArg<'tcx>,
 ) {
-    debug!("add_drop_of_var_derefs_origin(local={:?}, kind={:?}", local, kind);
+    debug!("emit_drop_facts(local={:?}, kind={:?}", local, kind);
     if let Some(facts) = typeck.all_facts.as_mut() {
         let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation");
         let universal_regions = &typeck.universal_regions;
@@ -134,3 +64,60 @@ pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
         });
     }
 }
+
+/// MIR visitor extracting point-wise facts about accesses.
+struct AccessFactsExtractor<'a, 'tcx> {
+    var_defined_at: &'a mut VarPointRelation,
+    var_used_at: &'a mut VarPointRelation,
+    location_table: &'a LocationTable,
+    var_dropped_at: &'a mut VarPointRelation,
+    move_data: &'a MoveData<'tcx>,
+    path_accessed_at_base: &'a mut PathPointRelation,
+}
+
+impl<'tcx> AccessFactsExtractor<'_, 'tcx> {
+    fn location_to_index(&self, location: Location) -> LocationIndex {
+        self.location_table.mid_index(location)
+    }
+}
+
+impl<'a, 'tcx> Visitor<'tcx> for AccessFactsExtractor<'a, 'tcx> {
+    fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
+        match def_use::categorize(context) {
+            Some(DefUse::Def) => {
+                debug!("AccessFactsExtractor - emit def");
+                self.var_defined_at.push((local, self.location_to_index(location)));
+            }
+            Some(DefUse::Use) => {
+                debug!("AccessFactsExtractor - emit use");
+                self.var_used_at.push((local, self.location_to_index(location)));
+            }
+            Some(DefUse::Drop) => {
+                debug!("AccessFactsExtractor - emit drop");
+                self.var_dropped_at.push((local, self.location_to_index(location)));
+            }
+            _ => (),
+        }
+    }
+
+    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
+        self.super_place(place, context, location);
+
+        match context {
+            PlaceContext::NonMutatingUse(_)
+            | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
+                let path = match self.move_data.rev_lookup.find(place.as_ref()) {
+                    LookupResult::Exact(path) | LookupResult::Parent(Some(path)) => path,
+                    _ => {
+                        // There's no path access to emit.
+                        return;
+                    }
+                };
+                debug!("AccessFactsExtractor - emit path access ({path:?}, {location:?})");
+                self.path_accessed_at_base.push((path, self.location_to_index(location)));
+            }
+
+            _ => {}
+        }
+    }
+}
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 3ec36c16cbf..539d3f97a63 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -590,7 +590,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
         // the destructor and must be live at this point.
         for &kind in &drop_data.dropck_result.kinds {
             Self::make_all_regions_live(self.elements, self.typeck, kind, live_at);
-            polonius::add_drop_of_var_derefs_origin(self.typeck, dropped_local, &kind);
+            polonius::emit_drop_facts(self.typeck, dropped_local, &kind);
         }
     }
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 89e683b8ae3..90d327b0ad2 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -31,7 +31,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{
     self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
     Dynamic, GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserArgs,
-    UserType, UserTypeAnnotationIndex,
+    UserTypeAnnotationIndex,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::ResultsCursor;
@@ -370,7 +370,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                 } else {
                     self.cx.ascribe_user_type(
                         constant.const_.ty(),
-                        UserType::TypeOf(uv.def, UserArgs { args: uv.args, user_self_ty: None }),
+                        ty::UserType::new(ty::UserTypeKind::TypeOf(uv.def, UserArgs {
+                            args: uv.args,
+                            user_self_ty: None,
+                        })),
                         locations.span(self.cx.body),
                     );
                 }
@@ -991,9 +994,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         for user_annotation in self.user_type_annotations {
             let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
             let annotation = self.instantiate_canonical(span, user_ty);
-            if let ty::UserType::TypeOf(def, args) = annotation
+            if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind
                 && let DefKind::InlineConst = tcx.def_kind(def)
             {
+                assert!(annotation.bounds.is_empty());
                 self.check_inline_const(inferred_ty, def.expect_local(), args, span);
             } else {
                 self.ascribe_user_type(inferred_ty, annotation, span);
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index 70fa4d00c0f..eb07975d8af 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -323,7 +323,8 @@ impl<'cx, 'a> Context<'cx, 'a> {
             | ExprKind::While(_, _, _)
             | ExprKind::Yeet(_)
             | ExprKind::Become(_)
-            | ExprKind::Yield(_) => {}
+            | ExprKind::Yield(_)
+            | ExprKind::UnsafeBinderCast(..) => {}
         }
     }
 
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index b2048c534a4..e7ff65e08f9 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -141,8 +141,10 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
 
         // We don't want to recurse into anything other than mods, since
         // mods or tests inside of functions will break things
-        if let ast::ItemKind::Mod(_, ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. })) =
-            item.kind
+        if let ast::ItemKind::Mod(
+            _,
+            ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _),
+        ) = item.kind
         {
             let prev_tests = mem::take(&mut self.tests);
             walk_item_kind(
diff --git a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs
index 2093b49ff31..b5a81fc11d5 100644
--- a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs
+++ b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs
@@ -1,8 +1,7 @@
 use std::sync::{Arc, Condvar, Mutex};
 
-use jobserver::HelperThread;
+use rustc_data_structures::jobserver::{self, HelperThread};
 use rustc_errors::DiagCtxtHandle;
-use rustc_session::Session;
 
 // FIXME don't panic when a worker thread panics
 
@@ -14,14 +13,13 @@ pub(super) struct ConcurrencyLimiter {
 }
 
 impl ConcurrencyLimiter {
-    pub(super) fn new(sess: &Session, pending_jobs: usize) -> Self {
+    pub(super) fn new(pending_jobs: usize) -> Self {
         let state = Arc::new(Mutex::new(state::ConcurrencyLimiterState::new(pending_jobs)));
         let available_token_condvar = Arc::new(Condvar::new());
 
         let state_helper = state.clone();
         let available_token_condvar_helper = available_token_condvar.clone();
-        let helper_thread = sess
-            .jobserver
+        let helper_thread = jobserver::client()
             .clone()
             .into_helper_thread(move |token| {
                 let mut state = state_helper.lock().unwrap();
@@ -113,7 +111,7 @@ impl Drop for ConcurrencyLimiterToken {
 }
 
 mod state {
-    use jobserver::Acquired;
+    use rustc_data_structures::jobserver::Acquired;
 
     #[derive(Debug)]
     pub(super) struct ConcurrencyLimiterState {
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 5bbcfc2cda7..4fc30b69123 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -679,7 +679,7 @@ pub(crate) fn run_aot(
             metadata_module: None,
             metadata,
             crate_info: CrateInfo::new(tcx, target_cpu),
-            concurrency_limiter: ConcurrencyLimiter::new(tcx.sess, 0),
+            concurrency_limiter: ConcurrencyLimiter::new(0),
         });
     };
 
@@ -711,7 +711,7 @@ pub(crate) fn run_aot(
             CguReuse::PreLto | CguReuse::PostLto => false,
         });
 
-    let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(tcx.sess, todo_cgus.len()));
+    let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(todo_cgus.len()));
 
     let modules = tcx.sess.time("codegen mono items", || {
         let mut modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| {
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index d68948966ea..4be4291021d 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
@@ -287,12 +287,7 @@ fn dep_symbol_lookup_fn(
 
     let mut dylib_paths = Vec::new();
 
-    let data = &crate_info
-        .dependency_formats
-        .iter()
-        .find(|(crate_type, _data)| *crate_type == rustc_session::config::CrateType::Executable)
-        .unwrap()
-        .1;
+    let data = &crate_info.dependency_formats[&rustc_session::config::CrateType::Executable].1;
     // `used_crates` is in reverse postorder in terms of dependencies. Reverse the order here to
     // get a postorder which ensures that all dependencies of a dylib are loaded before the dylib
     // itself. This helps the dynamic linker to find dylibs not in the regular dynamic library
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 9f552b3feb9..c38ef82e5b8 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -12,7 +12,6 @@
 #![warn(unused_lifetimes)]
 // tidy-alphabetical-end
 
-extern crate jobserver;
 #[macro_use]
 extern crate rustc_middle;
 extern crate rustc_abi;
@@ -175,7 +174,11 @@ impl CodegenBackend for CraneliftCodegenBackend {
         }
     }
 
-    fn target_features(&self, sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> {
+    fn target_features_cfg(
+        &self,
+        sess: &Session,
+        _allow_unstable: bool,
+    ) -> Vec<rustc_span::Symbol> {
         // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
         if sess.target.arch == "x86_64" && sess.target.os != "none" {
             // x86_64 mandates SSE2 support
diff --git a/compiler/rustc_codegen_gcc/messages.ftl b/compiler/rustc_codegen_gcc/messages.ftl
index 26ddc5732dd..85fa17a6ba5 100644
--- a/compiler/rustc_codegen_gcc/messages.ftl
+++ b/compiler/rustc_codegen_gcc/messages.ftl
@@ -9,7 +9,7 @@ codegen_gcc_lto_not_supported =
     LTO is not supported. You may get a linker error.
 
 codegen_gcc_forbidden_ctarget_feature =
-    target feature `{$feature}` cannot be toggled with `-Ctarget-feature`
+    target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason}
 
 codegen_gcc_unwinding_inline_asm =
     GCC backend does not support unwinding from inline asm
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index a1f9eab10e7..415f8affab9 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -867,6 +867,13 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         template_str.push_str("\n.popsection");
         self.context.add_top_level_asm(None, &template_str);
     }
+
+    fn mangled_name(&self, instance: Instance<'tcx>) -> String {
+        // TODO(@Amanieu): Additional mangling is needed on
+        // some targets to add a leading underscore (Mach-O)
+        // or byte count suffixes (x86 Windows).
+        self.tcx.symbol_name(instance).name.to_string()
+    }
 }
 
 fn modifier_to_gcc(
diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs
index 7a586b5b04c..56849cc8610 100644
--- a/compiler/rustc_codegen_gcc/src/errors.rs
+++ b/compiler/rustc_codegen_gcc/src/errors.rs
@@ -28,6 +28,7 @@ pub(crate) struct UnstableCTargetFeature<'a> {
 #[diag(codegen_gcc_forbidden_ctarget_feature)]
 pub(crate) struct ForbiddenCTargetFeature<'a> {
     pub feature: &'a str,
+    pub reason: &'a str,
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs
index 65279c9495a..058a874501b 100644
--- a/compiler/rustc_codegen_gcc/src/gcc_util.rs
+++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs
@@ -5,7 +5,7 @@ use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::bug;
 use rustc_session::Session;
-use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability};
+use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
 use smallvec::{SmallVec, smallvec};
 
 use crate::errors::{
@@ -94,13 +94,17 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
                         };
                         sess.dcx().emit_warn(unknown_feature);
                     }
-                    Some((_, Stability::Stable, _)) => {}
-                    Some((_, Stability::Unstable(_), _)) => {
-                        // An unstable feature. Warn about using it.
-                        sess.dcx().emit_warn(UnstableCTargetFeature { feature });
-                    }
-                    Some((_, Stability::Forbidden { .. }, _)) => {
-                        sess.dcx().emit_err(ForbiddenCTargetFeature { feature });
+                    Some((_, stability, _)) => {
+                        if let Err(reason) =
+                            stability.toggle_allowed(&sess.target, enable_disable == '+')
+                        {
+                            sess.dcx().emit_warn(ForbiddenCTargetFeature { feature, reason });
+                        } else if stability.requires_nightly().is_some() {
+                            // An unstable feature. Warn about using it. (It makes little sense
+                            // to hard-error here since we just warn about fully unknown
+                            // features above).
+                            sess.dcx().emit_warn(UnstableCTargetFeature { feature });
+                        }
                     }
                 }
 
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 452e92bffa2..bb0f2fa5b01 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -260,8 +260,8 @@ impl CodegenBackend for GccCodegenBackend {
             .join(sess)
     }
 
-    fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
-        target_features(sess, allow_unstable, &self.target_info)
+    fn target_features_cfg(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
+        target_features_cfg(sess, allow_unstable, &self.target_info)
     }
 }
 
@@ -472,7 +472,8 @@ fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel {
     }
 }
 
-pub fn target_features(
+/// Returns the features that should be set in `cfg(target_feature)`.
+fn target_features_cfg(
     sess: &Session,
     allow_unstable: bool,
     target_info: &LockedTargetInfo,
@@ -481,10 +482,10 @@ pub fn target_features(
     sess.target
         .rust_target_features()
         .iter()
-        .filter(|(_, gate, _)| gate.is_supported())
-        .filter_map(|&(feature, gate, _)| {
-            if sess.is_nightly_build() || allow_unstable || gate.is_stable() {
-                Some(feature)
+        .filter(|(_, gate, _)| gate.in_cfg())
+        .filter_map(|(feature, gate, _)| {
+            if sess.is_nightly_build() || allow_unstable || gate.requires_nightly().is_none() {
+                Some(*feature)
             } else {
                 None
             }
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index d1804cb49ad..3722d4350a2 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -442,6 +442,14 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
             );
         }
     }
+
+    fn mangled_name(&self, instance: Instance<'tcx>) -> String {
+        let llval = self.get_fn(instance);
+        llvm::build_string(|s| unsafe {
+            llvm::LLVMRustGetMangledName(llval, s);
+        })
+        .expect("symbol is not valid UTF-8")
+    }
 }
 
 pub(crate) fn inline_asm_call<'ll>(
@@ -504,14 +512,13 @@ pub(crate) fn inline_asm_call<'ll>(
             let key = "srcloc";
             let kind = llvm::LLVMGetMDKindIDInContext(
                 bx.llcx,
-                key.as_ptr() as *const c_char,
+                key.as_ptr().cast::<c_char>(),
                 key.len() as c_uint,
             );
 
-            // srcloc contains one integer for each line of assembly code.
-            // Unfortunately this isn't enough to encode a full span so instead
-            // we just encode the start position of each line.
-            // FIXME: Figure out a way to pass the entire line spans.
+            // `srcloc` contains one 64-bit integer for each line of assembly code,
+            // where the lower 32 bits hold the lo byte position and the upper 32 bits
+            // hold the hi byte position.
             let mut srcloc = vec![];
             if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
                 // LLVM inserts an extra line to add the ".intel_syntax", so add
@@ -521,13 +528,13 @@ pub(crate) fn inline_asm_call<'ll>(
                 // due to the asm template string coming from a macro. LLVM will
                 // default to the first srcloc for lines that don't have an
                 // associated srcloc.
-                srcloc.push(llvm::LLVMValueAsMetadata(bx.const_i32(0)));
+                srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
             }
-            srcloc.extend(
-                line_spans
-                    .iter()
-                    .map(|span| llvm::LLVMValueAsMetadata(bx.const_i32(span.lo().to_u32() as i32))),
-            );
+            srcloc.extend(line_spans.iter().map(|span| {
+                llvm::LLVMValueAsMetadata(bx.const_u64(
+                    u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32),
+                ))
+            }));
             let md = llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len());
             let md = llvm::LLVMMetadataAsValue(&bx.llcx, md);
             llvm::LLVMSetMetadata(call, kind, md);
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index cb958c1d4d7..5552a241060 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -395,17 +395,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         to_add.push(MemoryEffects::None.create_attr(cx.llcx));
     }
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
-        to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
-        // HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions.
-        // And it is a module-level attribute, so the alternative is pulling naked functions into
-        // new LLVM modules. Otherwise LLVM's "naked" functions come with endbr prefixes per
-        // https://github.com/rust-lang/rust/issues/98768
-        to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
-        if llvm_util::get_version() < (19, 0, 0) {
-            // Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
-            // the string "false". Now it is disabled by absence of the attribute.
-            to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
-        }
+        // do nothing; a naked function is converted into an extern function
+        // and a global assembly block. LLVM's support for naked functions is
+        // not used.
     } else {
         // Do not set sanitizer attributes for naked functions.
         to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index bde6668929c..66ca4e2b473 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -25,8 +25,8 @@ use rustc_session::Session;
 use rustc_session::config::{
     self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath,
 };
-use rustc_span::InnerSpan;
 use rustc_span::symbol::sym;
+use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext};
 use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
 use tracing::debug;
 
@@ -415,21 +415,32 @@ fn report_inline_asm(
     cgcx: &CodegenContext<LlvmCodegenBackend>,
     msg: String,
     level: llvm::DiagnosticLevel,
-    mut cookie: u64,
+    cookie: u64,
     source: Option<(String, Vec<InnerSpan>)>,
 ) {
     // In LTO build we may get srcloc values from other crates which are invalid
     // since they use a different source map. To be safe we just suppress these
     // in LTO builds.
-    if matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
-        cookie = 0;
-    }
+    let span = if cookie == 0 || matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
+        SpanData::default()
+    } else {
+        let lo = BytePos::from_u32(cookie as u32);
+        let hi = BytePos::from_u32((cookie >> 32) as u32);
+        SpanData {
+            lo,
+            // LLVM version < 19 silently truncates the cookie to 32 bits in some situations.
+            hi: if hi.to_u32() != 0 { hi } else { lo },
+            ctxt: SyntaxContext::root(),
+            parent: None,
+        }
+    };
     let level = match level {
         llvm::DiagnosticLevel::Error => Level::Error,
         llvm::DiagnosticLevel::Warning => Level::Warning,
         llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
     };
-    cgcx.diag_emitter.inline_asm_error(cookie.try_into().unwrap(), msg, level, source);
+    let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
+    cgcx.diag_emitter.inline_asm_error(span, msg, level, source);
 }
 
 unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index a573a37beb3..4f2af732527 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -75,10 +75,10 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
 
     // Encode all filenames referenced by coverage mappings in this CGU.
     let filenames_buffer = global_file_table.make_filenames_buffer(tcx);
-
-    let filenames_size = filenames_buffer.len();
-    let filenames_val = cx.const_bytes(&filenames_buffer);
-    let filenames_ref = llvm_cov::hash_bytes(&filenames_buffer);
+    // The `llvm-cov` tool uses this hash to associate each covfun record with
+    // its corresponding filenames table, since the final binary will typically
+    // contain multiple covmap records from different compilation units.
+    let filenames_hash = llvm_cov::hash_bytes(&filenames_buffer);
 
     let mut unused_function_names = Vec::new();
 
@@ -101,7 +101,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
     for covfun in &covfun_records {
         unused_function_names.extend(covfun.mangled_function_name_if_unused());
 
-        covfun::generate_covfun_record(cx, filenames_ref, covfun)
+        covfun::generate_covfun_record(cx, filenames_hash, covfun)
     }
 
     // For unused functions, we need to take their mangled names and store them
@@ -126,7 +126,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
     // Generate the coverage map header, which contains the filenames used by
     // this CGU's coverage mappings, and store it in a well-known global.
     // (This is skipped if we returned early due to having no covfun records.)
-    generate_covmap_record(cx, covmap_version, filenames_size, filenames_val);
+    generate_covmap_record(cx, covmap_version, &filenames_buffer);
 }
 
 /// Maps "global" (per-CGU) file ID numbers to their underlying filenames.
@@ -225,38 +225,35 @@ fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol {
 /// Generates the contents of the covmap record for this CGU, which mostly
 /// consists of a header and a list of filenames. The record is then stored
 /// as a global variable in the `__llvm_covmap` section.
-fn generate_covmap_record<'ll>(
-    cx: &CodegenCx<'ll, '_>,
-    version: u32,
-    filenames_size: usize,
-    filenames_val: &'ll llvm::Value,
-) {
-    debug!("cov map: filenames_size = {}, 0-based version = {}", filenames_size, version);
-
-    // Create the coverage data header (Note, fields 0 and 2 are now always zero,
-    // as of `llvm::coverage::CovMapVersion::Version4`.)
-    let zero_was_n_records_val = cx.const_u32(0);
-    let filenames_size_val = cx.const_u32(filenames_size as u32);
-    let zero_was_coverage_size_val = cx.const_u32(0);
-    let version_val = cx.const_u32(version);
-    let cov_data_header_val = cx.const_struct(
-        &[zero_was_n_records_val, filenames_size_val, zero_was_coverage_size_val, version_val],
-        /*packed=*/ false,
+fn generate_covmap_record<'ll>(cx: &CodegenCx<'ll, '_>, version: u32, filenames_buffer: &[u8]) {
+    // A covmap record consists of four target-endian u32 values, followed by
+    // the encoded filenames table. Two of the header fields are unused in
+    // modern versions of the LLVM coverage mapping format, and are always 0.
+    // <https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation>
+    // See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp`.
+    let covmap_header = cx.const_struct(
+        &[
+            cx.const_u32(0), // (unused)
+            cx.const_u32(filenames_buffer.len() as u32),
+            cx.const_u32(0), // (unused)
+            cx.const_u32(version),
+        ],
+        /* packed */ false,
     );
-
-    // Create the complete LLVM coverage data value to add to the LLVM IR
-    let covmap_data =
-        cx.const_struct(&[cov_data_header_val, filenames_val], /*packed=*/ false);
-
-    let llglobal = llvm::add_global(cx.llmod, cx.val_ty(covmap_data), &llvm_cov::covmap_var_name());
-    llvm::set_initializer(llglobal, covmap_data);
-    llvm::set_global_constant(llglobal, true);
-    llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
-    llvm::set_section(llglobal, &llvm_cov::covmap_section_name(cx.llmod));
+    let covmap_record = cx
+        .const_struct(&[covmap_header, cx.const_bytes(filenames_buffer)], /* packed */ false);
+
+    let covmap_global =
+        llvm::add_global(cx.llmod, cx.val_ty(covmap_record), &llvm_cov::covmap_var_name());
+    llvm::set_initializer(covmap_global, covmap_record);
+    llvm::set_global_constant(covmap_global, true);
+    llvm::set_linkage(covmap_global, llvm::Linkage::PrivateLinkage);
+    llvm::set_section(covmap_global, &llvm_cov::covmap_section_name(cx.llmod));
     // LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
     // <https://llvm.org/docs/CoverageMappingFormat.html>
-    llvm::set_alignment(llglobal, Align::EIGHT);
-    cx.add_used_global(llglobal);
+    llvm::set_alignment(covmap_global, Align::EIGHT);
+
+    cx.add_used_global(covmap_global);
 }
 
 /// Each CGU will normally only emit coverage metadata for the functions that it actually generates.
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
index 530e6827f55..33e7a0f2f20 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
@@ -136,7 +136,7 @@ fn fill_region_tables<'tcx>(
 /// as a global variable in the `__llvm_covfun` section.
 pub(crate) fn generate_covfun_record<'tcx>(
     cx: &CodegenCx<'_, 'tcx>,
-    filenames_ref: u64,
+    filenames_hash: u64,
     covfun: &CovfunRecord<'tcx>,
 ) {
     let &CovfunRecord {
@@ -155,46 +155,45 @@ pub(crate) fn generate_covfun_record<'tcx>(
         regions,
     );
 
-    // Concatenate the encoded coverage mappings
-    let coverage_mapping_size = coverage_mapping_buffer.len();
-    let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer);
-
+    // A covfun record consists of four target-endian integers, followed by the
+    // encoded mapping data in bytes. Note that the length field is 32 bits.
+    // <https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation>
+    // See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp` and
+    // `COVMAP_V3` in `src/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc`.
     let func_name_hash = llvm_cov::hash_bytes(mangled_function_name.as_bytes());
-    let func_name_hash_val = cx.const_u64(func_name_hash);
-    let coverage_mapping_size_val = cx.const_u32(coverage_mapping_size as u32);
-    let source_hash_val = cx.const_u64(source_hash);
-    let filenames_ref_val = cx.const_u64(filenames_ref);
-    let func_record_val = cx.const_struct(
+    let covfun_record = cx.const_struct(
         &[
-            func_name_hash_val,
-            coverage_mapping_size_val,
-            source_hash_val,
-            filenames_ref_val,
-            coverage_mapping_val,
+            cx.const_u64(func_name_hash),
+            cx.const_u32(coverage_mapping_buffer.len() as u32),
+            cx.const_u64(source_hash),
+            cx.const_u64(filenames_hash),
+            cx.const_bytes(&coverage_mapping_buffer),
         ],
-        /*packed=*/ true,
+        // This struct needs to be packed, so that the 32-bit length field
+        // doesn't have unexpected padding.
+        true,
     );
 
     // Choose a variable name to hold this function's covfun data.
     // Functions that are used have a suffix ("u") to distinguish them from
     // unused copies of the same function (from different CGUs), so that if a
     // linker sees both it won't discard the used copy's data.
-    let func_record_var_name =
-        CString::new(format!("__covrec_{:X}{}", func_name_hash, if is_used { "u" } else { "" }))
-            .unwrap();
-    debug!("function record var name: {:?}", func_record_var_name);
-
-    let llglobal = llvm::add_global(cx.llmod, cx.val_ty(func_record_val), &func_record_var_name);
-    llvm::set_initializer(llglobal, func_record_val);
-    llvm::set_global_constant(llglobal, true);
-    llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
-    llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
-    llvm::set_section(llglobal, cx.covfun_section_name());
+    let u = if is_used { "u" } else { "" };
+    let covfun_var_name = CString::new(format!("__covrec_{func_name_hash:X}{u}")).unwrap();
+    debug!("function record var name: {covfun_var_name:?}");
+
+    let covfun_global = llvm::add_global(cx.llmod, cx.val_ty(covfun_record), &covfun_var_name);
+    llvm::set_initializer(covfun_global, covfun_record);
+    llvm::set_global_constant(covfun_global, true);
+    llvm::set_linkage(covfun_global, llvm::Linkage::LinkOnceODRLinkage);
+    llvm::set_visibility(covfun_global, llvm::Visibility::Hidden);
+    llvm::set_section(covfun_global, cx.covfun_section_name());
     // LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
     // <https://llvm.org/docs/CoverageMappingFormat.html>
-    llvm::set_alignment(llglobal, Align::EIGHT);
+    llvm::set_alignment(covfun_global, Align::EIGHT);
     if cx.target_spec().supports_comdat() {
-        llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
+        llvm::set_comdat(cx.llmod, covfun_global, &covfun_var_name);
     }
-    cx.add_used_global(llglobal);
+
+    cx.add_used_global(covfun_global);
 }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 5235891a18d..af8562db054 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -27,7 +27,7 @@ use std::mem::ManuallyDrop;
 use back::owned_target_machine::OwnedTargetMachine;
 use back::write::{create_informational_target_machine, create_target_machine};
 use errors::ParseTargetMachineConfig;
-pub use llvm_util::target_features;
+pub use llvm_util::target_features_cfg;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
 use rustc_codegen_ssa::back::write::{
@@ -330,8 +330,8 @@ impl CodegenBackend for LlvmCodegenBackend {
         llvm_util::print_version();
     }
 
-    fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
-        target_features(sess, allow_unstable)
+    fn target_features_cfg(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
+        target_features_cfg(sess, allow_unstable)
     }
 
     fn codegen_crate<'tcx>(
diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
index a4cb5a25d1b..11043b664f5 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
@@ -151,7 +151,7 @@ impl InlineAsmDiagnostic {
             unsafe { SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)) };
         InlineAsmDiagnostic {
             level: smdiag.level,
-            cookie: cookie.into(),
+            cookie,
             message: smdiag.message,
             source: smdiag.source,
         }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index b1ace0033ba..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;
@@ -2317,7 +2319,7 @@ unsafe extern "C" {
 
     pub fn LLVMRustGetSMDiagnostic<'a>(
         DI: &'a DiagnosticInfo,
-        cookie_out: &mut c_uint,
+        cookie_out: &mut u64,
     ) -> &'a SMDiagnostic;
 
     pub fn LLVMRustUnpackSMDiagnostic(
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 07eb89e6041..194438af88c 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -17,7 +17,7 @@ use rustc_session::Session;
 use rustc_session::config::{PrintKind, PrintRequest};
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::{MergeFunctions, PanicStrategy, SmallDataThresholdSupport};
-use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES, Stability};
+use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES};
 
 use crate::back::write::create_informational_target_machine;
 use crate::errors::{
@@ -300,7 +300,7 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
 /// Must express features in the way Rust understands them.
 ///
 /// We do not have to worry about RUSTC_SPECIFIC_FEATURES here, those are handled outside codegen.
-pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
+pub fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
     let mut features: FxHashSet<Symbol> = Default::default();
 
     // Add base features for the target.
@@ -316,7 +316,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
         sess.target
             .rust_target_features()
             .iter()
-            .filter(|(_, gate, _)| gate.is_supported())
+            .filter(|(_, gate, _)| gate.in_cfg())
             .filter(|(feature, _, _)| {
                 // skip checking special features, as LLVM may not understand them
                 if RUSTC_SPECIAL_FEATURES.contains(feature) {
@@ -372,10 +372,10 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
     sess.target
         .rust_target_features()
         .iter()
-        .filter(|(_, gate, _)| gate.is_supported())
-        .filter_map(|&(feature, gate, _)| {
-            if sess.is_nightly_build() || allow_unstable || gate.is_stable() {
-                Some(feature)
+        .filter(|(_, gate, _)| gate.in_cfg())
+        .filter_map(|(feature, gate, _)| {
+            if sess.is_nightly_build() || allow_unstable || gate.requires_nightly().is_none() {
+                Some(*feature)
             } else {
                 None
             }
@@ -493,7 +493,7 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine, out: &mut Str
         .rust_target_features()
         .iter()
         .filter_map(|(feature, gate, _implied)| {
-            if !gate.is_supported() {
+            if !gate.in_cfg() {
                 // Only list (experimentally) supported features.
                 return None;
             }
@@ -716,13 +716,17 @@ pub(crate) fn global_llvm_features(
                             };
                             sess.dcx().emit_warn(unknown_feature);
                         }
-                        Some((_, Stability::Stable, _)) => {}
-                        Some((_, Stability::Unstable(_), _)) => {
-                            // An unstable feature. Warn about using it.
-                            sess.dcx().emit_warn(UnstableCTargetFeature { feature });
-                        }
-                        Some((_, Stability::Forbidden { reason }, _)) => {
-                            sess.dcx().emit_warn(ForbiddenCTargetFeature { feature, reason });
+                        Some((_, stability, _)) => {
+                            if let Err(reason) =
+                                stability.toggle_allowed(&sess.target, enable_disable == '+')
+                            {
+                                sess.dcx().emit_warn(ForbiddenCTargetFeature { feature, reason });
+                            } else if stability.requires_nightly().is_some() {
+                                // An unstable feature. Warn about using it. It makes little sense
+                                // to hard-error here since we just warn about fully unknown
+                                // features above.
+                                sess.dcx().emit_warn(UnstableCTargetFeature { feature });
+                            }
                         }
                     }
 
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index c81e36dfc8d..f5c155667ba 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -11,7 +11,6 @@ bitflags = "2.4.1"
 cc = "1.1.23"
 either = "1.5.0"
 itertools = "0.12"
-jobserver = "0.1.28"
 pathdiff = "0.2.0"
 regex = "1.4"
 rustc_abi = { path = "../rustc_abi" }
@@ -24,6 +23,7 @@ rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_fs_util = { path = "../rustc_fs_util" }
 rustc_hir = { path = "../rustc_hir" }
+rustc_hir_pretty = { path = "../rustc_hir_pretty" }
 rustc_incremental = { path = "../rustc_incremental" }
 rustc_index = { path = "../rustc_index" }
 rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
index 11bcd727501..d1b1ff88b4a 100644
--- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
+++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
@@ -26,9 +26,9 @@
 use std::borrow::Cow;
 use std::fmt;
 
-use rustc_ast as ast;
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::{DiagArgValue, IntoDiagArg};
+use rustc_hir as hir;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::mir::mono::CodegenUnitNameBuilder;
 use rustc_middle::ty::TyCtxt;
@@ -77,7 +77,7 @@ struct AssertModuleSource<'tcx> {
 }
 
 impl<'tcx> AssertModuleSource<'tcx> {
-    fn check_attr(&mut self, attr: &ast::Attribute) {
+    fn check_attr(&mut self, attr: &hir::Attribute) {
         let (expected_reuse, comp_kind) = if attr.has_name(sym::rustc_partition_reused) {
             (CguReuse::PreLto, ComparisonKind::AtLeast)
         } else if attr.has_name(sym::rustc_partition_codegened) {
@@ -158,7 +158,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
         );
     }
 
-    fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol {
+    fn field(&self, attr: &hir::Attribute, name: Symbol) -> Symbol {
         for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
             if item.has_name(name) {
                 if let Some(value) = item.value_str() {
@@ -177,7 +177,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
 
     /// Scan for a `cfg="foo"` attribute and check whether we have a
     /// cfg flag called `foo`.
-    fn check_config(&self, attr: &ast::Attribute) -> bool {
+    fn check_config(&self, attr: &hir::Attribute) -> bool {
         let config = &self.tcx.sess.psess.config;
         let value = self.field(attr, sym::cfg);
         debug!("check_config(config={:?}, value={:?})", config, value);
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 35d18d0206d..cfd40a575b1 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -236,7 +236,13 @@ pub fn each_linked_rlib(
 ) -> Result<(), errors::LinkRlibError> {
     let crates = info.used_crates.iter();
 
-    let fmts = if crate_type.is_none() {
+    let fmts = if let Some(crate_type) = crate_type {
+        let Some(fmts) = info.dependency_formats.get(&crate_type) else {
+            return Err(errors::LinkRlibError::MissingFormat);
+        };
+
+        fmts
+    } else {
         for combination in info.dependency_formats.iter().combinations(2) {
             let (ty1, list1) = &combination[0];
             let (ty2, list2) = &combination[1];
@@ -252,18 +258,7 @@ pub fn each_linked_rlib(
         if info.dependency_formats.is_empty() {
             return Err(errors::LinkRlibError::MissingFormat);
         }
-        &info.dependency_formats[0].1
-    } else {
-        let fmts = info
-            .dependency_formats
-            .iter()
-            .find_map(|&(ty, ref list)| if Some(ty) == crate_type { Some(list) } else { None });
-
-        let Some(fmts) = fmts else {
-            return Err(errors::LinkRlibError::MissingFormat);
-        };
-
-        fmts
+        info.dependency_formats.first().unwrap().1
     };
 
     for &cnum in crates {
@@ -624,8 +619,7 @@ fn link_staticlib(
     let fmts = codegen_results
         .crate_info
         .dependency_formats
-        .iter()
-        .find_map(|&(ty, ref list)| if ty == CrateType::Staticlib { Some(list) } else { None })
+        .get(&CrateType::Staticlib)
         .expect("no dependency formats for staticlib");
 
     let mut all_rust_dylibs = vec![];
@@ -992,12 +986,12 @@ fn link_natively(
                 let mut output = prog.stderr.clone();
                 output.extend_from_slice(&prog.stdout);
                 let escaped_output = escape_linker_output(&output, flavor);
-                // FIXME: Add UI tests for this error.
                 let err = errors::LinkingFailed {
                     linker_path: &linker_path,
                     exit_status: prog.status,
-                    command: &cmd,
+                    command: cmd,
                     escaped_output,
+                    verbose: sess.opts.verbose,
                 };
                 sess.dcx().emit_err(err);
                 // If MSVC's `link.exe` was expected but the return code
@@ -2355,11 +2349,10 @@ fn linker_with_args(
     // they are used within inlined functions or instantiated generic functions. We do this *after*
     // handling the raw-dylib symbols in the current crate to make sure that those are chosen first
     // by the linker.
-    let (_, dependency_linkage) = codegen_results
+    let dependency_linkage = codegen_results
         .crate_info
         .dependency_formats
-        .iter()
-        .find(|(ty, _)| *ty == crate_type)
+        .get(&crate_type)
         .expect("failed to find crate type in dependency format list");
 
     // We sort the libraries below
@@ -2738,11 +2731,10 @@ fn add_upstream_rust_crates(
     // Linking to a rlib involves just passing it to the linker (the linker
     // will slurp up the object files inside), and linking to a dynamic library
     // involves just passing the right -l flag.
-    let (_, data) = codegen_results
+    let data = codegen_results
         .crate_info
         .dependency_formats
-        .iter()
-        .find(|(ty, _)| *ty == crate_type)
+        .get(&crate_type)
         .expect("failed to find crate type in dependency format list");
 
     if sess.target.is_like_aix {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 4c5eb98e890..301b22f2be4 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1749,7 +1749,7 @@ fn for_each_exported_symbols_include_dep<'tcx>(
     }
 
     let formats = tcx.dependency_formats(());
-    let deps = formats.iter().find_map(|(t, list)| (*t == crate_type).then_some(list)).unwrap();
+    let deps = &formats[&crate_type];
 
     for (index, dep_format) in deps.iter().enumerate() {
         let cnum = CrateNum::new(index + 1);
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 90d48d6ee7e..683defcafee 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -6,9 +6,9 @@ use std::sync::Arc;
 use std::sync::mpsc::{Receiver, Sender, channel};
 use std::{fs, io, mem, str, thread};
 
-use jobserver::{Acquired, Client};
 use rustc_ast::attr;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
+use rustc_data_structures::jobserver::{self, Acquired};
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
 use rustc_errors::emitter::Emitter;
@@ -34,7 +34,7 @@ use rustc_session::config::{
 };
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::sym;
-use rustc_span::{BytePos, FileName, InnerSpan, Pos, Span};
+use rustc_span::{FileName, InnerSpan, Span, SpanData};
 use rustc_target::spec::{MergeFunctions, SanitizerSet};
 use tracing::debug;
 
@@ -456,7 +456,6 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
     metadata_module: Option<CompiledModule>,
 ) -> OngoingCodegen<B> {
     let (coordinator_send, coordinator_receive) = channel();
-    let sess = tcx.sess;
 
     let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
     let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins);
@@ -477,7 +476,6 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
         shared_emitter,
         codegen_worker_send,
         coordinator_receive,
-        sess.jobserver.clone(),
         Arc::new(regular_config),
         Arc::new(metadata_config),
         Arc::new(allocator_config),
@@ -1093,7 +1091,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
     shared_emitter: SharedEmitter,
     codegen_worker_send: Sender<CguMessage>,
     coordinator_receive: Receiver<Box<dyn Any + Send>>,
-    jobserver: Client,
     regular_config: Arc<ModuleConfig>,
     metadata_config: Arc<ModuleConfig>,
     allocator_config: Arc<ModuleConfig>,
@@ -1145,7 +1142,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
     // get tokens on `coordinator_receive` which will
     // get managed in the main loop below.
     let coordinator_send2 = coordinator_send.clone();
-    let helper = jobserver
+    let helper = jobserver::client()
         .into_helper_thread(move |token| {
             drop(coordinator_send2.send(Box::new(Message::Token::<B>(token))));
         })
@@ -1837,7 +1834,7 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
 
 enum SharedEmitterMessage {
     Diagnostic(Diagnostic),
-    InlineAsmError(u32, String, Level, Option<(String, Vec<InnerSpan>)>),
+    InlineAsmError(SpanData, String, Level, Option<(String, Vec<InnerSpan>)>),
     Fatal(String),
 }
 
@@ -1859,12 +1856,12 @@ impl SharedEmitter {
 
     pub fn inline_asm_error(
         &self,
-        cookie: u32,
+        span: SpanData,
         msg: String,
         level: Level,
         source: Option<(String, Vec<InnerSpan>)>,
     ) {
-        drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)));
+        drop(self.sender.send(SharedEmitterMessage::InlineAsmError(span, msg, level, source)));
     }
 
     fn fatal(&self, msg: &str) {
@@ -1953,17 +1950,12 @@ impl SharedEmitterMain {
                     dcx.emit_diagnostic(d);
                     sess.dcx().abort_if_errors();
                 }
-                Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
+                Ok(SharedEmitterMessage::InlineAsmError(span, msg, level, source)) => {
                     assert_matches!(level, Level::Error | Level::Warning | Level::Note);
-                    let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
                     let mut err = Diag::<()>::new(sess.dcx(), level, msg);
-
-                    // If the cookie is 0 then we don't have span information.
-                    if cookie != 0 {
-                        let pos = BytePos::from_u32(cookie);
-                        let span = Span::with_root_ctxt(pos, pos);
-                        err.span(span);
-                    };
+                    if !span.is_dummy() {
+                        err.span(span.span());
+                    }
 
                     // Point to the generated assembly if it is available.
                     if let Some((buffer, spans)) = source {
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 11744eabab0..5edd18bd3f4 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -1,4 +1,4 @@
-use rustc_ast::{MetaItemInner, MetaItemKind, ast, attr};
+use rustc_ast::{MetaItemInner, attr};
 use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_name};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::codes::*;
@@ -251,7 +251,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
             sym::target_feature => {
                 if !tcx.is_closure_like(did.to_def_id())
                     && let Some(fn_sig) = fn_sig()
-                    && fn_sig.skip_binder().safety() == hir::Safety::Safe
+                    && fn_sig.skip_binder().safety().is_safe()
                 {
                     if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
                         // The `#[target_feature]` attribute is allowed on
@@ -525,57 +525,59 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         if !attr.has_name(sym::inline) {
             return ia;
         }
-        match attr.meta_kind() {
-            Some(MetaItemKind::Word) => InlineAttr::Hint,
-            Some(MetaItemKind::List(ref items)) => {
-                inline_span = Some(attr.span);
-                if items.len() != 1 {
-                    struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument")
-                        .emit();
-                    InlineAttr::None
-                } else if list_contains_name(items, sym::always) {
-                    InlineAttr::Always
-                } else if list_contains_name(items, sym::never) {
-                    InlineAttr::Never
-                } else {
-                    struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
-                        .with_help("valid inline arguments are `always` and `never`")
-                        .emit();
+        if attr.is_word() {
+            InlineAttr::Hint
+        } else if let Some(ref items) = attr.meta_item_list() {
+            inline_span = Some(attr.span);
+            if items.len() != 1 {
+                struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit();
+                InlineAttr::None
+            } else if list_contains_name(items, sym::always) {
+                InlineAttr::Always
+            } else if list_contains_name(items, sym::never) {
+                InlineAttr::Never
+            } else {
+                struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
+                    .with_help("valid inline arguments are `always` and `never`")
+                    .emit();
 
-                    InlineAttr::None
-                }
+                InlineAttr::None
             }
-            Some(MetaItemKind::NameValue(_)) => ia,
-            None => ia,
+        } else {
+            ia
         }
     });
 
+    // naked function MUST NOT be inlined! This attribute is required for the rust compiler itself,
+    // but not for the code generation backend because at that point the naked function will just be
+    // a declaration, with a definition provided in global assembly.
+    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
+        codegen_fn_attrs.inline = InlineAttr::Never;
+    }
+
     codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
         if !attr.has_name(sym::optimize) {
             return ia;
         }
         let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit();
-        match attr.meta_kind() {
-            Some(MetaItemKind::Word) => {
+        if attr.is_word() {
+            err(attr.span, "expected one argument");
+            ia
+        } else if let Some(ref items) = attr.meta_item_list() {
+            inline_span = Some(attr.span);
+            if items.len() != 1 {
                 err(attr.span, "expected one argument");
-                ia
-            }
-            Some(MetaItemKind::List(ref items)) => {
-                inline_span = Some(attr.span);
-                if items.len() != 1 {
-                    err(attr.span, "expected one argument");
-                    OptimizeAttr::None
-                } else if list_contains_name(items, sym::size) {
-                    OptimizeAttr::Size
-                } else if list_contains_name(items, sym::speed) {
-                    OptimizeAttr::Speed
-                } else {
-                    err(items[0].span(), "invalid argument");
-                    OptimizeAttr::None
-                }
+                OptimizeAttr::None
+            } else if list_contains_name(items, sym::size) {
+                OptimizeAttr::Size
+            } else if list_contains_name(items, sym::speed) {
+                OptimizeAttr::Speed
+            } else {
+                err(items[0].span(), "invalid argument");
+                OptimizeAttr::None
             }
-            Some(MetaItemKind::NameValue(_)) => ia,
-            None => ia,
+        } else {
+            OptimizeAttr::None
         }
     });
 
@@ -634,10 +636,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         }
     }
 
-    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
-        codegen_fn_attrs.inline = InlineAttr::Never;
-    }
-
     // Weak lang items have the same semantics as "std internal" symbols in the
     // sense that they're preserved through all our LTO passes and only
     // strippable by the linker.
@@ -727,7 +725,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     false
 }
 
-fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
+fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
     use rustc_ast::{LitIntType, LitKind, MetaItemLit};
     let meta_item_list = attr.meta_item_list();
     let meta_item_list = meta_item_list.as_deref();
@@ -792,7 +790,7 @@ struct MixedExportNameAndNoMangleState<'a> {
     export_name: Option<Span>,
     hir_id: Option<HirId>,
     no_mangle: Option<Span>,
-    no_mangle_attr: Option<&'a ast::Attribute>,
+    no_mangle_attr: Option<&'a hir::Attribute>,
 }
 
 impl<'a> MixedExportNameAndNoMangleState<'a> {
@@ -800,7 +798,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
         self.export_name = Some(span);
     }
 
-    fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a ast::Attribute) {
+    fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a hir::Attribute) {
         self.no_mangle = Some(span);
         self.hir_id = Some(hir_id);
         self.no_mangle_attr = Some(attr_name);
@@ -821,7 +819,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
                 no_mangle,
                 errors::MixedExportNameAndNoMangle {
                     no_mangle,
-                    no_mangle_attr: rustc_ast_pretty::pprust::attribute_to_string(no_mangle_attr),
+                    no_mangle_attr: rustc_hir_pretty::attribute_to_string(&tcx, no_mangle_attr),
                     export_name,
                     removal_span: no_mangle,
                 },
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 00f8654e670..c7213bbc801 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -1,6 +1,7 @@
 //! Errors emitted by codegen_ssa
 
 use std::borrow::Cow;
+use std::ffi::OsString;
 use std::io::Error;
 use std::num::ParseIntError;
 use std::path::{Path, PathBuf};
@@ -345,21 +346,82 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
 }
 
 pub(crate) struct LinkingFailed<'a> {
-    pub linker_path: &'a PathBuf,
+    pub linker_path: &'a Path,
     pub exit_status: ExitStatus,
-    pub command: &'a Command,
+    pub command: Command,
     pub escaped_output: String,
+    pub verbose: bool,
 }
 
 impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
-    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
+    fn into_diag(mut self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
         let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_linking_failed);
         diag.arg("linker_path", format!("{}", self.linker_path.display()));
         diag.arg("exit_status", format!("{}", self.exit_status));
 
         let contains_undefined_ref = self.escaped_output.contains("undefined reference to");
 
-        diag.note(format!("{:?}", self.command)).note(self.escaped_output);
+        if self.verbose {
+            diag.note(format!("{:?}", self.command));
+        } else {
+            enum ArgGroup {
+                Regular(OsString),
+                Objects(usize),
+                Rlibs(PathBuf, Vec<OsString>),
+            }
+
+            // Omit rust object files and fold rlibs in the error by default to make linker errors a
+            // bit less verbose.
+            let orig_args = self.command.take_args();
+            let mut args: Vec<ArgGroup> = vec![];
+            for arg in orig_args {
+                if arg.as_encoded_bytes().ends_with(b".rcgu.o") {
+                    if let Some(ArgGroup::Objects(n)) = args.last_mut() {
+                        *n += 1;
+                    } else {
+                        args.push(ArgGroup::Objects(1));
+                    }
+                } else if arg.as_encoded_bytes().ends_with(b".rlib") {
+                    let rlib_path = Path::new(&arg);
+                    let dir = rlib_path.parent().unwrap();
+                    let filename = rlib_path.file_name().unwrap().to_owned();
+                    if let Some(ArgGroup::Rlibs(parent, rlibs)) = args.last_mut() {
+                        if parent == dir {
+                            rlibs.push(filename);
+                        } else {
+                            args.push(ArgGroup::Rlibs(dir.to_owned(), vec![filename]));
+                        }
+                    } else {
+                        args.push(ArgGroup::Rlibs(dir.to_owned(), vec![filename]));
+                    }
+                } else {
+                    args.push(ArgGroup::Regular(arg));
+                }
+            }
+            self.command.args(args.into_iter().map(|arg_group| match arg_group {
+                ArgGroup::Regular(arg) => arg,
+                ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")),
+                ArgGroup::Rlibs(dir, rlibs) => {
+                    let mut arg = dir.into_os_string();
+                    arg.push("/{");
+                    let mut first = true;
+                    for rlib in rlibs {
+                        if !first {
+                            arg.push(",");
+                        }
+                        first = false;
+                        arg.push(rlib);
+                    }
+                    arg.push("}");
+                    arg
+                }
+            }));
+
+            diag.note(format!("{:?}", self.command));
+            diag.note("some arguments are omitted. use `--verbose` to show all linker arguments");
+        }
+
+        diag.note(self.escaped_output);
 
         // Trying to match an error from OS linkers
         // which by now we have no way to translate.
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 0cbc5c45736..62f69af3f2f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -20,6 +20,7 @@ mod coverageinfo;
 pub mod debuginfo;
 mod intrinsic;
 mod locals;
+mod naked_asm;
 pub mod operand;
 pub mod place;
 mod rvalue;
@@ -176,6 +177,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
     debug!("fn_abi: {:?}", fn_abi);
 
+    if cx.tcx().codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) {
+        crate::mir::naked_asm::codegen_naked_asm::<Bx>(cx, &mir, instance);
+        return;
+    }
+
     let debug_context = cx.create_function_debug_context(instance, fn_abi, llfn, mir);
 
     let start_llbb = Bx::append_block(cx, llfn, "start");
diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
new file mode 100644
index 00000000000..c08758a9796
--- /dev/null
+++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
@@ -0,0 +1,266 @@
+use rustc_attr::InstructionSetAttr;
+use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
+use rustc_middle::mir::{Body, InlineAsmOperand};
+use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf};
+use rustc_middle::ty::{Instance, TyCtxt};
+use rustc_middle::{bug, ty};
+use rustc_span::sym;
+
+use crate::common;
+use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods};
+
+pub(crate) fn codegen_naked_asm<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+    cx: &'a Bx::CodegenCx,
+    mir: &Body<'tcx>,
+    instance: Instance<'tcx>,
+) {
+    let rustc_middle::mir::TerminatorKind::InlineAsm {
+        asm_macro: _,
+        template,
+        ref operands,
+        options,
+        line_spans,
+        targets: _,
+        unwind: _,
+    } = mir.basic_blocks.iter().next().unwrap().terminator().kind
+    else {
+        bug!("#[naked] functions should always terminate with an asm! block")
+    };
+
+    let operands: Vec<_> =
+        operands.iter().map(|op| inline_to_global_operand::<Bx>(cx, instance, op)).collect();
+
+    let item_data = cx.codegen_unit().items().get(&MonoItem::Fn(instance)).unwrap();
+    let name = cx.mangled_name(instance);
+    let (begin, end) = prefix_and_suffix(cx.tcx(), instance, &name, item_data);
+
+    let mut template_vec = Vec::new();
+    template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(begin.into()));
+    template_vec.extend(template.iter().cloned());
+    template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(end.into()));
+
+    cx.codegen_global_asm(&template_vec, &operands, options, line_spans);
+}
+
+fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+    cx: &'a Bx::CodegenCx,
+    instance: Instance<'tcx>,
+    op: &InlineAsmOperand<'tcx>,
+) -> GlobalAsmOperandRef<'tcx> {
+    match op {
+        InlineAsmOperand::Const { value } => {
+            let const_value = instance
+                .instantiate_mir_and_normalize_erasing_regions(
+                    cx.tcx(),
+                    cx.typing_env(),
+                    ty::EarlyBinder::bind(value.const_),
+                )
+                .eval(cx.tcx(), cx.typing_env(), value.span)
+                .expect("erroneous constant missed by mono item collection");
+
+            let mono_type = instance.instantiate_mir_and_normalize_erasing_regions(
+                cx.tcx(),
+                cx.typing_env(),
+                ty::EarlyBinder::bind(value.ty()),
+            );
+
+            let string = common::asm_const_to_str(
+                cx.tcx(),
+                value.span,
+                const_value,
+                cx.layout_of(mono_type),
+            );
+
+            GlobalAsmOperandRef::Const { string }
+        }
+        InlineAsmOperand::SymFn { value } => {
+            let mono_type = instance.instantiate_mir_and_normalize_erasing_regions(
+                cx.tcx(),
+                cx.typing_env(),
+                ty::EarlyBinder::bind(value.ty()),
+            );
+
+            let instance = match mono_type.kind() {
+                &ty::FnDef(def_id, args) => Instance::new(def_id, args),
+                _ => bug!("asm sym is not a function"),
+            };
+
+            GlobalAsmOperandRef::SymFn { instance }
+        }
+        InlineAsmOperand::SymStatic { def_id } => {
+            GlobalAsmOperandRef::SymStatic { def_id: *def_id }
+        }
+        InlineAsmOperand::In { .. }
+        | InlineAsmOperand::Out { .. }
+        | InlineAsmOperand::InOut { .. }
+        | InlineAsmOperand::Label { .. } => {
+            bug!("invalid operand type for naked_asm!")
+        }
+    }
+}
+
+enum AsmBinaryFormat {
+    Elf,
+    Macho,
+    Coff,
+}
+
+impl AsmBinaryFormat {
+    fn from_target(target: &rustc_target::spec::Target) -> Self {
+        if target.is_like_windows {
+            Self::Coff
+        } else if target.is_like_osx {
+            Self::Macho
+        } else {
+            Self::Elf
+        }
+    }
+}
+
+fn prefix_and_suffix<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    instance: Instance<'tcx>,
+    asm_name: &str,
+    item_data: &MonoItemData,
+) -> (String, String) {
+    use std::fmt::Write;
+
+    let asm_binary_format = AsmBinaryFormat::from_target(&tcx.sess.target);
+
+    let is_arm = tcx.sess.target.arch == "arm";
+    let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
+
+    let attrs = tcx.codegen_fn_attrs(instance.def_id());
+    let link_section = attrs.link_section.map(|symbol| symbol.as_str().to_string());
+    let align = attrs.alignment.map(|a| a.bytes()).unwrap_or(4);
+
+    // See https://sourceware.org/binutils/docs/as/ARM-Directives.html for info on these directives.
+    // In particular, `.arm` can also be written `.code 32` and `.thumb` as `.code 16`.
+    let (arch_prefix, arch_suffix) = if is_arm {
+        (
+            match attrs.instruction_set {
+                None => match is_thumb {
+                    true => ".thumb\n.thumb_func",
+                    false => ".arm",
+                },
+                Some(InstructionSetAttr::ArmT32) => ".thumb\n.thumb_func",
+                Some(InstructionSetAttr::ArmA32) => ".arm",
+            },
+            match is_thumb {
+                true => ".thumb",
+                false => ".arm",
+            },
+        )
+    } else {
+        ("", "")
+    };
+
+    let emit_fatal = |msg| tcx.dcx().span_fatal(tcx.def_span(instance.def_id()), msg);
+
+    // see https://godbolt.org/z/cPK4sxKor.
+    let write_linkage = |w: &mut String| -> std::fmt::Result {
+        match item_data.linkage {
+            Linkage::External => {
+                writeln!(w, ".globl {asm_name}")?;
+            }
+            Linkage::LinkOnceAny | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR => {
+                match asm_binary_format {
+                    AsmBinaryFormat::Elf | AsmBinaryFormat::Coff => {
+                        writeln!(w, ".weak {asm_name}")?;
+                    }
+                    AsmBinaryFormat::Macho => {
+                        writeln!(w, ".globl {asm_name}")?;
+                        writeln!(w, ".weak_definition {asm_name}")?;
+                    }
+                }
+            }
+            Linkage::Internal | Linkage::Private => {
+                // write nothing
+            }
+            Linkage::Appending => emit_fatal("Only global variables can have appending linkage!"),
+            Linkage::Common => emit_fatal("Functions may not have common linkage"),
+            Linkage::AvailableExternally => {
+                // this would make the function equal an extern definition
+                emit_fatal("Functions may not have available_externally linkage")
+            }
+            Linkage::ExternalWeak => {
+                // FIXME: actually this causes a SIGILL in LLVM
+                emit_fatal("Functions may not have external weak linkage")
+            }
+        }
+
+        Ok(())
+    };
+
+    let mut begin = String::new();
+    let mut end = String::new();
+    match asm_binary_format {
+        AsmBinaryFormat::Elf => {
+            let section = link_section.unwrap_or(format!(".text.{asm_name}"));
+
+            let progbits = match is_arm {
+                true => "%progbits",
+                false => "@progbits",
+            };
+
+            let function = match is_arm {
+                true => "%function",
+                false => "@function",
+            };
+
+            writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
+            writeln!(begin, ".balign {align}").unwrap();
+            write_linkage(&mut begin).unwrap();
+            if let Visibility::Hidden = item_data.visibility {
+                writeln!(begin, ".hidden {asm_name}").unwrap();
+            }
+            writeln!(begin, ".type {asm_name}, {function}").unwrap();
+            if !arch_prefix.is_empty() {
+                writeln!(begin, "{}", arch_prefix).unwrap();
+            }
+            writeln!(begin, "{asm_name}:").unwrap();
+
+            writeln!(end).unwrap();
+            writeln!(end, ".size {asm_name}, . - {asm_name}").unwrap();
+            writeln!(end, ".popsection").unwrap();
+            if !arch_suffix.is_empty() {
+                writeln!(end, "{}", arch_suffix).unwrap();
+            }
+        }
+        AsmBinaryFormat::Macho => {
+            let section = link_section.unwrap_or("__TEXT,__text".to_string());
+            writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
+            writeln!(begin, ".balign {align}").unwrap();
+            write_linkage(&mut begin).unwrap();
+            if let Visibility::Hidden = item_data.visibility {
+                writeln!(begin, ".private_extern {asm_name}").unwrap();
+            }
+            writeln!(begin, "{asm_name}:").unwrap();
+
+            writeln!(end).unwrap();
+            writeln!(end, ".popsection").unwrap();
+            if !arch_suffix.is_empty() {
+                writeln!(end, "{}", arch_suffix).unwrap();
+            }
+        }
+        AsmBinaryFormat::Coff => {
+            let section = link_section.unwrap_or(format!(".text.{asm_name}"));
+            writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
+            writeln!(begin, ".balign {align}").unwrap();
+            write_linkage(&mut begin).unwrap();
+            writeln!(begin, ".def {asm_name}").unwrap();
+            writeln!(begin, ".scl 2").unwrap();
+            writeln!(begin, ".type 32").unwrap();
+            writeln!(begin, ".endef {asm_name}").unwrap();
+            writeln!(begin, "{asm_name}:").unwrap();
+
+            writeln!(end).unwrap();
+            writeln!(end, ".popsection").unwrap();
+            if !arch_suffix.is_empty() {
+                writeln!(end, "{}", arch_suffix).unwrap();
+            }
+        }
+    }
+
+    (begin, end)
+}
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index c38484109d2..a9e80e27ed4 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -422,10 +422,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
             layout.size
         };
 
-        let llval = bx.inbounds_gep(bx.cx().backend_type(self.layout), self.val.llval, &[
-            bx.cx().const_usize(0),
-            llindex,
-        ]);
+        let llval = bx.inbounds_gep(bx.cx().backend_type(layout), self.val.llval, &[llindex]);
         let align = self.val.align.restrict_for_offset(offset);
         PlaceValue::new_sized(llval, align).with_type(layout)
     }
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index 038c5857fac..6749bc63327 100644
--- a/compiler/rustc_codegen_ssa/src/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -1,4 +1,5 @@
 use rustc_hir as hir;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
 use rustc_middle::ty::Instance;
@@ -135,7 +136,13 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
                 cx.predefine_static(def_id, linkage, visibility, symbol_name);
             }
             MonoItem::Fn(instance) => {
-                cx.predefine_fn(instance, linkage, visibility, symbol_name);
+                let attrs = cx.tcx().codegen_fn_attrs(instance.def_id());
+
+                if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
+                    // do not define this function; it will become a global assembly block
+                } else {
+                    cx.predefine_fn(instance, linkage, visibility, symbol_name);
+                };
             }
             MonoItem::GlobalAsm(..) => {}
         }
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index eee7cc75400..a84f5c74d1e 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -1,8 +1,8 @@
-use rustc_ast::ast;
 use rustc_attr::InstructionSetAttr;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::Applicability;
+use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
 use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
@@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
 use rustc_span::Span;
 use rustc_span::symbol::{Symbol, sym};
-use rustc_target::target_features::{self, Stability};
+use rustc_target::target_features;
 
 use crate::errors;
 
@@ -19,8 +19,8 @@ use crate::errors;
 /// Enabled target features are added to `target_features`.
 pub(crate) fn from_target_feature_attr(
     tcx: TyCtxt<'_>,
-    attr: &ast::Attribute,
-    rust_target_features: &UnordMap<String, target_features::Stability>,
+    attr: &hir::Attribute,
+    rust_target_features: &UnordMap<String, target_features::StabilityComputed>,
     target_features: &mut Vec<TargetFeature>,
 ) {
     let Some(list) = attr.meta_item_list() else { return };
@@ -63,32 +63,24 @@ pub(crate) fn from_target_feature_attr(
                 return None;
             };
 
-            // Only allow target features whose feature gates have been enabled.
-            let allowed = match stability {
-                Stability::Forbidden { .. } => false,
-                Stability::Stable => true,
-                Stability::Unstable(name) => rust_features.enabled(*name),
-            };
-            if !allowed {
-                match stability {
-                    Stability::Stable => unreachable!(),
-                    &Stability::Unstable(lang_feature_name) => {
-                        feature_err(
-                            &tcx.sess,
-                            lang_feature_name,
-                            item.span(),
-                            format!("the target feature `{feature}` is currently unstable"),
-                        )
-                        .emit();
-                    }
-                    Stability::Forbidden { reason } => {
-                        tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
-                            span: item.span(),
-                            feature,
-                            reason,
-                        });
-                    }
-                }
+            // Only allow target features whose feature gates have been enabled
+            // and which are permitted to be toggled.
+            if let Err(reason) = stability.toggle_allowed(/*enable*/ true) {
+                tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
+                    span: item.span(),
+                    feature,
+                    reason,
+                });
+            } else if let Some(nightly_feature) = stability.requires_nightly()
+                && !rust_features.enabled(nightly_feature)
+            {
+                feature_err(
+                    &tcx.sess,
+                    nightly_feature,
+                    item.span(),
+                    format!("the target feature `{feature}` is currently unstable"),
+                )
+                .emit();
             }
             Some(Symbol::intern(feature))
         }));
@@ -156,18 +148,19 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers {
         rust_target_features: |tcx, cnum| {
             assert_eq!(cnum, LOCAL_CRATE);
+            let target = &tcx.sess.target;
             if tcx.sess.opts.actually_rustdoc {
                 // rustdoc needs to be able to document functions that use all the features, so
                 // whitelist them all
                 rustc_target::target_features::all_rust_features()
-                    .map(|(a, b)| (a.to_string(), b))
+                    .map(|(a, b)| (a.to_string(), b.compute_toggleability(target)))
                     .collect()
             } else {
                 tcx.sess
                     .target
                     .rust_target_features()
                     .iter()
-                    .map(|&(a, b, _)| (a.to_string(), b))
+                    .map(|(a, b, _)| (a.to_string(), b.compute_toggleability(target)))
                     .collect()
             }
         },
diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs
index f4853da1156..7767bffbfbf 100644
--- a/compiler/rustc_codegen_ssa/src/traits/asm.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs
@@ -68,4 +68,11 @@ pub trait AsmCodegenMethods<'tcx> {
         options: InlineAsmOptions,
         line_spans: &[Span],
     );
+
+    /// The mangled name of this instance
+    ///
+    /// Additional mangling is used on
+    /// some targets to add a leading underscore (Mach-O)
+    /// or byte count suffixes (x86 Windows).
+    fn mangled_name(&self, instance: Instance<'tcx>) -> String;
 }
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 5b4a51fc301..4b17db2c49e 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -45,7 +45,9 @@ pub trait CodegenBackend {
 
     fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
 
-    fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
+    /// Returns the features that should be set in `cfg(target_features)`.
+    /// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen.
+    fn target_features_cfg(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
         vec![]
     }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 916929b6c0b..16610ebfca2 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -573,12 +573,27 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             ) => {}
             Rvalue::ShallowInitBox(_, _) => {}
 
-            Rvalue::UnaryOp(_, operand) => {
+            Rvalue::UnaryOp(op, operand) => {
                 let ty = operand.ty(self.body, self.tcx);
-                if is_int_bool_float_or_char(ty) {
-                    // Int, bool, float, and char operations are fine.
-                } else {
-                    span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
+                match op {
+                    UnOp::Not | UnOp::Neg => {
+                        if is_int_bool_float_or_char(ty) {
+                            // Int, bool, float, and char operations are fine.
+                        } else {
+                            span_bug!(
+                                self.span,
+                                "non-primitive type in `Rvalue::UnaryOp{op:?}`: {ty:?}",
+                            );
+                        }
+                    }
+                    UnOp::PtrMetadata => {
+                        if !ty.is_ref() && !ty.is_unsafe_ptr() {
+                            span_bug!(
+                                self.span,
+                                "non-pointer type in `Rvalue::UnaryOp({op:?})`: {ty:?}",
+                            );
+                        }
+                    }
                 }
             }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
index 0f9a460ca1b..763c37a41af 100644
--- a/compiler/rustc_const_eval/src/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
@@ -329,7 +329,7 @@ where
         self.transfer_function(state).initialize_state();
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         statement: &mir::Statement<'tcx>,
@@ -338,7 +338,7 @@ where
         self.transfer_function(state).visit_statement(statement, location);
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
         state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index beff0cd99fc..babf99c4c1f 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -4,27 +4,29 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 
-pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
+fn parent_impl_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
     let parent_id = tcx.local_parent(def_id);
-    matches!(tcx.def_kind(parent_id), DefKind::Impl { .. })
-        && tcx.constness(parent_id) == hir::Constness::Const
+    if matches!(tcx.def_kind(parent_id), DefKind::Impl { .. })
+        && let Some(header) = tcx.impl_trait_header(parent_id)
+    {
+        header.constness
+    } else {
+        hir::Constness::NotConst
+    }
 }
 
-/// Checks whether an item is considered to be `const`. If it is a constructor, anonymous const,
-/// const block, const item or associated const, it is const. If it is a trait impl/function,
+/// Checks whether an item is considered to be `const`. If it is a constructor, it is const.
+/// If it is an assoc method or function,
 /// return if it has a `const` modifier. If it is an intrinsic, report whether said intrinsic
-/// has a `rustc_const_{un,}stable` attribute. Otherwise, return `Constness::NotConst`.
+/// has a `rustc_const_{un,}stable` attribute. Otherwise, panic.
 fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
     let node = tcx.hir_node_by_def_id(def_id);
 
     match node {
-        hir::Node::Ctor(_)
-        | hir::Node::AnonConst(_)
-        | hir::Node::ConstBlock(_)
+        hir::Node::Ctor(hir::VariantData::Tuple(..))
         | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
             hir::Constness::Const
         }
-        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
         hir::Node::ForeignItem(_) => {
             // Foreign items cannot be evaluated at compile-time.
             hir::Constness::NotConst
@@ -38,10 +40,12 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
 
                 // If the function itself is not annotated with `const`, it may still be a `const fn`
                 // if it resides in a const trait impl.
-                let is_const = is_parent_const_impl_raw(tcx, def_id);
-                if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
+                parent_impl_constness(tcx, def_id)
             } else {
-                hir::Constness::NotConst
+                tcx.dcx().span_bug(
+                    tcx.def_span(def_id),
+                    format!("should not be requesting the constness of items that can't be const: {node:#?}: {:?}", tcx.def_kind(def_id))
+                )
             }
         }
     }
@@ -53,9 +57,8 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
             Some(stab) => {
                 if cfg!(debug_assertions) && stab.promotable {
                     let sig = tcx.fn_sig(def_id);
-                    assert_eq!(
-                        sig.skip_binder().safety(),
-                        hir::Safety::Safe,
+                    assert!(
+                        sig.skip_binder().safety().is_safe(),
                         "don't mark const unsafe fns as promotable",
                         // https://github.com/rust-lang/rust/pull/53851#issuecomment-418760682
                     );
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 56325eaa1be..23683851799 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -249,10 +249,9 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
         } else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
             // For panic_fmt, call const_panic_fmt instead.
             let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
-            // FIXME(@lcnr): why does this use an empty env if we've got a `param_env` right here.
             let new_instance = ty::Instance::expect_resolve(
                 *self.tcx,
-                ty::TypingEnv::fully_monomorphized(),
+                self.typing_env(),
                 const_def_id,
                 instance.args,
                 self.cur_span(),
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index a180d5da941..9ac2a024ccf 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -540,10 +540,14 @@ pub trait Machine<'tcx>: Sized {
         interp_ok(ReturnAction::Normal)
     }
 
-    /// Called immediately after an "immediate" local variable is read
+    /// Called immediately after an "immediate" local variable is read in a given frame
     /// (i.e., this is called for reads that do not end up accessing addressable memory).
     #[inline(always)]
-    fn after_local_read(_ecx: &InterpCx<'tcx, Self>, _local: mir::Local) -> InterpResult<'tcx> {
+    fn after_local_read(
+        _ecx: &InterpCx<'tcx, Self>,
+        _frame: &Frame<'tcx, Self::Provenance, Self::FrameExtra>,
+        _local: mir::Local,
+    ) -> InterpResult<'tcx> {
         interp_ok(())
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 0157e6c2125..b861ffb6110 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -15,9 +15,9 @@ use rustc_middle::{bug, mir, span_bug, ty};
 use tracing::trace;
 
 use super::{
-    CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode,
-    PlaceTy, Pointer, Projectable, Provenance, Scalar, alloc_range, err_ub, from_known_layout,
-    interp_ok, mir_assign_valid_types, throw_ub,
+    CtfeProvenance, Frame, InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta,
+    OffsetMode, PlaceTy, Pointer, Projectable, Provenance, Scalar, alloc_range, err_ub,
+    from_known_layout, interp_ok, mir_assign_valid_types, throw_ub,
 };
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
@@ -297,6 +297,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
 
     #[inline]
     pub fn from_bool(b: bool, tcx: TyCtxt<'tcx>) -> Self {
+        // Can use any typing env, since `bool` is always monomorphic.
         let layout = tcx
             .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.bool))
             .unwrap();
@@ -305,17 +306,18 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
 
     #[inline]
     pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self {
+        // Can use any typing env, since `Ordering` is always monomorphic.
         let ty = tcx.ty_ordering_enum(None);
         let layout =
             tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap();
         Self::from_scalar(Scalar::from_i8(c as i8), layout)
     }
 
-    pub fn from_pair(a: Self, b: Self, tcx: TyCtxt<'tcx>) -> Self {
-        let layout = tcx
+    pub fn from_pair(a: Self, b: Self, cx: &(impl HasTypingEnv<'tcx> + HasTyCtxt<'tcx>)) -> Self {
+        let layout = cx
+            .tcx()
             .layout_of(
-                ty::TypingEnv::fully_monomorphized()
-                    .as_query_input(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])),
+                cx.typing_env().as_query_input(Ty::new_tup(cx.tcx(), &[a.layout.ty, b.layout.ty])),
             )
             .unwrap();
         Self::from_scalar_pair(a.to_scalar(), b.to_scalar(), layout)
@@ -706,23 +708,32 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         interp_ok(str)
     }
 
-    /// Read from a local of the current frame.
+    /// Read from a local of the current frame. Convenience method for [`InterpCx::local_at_frame_to_op`].
+    pub fn local_to_op(
+        &self,
+        local: mir::Local,
+        layout: Option<TyAndLayout<'tcx>>,
+    ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
+        self.local_at_frame_to_op(self.frame(), local, layout)
+    }
+
+    /// Read from a local of a given frame.
     /// Will not access memory, instead an indirect `Operand` is returned.
     ///
-    /// This is public because it is used by [priroda](https://github.com/oli-obk/priroda) to get an
-    /// OpTy from a local.
-    pub fn local_to_op(
+    /// This is public because it is used by [Aquascope](https://github.com/cognitive-engineering-lab/aquascope/)
+    /// to get an OpTy from a local.
+    pub fn local_at_frame_to_op(
         &self,
+        frame: &Frame<'tcx, M::Provenance, M::FrameExtra>,
         local: mir::Local,
         layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
-        let frame = self.frame();
         let layout = self.layout_of_local(frame, local, layout)?;
         let op = *frame.locals[local].access()?;
         if matches!(op, Operand::Immediate(_)) {
             assert!(!layout.is_unsized());
         }
-        M::after_local_read(self, local)?;
+        M::after_local_read(self, frame, local)?;
         interp_ok(OpTy { op, layout })
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 1fa5dcbd24f..8b7b78c7129 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -222,7 +222,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let res = ImmTy::from_scalar_int(result, left.layout);
                 return interp_ok(if with_overflow {
                     let overflow = ImmTy::from_bool(overflow, *self.tcx);
-                    ImmTy::from_pair(res, overflow, *self.tcx)
+                    ImmTy::from_pair(res, overflow, self)
                 } else {
                     res
                 });
@@ -279,7 +279,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let res = ImmTy::from_scalar_int(result, left.layout);
                 if with_overflow {
                     let overflow = ImmTy::from_bool(overflow, *self.tcx);
-                    ImmTy::from_pair(res, overflow, *self.tcx)
+                    ImmTy::from_pair(res, overflow, self)
                 } else {
                     res
                 }
diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs
index a9ebf386617..6512675530a 100644
--- a/compiler/rustc_const_eval/src/interpret/stack.rs
+++ b/compiler/rustc_const_eval/src/interpret/stack.rs
@@ -584,8 +584,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         interp_ok(())
     }
 
+    /// This is public because it is used by [Aquascope](https://github.com/cognitive-engineering-lab/aquascope/)
+    /// to analyze all the locals in a stack frame.
     #[inline(always)]
-    pub(super) fn layout_of_local(
+    pub fn layout_of_local(
         &self,
         frame: &Frame<'tcx, M::Provenance, M::FrameExtra>,
         local: mir::Local,
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index b61865be667..a26c2eca107 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,6 +9,7 @@ use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::source_map::Spanned;
+use rustc_span::{DesugaringKind, Span};
 use rustc_target::callconv::FnAbi;
 use tracing::{info, instrument, trace};
 
@@ -80,7 +81,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         use rustc_middle::mir::StatementKind::*;
 
         match &stmt.kind {
-            Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
+            Assign(box (place, rvalue)) => {
+                self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
+            }
 
             SetDiscriminant { place, variant_index } => {
                 let dest = self.eval_place(**place)?;
@@ -159,6 +162,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         &mut self,
         rvalue: &mir::Rvalue<'tcx>,
         place: mir::Place<'tcx>,
+        span: Span,
     ) -> InterpResult<'tcx> {
         let dest = self.eval_place(place)?;
         // FIXME: ensure some kind of non-aliasing between LHS and RHS?
@@ -250,8 +254,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(&src)?;
                 let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
-                if !place_base_raw {
+                if !place_base_raw
+                    && span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
+                {
                     // If this was not already raw, it needs retagging.
+                    // As a special hack, we exclude the desugared `PtrMetadata(&raw const *_n)`
+                    // from indexing. (Really we should not do any retag on `&raw` but that does not
+                    // currently work with Stacked Borrows.)
                     val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
                 }
                 self.write_immediate(*val, &dest)?;
diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs
index d09f7efc8ff..1204f2d692d 100644
--- a/compiler/rustc_data_structures/src/jobserver.rs
+++ b/compiler/rustc_data_structures/src/jobserver.rs
@@ -1,6 +1,6 @@
 use std::sync::{LazyLock, OnceLock};
 
-pub use jobserver_crate::Client;
+pub use jobserver_crate::{Acquired, Client, HelperThread};
 use jobserver_crate::{FromEnv, FromEnvErrorKind};
 
 // We can only call `from_env_ext` once per process
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 2e01c385a66..b80736f41ad 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -45,7 +45,7 @@ use rustc_errors::registry::Registry;
 use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown};
 use rustc_feature::find_gated_cfg;
 use rustc_interface::util::{self, get_codegen_backend};
-use rustc_interface::{Linker, Queries, interface, passes};
+use rustc_interface::{Linker, interface, passes};
 use rustc_lint::unerased_lint_store;
 use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::locator;
@@ -158,13 +158,10 @@ pub trait Callbacks {
     /// Called after parsing the crate root. Submodules are not yet parsed when
     /// this callback is called. Return value instructs the compiler whether to
     /// continue the compilation afterwards (defaults to `Compilation::Continue`)
-    #[deprecated = "This callback will likely be removed or stop giving access \
-                    to the TyCtxt in the future. Use either the after_expansion \
-                    or the after_analysis callback instead."]
-    fn after_crate_root_parsing<'tcx>(
+    fn after_crate_root_parsing(
         &mut self,
         _compiler: &interface::Compiler,
-        _queries: &'tcx Queries<'tcx>,
+        _queries: &ast::Crate,
     ) -> Compilation {
         Compilation::Continue
     }
@@ -173,7 +170,7 @@ pub trait Callbacks {
     fn after_expansion<'tcx>(
         &mut self,
         _compiler: &interface::Compiler,
-        _queries: &'tcx Queries<'tcx>,
+        _tcx: TyCtxt<'tcx>,
     ) -> Compilation {
         Compilation::Continue
     }
@@ -350,6 +347,8 @@ fn run_compiler(
 
     callbacks.config(&mut config);
 
+    let registered_lints = config.register_lints.is_some();
+
     interface::run_compiler(config, |compiler| {
         let sess = &compiler.sess;
         let codegen_backend = &*compiler.codegen_backend;
@@ -365,7 +364,7 @@ fn run_compiler(
         // `--help`/`-Zhelp`/`-Chelp`. This is the earliest it can run, because
         // it must happen after lints are registered, during session creation.
         if sess.opts.describe_lints {
-            describe_lints(sess);
+            describe_lints(sess, registered_lints);
             return early_exit();
         }
 
@@ -416,8 +415,9 @@ fn run_compiler(
                 return early_exit();
             }
 
-            #[allow(deprecated)]
-            if callbacks.after_crate_root_parsing(compiler, queries) == Compilation::Stop {
+            if callbacks.after_crate_root_parsing(compiler, &*queries.parse().borrow())
+                == Compilation::Stop
+            {
                 return early_exit();
             }
 
@@ -425,18 +425,18 @@ fn run_compiler(
                 return early_exit();
             }
 
-            // Make sure name resolution and macro expansion is run.
-            queries.global_ctxt().enter(|tcx| tcx.resolver_for_lowering());
+            queries.global_ctxt().enter(|tcx| {
+                // Make sure name resolution and macro expansion is run.
+                let _ = tcx.resolver_for_lowering();
 
-            if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
-                queries.global_ctxt().enter(|tcxt| dump_feature_usage_metrics(tcxt, metrics_dir));
-            }
+                if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
+                    dump_feature_usage_metrics(tcx, metrics_dir);
+                }
 
-            if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
-                return early_exit();
-            }
+                if callbacks.after_expansion(compiler, tcx) == Compilation::Stop {
+                    return early_exit();
+                }
 
-            queries.global_ctxt().enter(|tcx| {
                 passes::write_dep_info(tcx);
 
                 if sess.opts.output_types.contains_key(&OutputType::DepInfo)
@@ -982,7 +982,7 @@ the command line flag directly.
 }
 
 /// Write to stdout lint command options, together with a list of all available lints
-pub fn describe_lints(sess: &Session) {
+pub fn describe_lints(sess: &Session, registered_lints: bool) {
     safe_println!(
         "
 Available lint options:
@@ -1086,7 +1086,7 @@ Available lint options:
 
     print_lint_groups(builtin_groups, true);
 
-    match (sess.registered_lints, loaded.len(), loaded_groups.len()) {
+    match (registered_lints, loaded.len(), loaded_groups.len()) {
         (false, 0, _) | (false, _, 0) => {
             safe_println!("Lint tools like Clippy can load additional lints and lint groups.");
         }
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/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 1b6c6edcc61..ac2f91cdeb3 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -3048,11 +3048,19 @@ impl FileWithAnnotatedLines {
                 // working correctly.
                 let middle = min(ann.line_start + 4, ann.line_end);
                 // We'll show up to 4 lines past the beginning of the multispan start.
-                // We will *not* include the tail of lines that are only whitespace.
+                // We will *not* include the tail of lines that are only whitespace, a comment or
+                // a bare delimiter.
+                let filter = |s: &str| {
+                    let s = s.trim();
+                    // Consider comments as empty, but don't consider docstrings to be empty.
+                    !(s.starts_with("//") && !(s.starts_with("///") || s.starts_with("//!")))
+                        // Consider lines with nothing but whitespace, a single delimiter as empty.
+                        && !["", "{", "}", "(", ")", "[", "]"].contains(&s)
+                };
                 let until = (ann.line_start..middle)
                     .rev()
                     .filter_map(|line| file.get_line(line - 1).map(|s| (line + 1, s)))
-                    .find(|(_, s)| !s.trim().is_empty())
+                    .find(|(_, s)| filter(s))
                     .map(|(line, _)| line)
                     .unwrap_or(ann.line_start);
                 for line in ann.line_start + 1..until {
@@ -3060,7 +3068,8 @@ impl FileWithAnnotatedLines {
                     add_annotation_to_file(&mut output, Lrc::clone(&file), line, ann.as_line());
                 }
                 let line_end = ann.line_end - 1;
-                if middle < line_end {
+                let end_is_empty = file.get_line(line_end - 1).map_or(false, |s| !filter(&s));
+                if middle < line_end && !end_is_empty {
                     add_annotation_to_file(&mut output, Lrc::clone(&file), line_end, ann.as_line());
                 }
             } else {
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_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index bed500c3032..8e42afb60d8 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -4,7 +4,7 @@ use std::path::Component::Prefix;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
 
-use rustc_ast::attr::MarkedAttrs;
+use rustc_ast::attr::{AttributeExt, MarkedAttrs};
 use rustc_ast::ptr::P;
 use rustc_ast::token::Nonterminal;
 use rustc_ast::tokenstream::TokenStream;
@@ -782,10 +782,12 @@ impl SyntaxExtension {
         }
     }
 
-    fn collapse_debuginfo_by_name(attr: &Attribute) -> Result<CollapseMacroDebuginfo, Span> {
+    fn collapse_debuginfo_by_name(
+        attr: &impl AttributeExt,
+    ) -> Result<CollapseMacroDebuginfo, Span> {
         let list = attr.meta_item_list();
         let Some([MetaItemInner::MetaItem(item)]) = list.as_deref() else {
-            return Err(attr.span);
+            return Err(attr.span());
         };
         if !item.is_word() {
             return Err(item.span);
@@ -805,7 +807,7 @@ impl SyntaxExtension {
     /// | (unspecified) | no  | if-ext        | if-ext   | yes |
     /// | external      | no  | if-ext        | if-ext   | yes |
     /// | yes           | yes | yes           | yes      | yes |
-    fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], ext: bool) -> bool {
+    fn get_collapse_debuginfo(sess: &Session, attrs: &[impl AttributeExt], ext: bool) -> bool {
         let flag = sess.opts.cg.collapse_macro_debuginfo;
         let attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
             .and_then(|attr| {
@@ -842,11 +844,11 @@ impl SyntaxExtension {
         helper_attrs: Vec<Symbol>,
         edition: Edition,
         name: Symbol,
-        attrs: &[ast::Attribute],
+        attrs: &[impl AttributeExt],
         is_local: bool,
     ) -> SyntaxExtension {
         let allow_internal_unstable =
-            attr::allow_internal_unstable(sess, attrs).collect::<Vec<Symbol>>();
+            rustc_attr::allow_internal_unstable(sess, attrs).collect::<Vec<Symbol>>();
 
         let allow_internal_unsafe = attr::contains_name(attrs, sym::allow_internal_unsafe);
         let local_inner_macros = attr::find_by_name(attrs, sym::macro_export)
@@ -1305,7 +1307,7 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe
 
 pub fn parse_macro_name_and_helper_attrs(
     dcx: DiagCtxtHandle<'_>,
-    attr: &Attribute,
+    attr: &impl AttributeExt,
     macro_type: &str,
 ) -> Option<(Symbol, Vec<Symbol>)> {
     // Once we've located the `#[proc_macro_derive]` attribute, verify
@@ -1313,7 +1315,7 @@ pub fn parse_macro_name_and_helper_attrs(
     // `#[proc_macro_derive(Foo, attributes(A, ..))]`
     let list = attr.meta_item_list()?;
     let ([trait_attr] | [trait_attr, _]) = list.as_slice() else {
-        dcx.emit_err(errors::AttrNoArguments { span: attr.span });
+        dcx.emit_err(errors::AttrNoArguments { span: attr.span() });
         return None;
     };
     let Some(trait_attr) = trait_attr.meta_item() else {
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 6a6496f9827..690e080fbfc 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -723,7 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                                     item_inner.kind,
                                     ItemKind::Mod(
                                         _,
-                                        ModKind::Unloaded | ModKind::Loaded(_, Inline::No, _),
+                                        ModKind::Unloaded | ModKind::Loaded(_, Inline::No, _, _),
                                     )
                                 ) =>
                         {
@@ -889,7 +889,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             fn visit_item(&mut self, item: &'ast ast::Item) {
                 match &item.kind {
                     ItemKind::Mod(_, mod_kind)
-                        if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) =>
+                        if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _)) =>
                     {
                         feature_err(
                             self.sess,
@@ -1195,7 +1195,7 @@ impl InvocationCollectorNode for P<ast::Item> {
 
         let ecx = &mut collector.cx;
         let (file_path, dir_path, dir_ownership) = match mod_kind {
-            ModKind::Loaded(_, inline, _) => {
+            ModKind::Loaded(_, inline, _, _) => {
                 // Inline `mod foo { ... }`, but we still need to push directories.
                 let (dir_path, dir_ownership) = mod_dir_path(
                     ecx.sess,
@@ -1217,15 +1217,21 @@ impl InvocationCollectorNode for P<ast::Item> {
             ModKind::Unloaded => {
                 // We have an outline `mod foo;` so we need to parse the file.
                 let old_attrs_len = attrs.len();
-                let ParsedExternalMod { items, spans, file_path, dir_path, dir_ownership } =
-                    parse_external_mod(
-                        ecx.sess,
-                        ident,
-                        span,
-                        &ecx.current_expansion.module,
-                        ecx.current_expansion.dir_ownership,
-                        &mut attrs,
-                    );
+                let ParsedExternalMod {
+                    items,
+                    spans,
+                    file_path,
+                    dir_path,
+                    dir_ownership,
+                    had_parse_error,
+                } = parse_external_mod(
+                    ecx.sess,
+                    ident,
+                    span,
+                    &ecx.current_expansion.module,
+                    ecx.current_expansion.dir_ownership,
+                    &mut attrs,
+                );
 
                 if let Some(lint_store) = ecx.lint_store {
                     lint_store.pre_expansion_lint(
@@ -1239,7 +1245,7 @@ impl InvocationCollectorNode for P<ast::Item> {
                     );
                 }
 
-                *mod_kind = ModKind::Loaded(items, Inline::No, spans);
+                *mod_kind = ModKind::Loaded(items, Inline::No, spans, had_parse_error);
                 node.attrs = attrs;
                 if node.attrs.len() > old_attrs_len {
                     // If we loaded an out-of-line module and added some inner attributes,
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index a373c753cc1..f7e3403cd28 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -9,7 +9,7 @@ use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
 use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId};
 use rustc_ast_pretty::pprust;
-use rustc_attr::{self as attr, TransparencyError};
+use rustc_attr::{self as attr, AttributeExt, TransparencyError};
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::{Applicability, ErrorGuaranteed};
 use rustc_feature::Features;
@@ -371,7 +371,7 @@ pub fn compile_declarative_macro(
     features: &Features,
     macro_def: &ast::MacroDef,
     ident: Ident,
-    attrs: &[ast::Attribute],
+    attrs: &[impl AttributeExt],
     span: Span,
     node_id: NodeId,
     edition: Edition,
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 614f52bbd28..85ea42e78ad 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -37,6 +37,7 @@ pub(crate) struct ParsedExternalMod {
     pub file_path: PathBuf,
     pub dir_path: PathBuf,
     pub dir_ownership: DirOwnership,
+    pub had_parse_error: Result<(), ErrorGuaranteed>,
 }
 
 pub enum ModError<'a> {
@@ -74,14 +75,17 @@ pub(crate) fn parse_external_mod(
         attrs.extend(inner_attrs);
         (items, inner_span, mp.file_path)
     };
+
     // (1) ...instead, we return a dummy module.
-    let (items, spans, file_path) =
-        result.map_err(|err| err.report(sess, span)).unwrap_or_default();
+    let ((items, spans, file_path), had_parse_error) = match result {
+        Err(err) => (Default::default(), Err(err.report(sess, span))),
+        Ok(result) => (result, Ok(())),
+    };
 
     // Extract the directory path for submodules of the module.
     let dir_path = file_path.parent().unwrap_or(&file_path).to_owned();
 
-    ParsedExternalMod { items, spans, file_path, dir_path, dir_ownership }
+    ParsedExternalMod { items, spans, file_path, dir_path, dir_ownership, had_parse_error }
 }
 
 pub(crate) fn mod_dir_path(
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/removed.rs b/compiler/rustc_feature/src/removed.rs
index 8b4f441dafe..e25840ba5fc 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -126,9 +126,6 @@ declare_features! (
             better implied higher-ranked implied bounds support"
         )
     ),
-    /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
-    (removed, impl_trait_in_bindings, "1.55.0", Some(63065),
-     Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
     (removed, import_shadowing, "1.0.0", None, None),
     /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
     (removed, in_band_lifetimes, "1.23.0", Some(44524),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 93a605e197c..76b9bee4b00 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -332,6 +332,7 @@ declare_features! (
     (unstable, hexagon_target_feature, "1.27.0", Some(44839)),
     (unstable, lahfsahf_target_feature, "1.78.0", Some(44839)),
     (unstable, loongarch_target_feature, "1.73.0", Some(44839)),
+    (unstable, m68k_target_feature, "CURRENT_RUSTC_VERSION", Some(134328)),
     (unstable, mips_target_feature, "1.27.0", Some(44839)),
     (unstable, powerpc_target_feature, "1.27.0", Some(44839)),
     (unstable, prfchw_target_feature, "1.78.0", Some(44839)),
@@ -342,6 +343,7 @@ declare_features! (
     (unstable, sse4a_target_feature, "1.27.0", Some(44839)),
     (unstable, tbm_target_feature, "1.27.0", Some(44839)),
     (unstable, wasm_target_feature, "1.30.0", Some(44839)),
+    (unstable, x87_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
     // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
@@ -388,8 +390,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.
@@ -516,6 +518,8 @@ declare_features! (
     (unstable, if_let_guard, "1.47.0", Some(51114)),
     /// Allows `impl Trait` to be used inside associated types (RFC 2515).
     (unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)),
+    /// Allows `impl Trait` in bindings (`let`).
+    (unstable, impl_trait_in_bindings, "1.64.0", Some(63065)),
     /// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
     (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
     /// Allows associated types in inherent impls.
@@ -635,6 +639,8 @@ declare_features! (
     /// Allows creation of instances of a struct by moving fields that have
     /// not changed from prior instances of the same struct (RFC #2528)
     (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
+    /// Allows using `unsafe<'a> &'a T` unsafe binder types.
+    (incomplete, unsafe_binders, "CURRENT_RUSTC_VERSION", Some(130516)),
     /// Allows declaring fields `unsafe`.
     (incomplete, unsafe_fields, "CURRENT_RUSTC_VERSION", Some(132922)),
     /// Allows const generic parameters to be defined with types that
diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml
index 85c6da83379..5bfc4756ec6 100644
--- a/compiler/rustc_hir/Cargo.toml
+++ b/compiler/rustc_hir/Cargo.toml
@@ -16,5 +16,6 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs
index f1f624269ae..88c0d223fd3 100644
--- a/compiler/rustc_hir/src/arena.rs
+++ b/compiler/rustc_hir/src/arena.rs
@@ -6,7 +6,7 @@ macro_rules! arena_types {
         $macro!([
             // HIR types
             [] asm_template: rustc_ast::InlineAsmTemplatePiece,
-            [] attribute: rustc_ast::Attribute,
+            [] attribute: rustc_hir::Attribute,
             [] owner_info: rustc_hir::OwnerInfo<'tcx>,
             [] use_path: rustc_hir::UsePath<'tcx>,
             [] lit: rustc_hir::Lit,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 4800a479ff4..56dba0c61e2 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1,14 +1,17 @@
 use std::fmt;
 
 use rustc_abi::ExternAbi;
+// ignore-tidy-filelength
+use rustc_ast::attr::AttributeExt;
+use rustc_ast::token::CommentKind;
 use rustc_ast::util::parser::{AssocOp, ExprPrecedence};
 use rustc_ast::{
-    self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
-    LitKind, TraitObjectSyntax, UintTy,
+    self as ast, AttrId, AttrStyle, DelimArgs, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece,
+    IntTy, Label, LitKind, MetaItemInner, MetaItemLit, TraitObjectSyntax, UintTy,
 };
 pub use rustc_ast::{
     BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy,
-    ImplPolarity, IsAuto, Movability, Mutability, UnOp,
+    ImplPolarity, IsAuto, Movability, Mutability, UnOp, UnsafeBinderCastKind,
 };
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::sorted_map::SortedMap;
@@ -21,6 +24,7 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym};
 use rustc_span::{BytePos, DUMMY_SP, ErrorGuaranteed, Span};
 use rustc_target::asm::InlineAsmRegOrRegClass;
 use smallvec::SmallVec;
+use thin_vec::ThinVec;
 use tracing::debug;
 
 use crate::LangItem;
@@ -937,6 +941,250 @@ pub struct ParentedNode<'tcx> {
     pub node: Node<'tcx>,
 }
 
+/// Arguments passed to an attribute macro.
+#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
+pub enum AttrArgs {
+    /// No arguments: `#[attr]`.
+    Empty,
+    /// Delimited arguments: `#[attr()/[]/{}]`.
+    Delimited(DelimArgs),
+    /// Arguments of a key-value attribute: `#[attr = "value"]`.
+    Eq {
+        /// Span of the `=` token.
+        eq_span: Span,
+        /// The "value".
+        expr: MetaItemLit,
+    },
+}
+
+#[derive(Clone, Debug, Encodable, Decodable)]
+pub enum AttrKind {
+    /// A normal attribute.
+    Normal(Box<AttrItem>),
+
+    /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
+    /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
+    /// variant (which is much less compact and thus more expensive).
+    DocComment(CommentKind, Symbol),
+}
+
+#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
+pub struct AttrPath {
+    pub segments: Box<[Ident]>,
+    pub span: Span,
+}
+
+#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
+pub struct AttrItem {
+    pub unsafety: Safety,
+    // Not lowered to hir::Path because we have no NodeId to resolve to.
+    pub path: AttrPath,
+    pub args: AttrArgs,
+}
+
+#[derive(Clone, Debug, Encodable, Decodable)]
+pub struct Attribute {
+    pub kind: AttrKind,
+    pub id: AttrId,
+    /// Denotes if the attribute decorates the following construct (outer)
+    /// or the construct this attribute is contained within (inner).
+    pub style: AttrStyle,
+    pub span: Span,
+}
+
+impl Attribute {
+    pub fn get_normal_item(&self) -> &AttrItem {
+        match &self.kind {
+            AttrKind::Normal(normal) => &normal,
+            AttrKind::DocComment(..) => panic!("unexpected doc comment"),
+        }
+    }
+
+    pub fn unwrap_normal_item(self) -> AttrItem {
+        match self.kind {
+            AttrKind::Normal(normal) => *normal,
+            AttrKind::DocComment(..) => panic!("unexpected doc comment"),
+        }
+    }
+
+    pub fn value_lit(&self) -> Option<&MetaItemLit> {
+        match &self.kind {
+            AttrKind::Normal(n) => match n.as_ref() {
+                AttrItem { args: AttrArgs::Eq { expr, .. }, .. } => Some(expr),
+                _ => None,
+            },
+            _ => None,
+        }
+    }
+}
+
+impl AttributeExt for Attribute {
+    fn id(&self) -> AttrId {
+        self.id
+    }
+
+    fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
+        match &self.kind {
+            AttrKind::Normal(n) => match n.as_ref() {
+                AttrItem { args: AttrArgs::Delimited(d), .. } => {
+                    ast::MetaItemKind::list_from_tokens(d.tokens.clone())
+                }
+                _ => None,
+            },
+            _ => None,
+        }
+    }
+
+    fn value_str(&self) -> Option<Symbol> {
+        self.value_lit().and_then(|x| x.value_str())
+    }
+
+    fn value_span(&self) -> Option<Span> {
+        self.value_lit().map(|i| i.span)
+    }
+
+    /// For a single-segment attribute, returns its name; otherwise, returns `None`.
+    fn ident(&self) -> Option<Ident> {
+        match &self.kind {
+            AttrKind::Normal(n) => {
+                if let [ident] = n.path.segments.as_ref() {
+                    Some(*ident)
+                } else {
+                    None
+                }
+            }
+            AttrKind::DocComment(..) => None,
+        }
+    }
+
+    fn path_matches(&self, name: &[Symbol]) -> bool {
+        match &self.kind {
+            AttrKind::Normal(n) => {
+                n.path.segments.len() == name.len()
+                    && n.path.segments.iter().zip(name).all(|(s, n)| s.name == *n)
+            }
+            AttrKind::DocComment(..) => false,
+        }
+    }
+
+    fn is_doc_comment(&self) -> bool {
+        matches!(self.kind, AttrKind::DocComment(..))
+    }
+
+    fn span(&self) -> Span {
+        self.span
+    }
+
+    fn is_word(&self) -> bool {
+        match &self.kind {
+            AttrKind::Normal(n) => {
+                matches!(n.args, AttrArgs::Empty)
+            }
+            AttrKind::DocComment(..) => false,
+        }
+    }
+
+    fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
+        match &self.kind {
+            AttrKind::Normal(n) => Some(n.path.segments.iter().copied().collect()),
+            AttrKind::DocComment(..) => None,
+        }
+    }
+
+    fn doc_str(&self) -> Option<Symbol> {
+        match &self.kind {
+            AttrKind::DocComment(.., data) => Some(*data),
+            AttrKind::Normal(_) if self.has_name(sym::doc) => self.value_str(),
+            _ => None,
+        }
+    }
+    fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
+        match &self.kind {
+            AttrKind::DocComment(kind, data) => Some((*data, *kind)),
+            AttrKind::Normal(_) if self.name_or_empty() == sym::doc => {
+                self.value_str().map(|s| (s, CommentKind::Line))
+            }
+            _ => None,
+        }
+    }
+
+    fn style(&self) -> AttrStyle {
+        self.style
+    }
+}
+
+// FIXME(fn_delegation): use function delegation instead of manually forwarding
+impl Attribute {
+    pub fn id(&self) -> AttrId {
+        AttributeExt::id(self)
+    }
+
+    pub fn name_or_empty(&self) -> Symbol {
+        AttributeExt::name_or_empty(self)
+    }
+
+    pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
+        AttributeExt::meta_item_list(self)
+    }
+
+    pub fn value_str(&self) -> Option<Symbol> {
+        AttributeExt::value_str(self)
+    }
+
+    pub fn value_span(&self) -> Option<Span> {
+        AttributeExt::value_span(self)
+    }
+
+    pub fn ident(&self) -> Option<Ident> {
+        AttributeExt::ident(self)
+    }
+
+    pub fn path_matches(&self, name: &[Symbol]) -> bool {
+        AttributeExt::path_matches(self, name)
+    }
+
+    pub fn is_doc_comment(&self) -> bool {
+        AttributeExt::is_doc_comment(self)
+    }
+
+    #[inline]
+    pub fn has_name(&self, name: Symbol) -> bool {
+        AttributeExt::has_name(self, name)
+    }
+
+    pub fn span(&self) -> Span {
+        AttributeExt::span(self)
+    }
+
+    pub fn is_word(&self) -> bool {
+        AttributeExt::is_word(self)
+    }
+
+    pub fn path(&self) -> SmallVec<[Symbol; 1]> {
+        AttributeExt::path(self)
+    }
+
+    pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
+        AttributeExt::ident_path(self)
+    }
+
+    pub fn doc_str(&self) -> Option<Symbol> {
+        AttributeExt::doc_str(self)
+    }
+
+    pub fn is_proc_macro_attr(&self) -> bool {
+        AttributeExt::is_proc_macro_attr(self)
+    }
+
+    pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
+        AttributeExt::doc_str_and_comment_kind(self)
+    }
+
+    pub fn style(&self) -> AttrStyle {
+        AttributeExt::style(self)
+    }
+}
+
 /// Attributes owned by a HIR owner.
 #[derive(Debug)]
 pub struct AttributeMap<'tcx> {
@@ -1740,6 +1988,7 @@ impl Expr<'_> {
             | ExprKind::Struct(..)
             | ExprKind::Tup(_)
             | ExprKind::Type(..)
+            | ExprKind::UnsafeBinderCast(..)
             | ExprKind::Err(_) => ExprPrecedence::Unambiguous,
 
             ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
@@ -1769,6 +2018,9 @@ impl Expr<'_> {
             // https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries
             ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
 
+            // Unsafe binder cast preserves place-ness of the sub-expression.
+            ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),
+
             ExprKind::Unary(UnOp::Deref, _) => true,
 
             ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
@@ -1850,7 +2102,8 @@ impl Expr<'_> {
             | ExprKind::Field(base, _)
             | ExprKind::Index(base, _, _)
             | ExprKind::AddrOf(.., base)
-            | ExprKind::Cast(base, _) => {
+            | ExprKind::Cast(base, _)
+            | ExprKind::UnsafeBinderCast(_, base, _) => {
                 // This isn't exactly true for `Index` and all `Unary`, but we are using this
                 // method exclusively for diagnostics and there's a *cultural* pressure against
                 // them being used only for its side-effects.
@@ -2020,6 +2273,22 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
     }
 }
 
+/// Checks if the specified expression needs parentheses for prefix
+/// or postfix suggestions to be valid.
+/// For example, `a + b` requires parentheses to suggest `&(a + b)`,
+/// but just `a` does not.
+/// Similarly, `(a + b).c()` also requires parentheses.
+/// This should not be used for other types of suggestions.
+pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
+    match expr.kind {
+        // parenthesize if needed (Issue #46756)
+        ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
+        // parenthesize borrows of range literals (Issue #54505)
+        _ if is_range_literal(expr) => true,
+        _ => false,
+    }
+}
+
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum ExprKind<'hir> {
     /// Allow anonymous constants from an inline `const` block
@@ -2144,6 +2413,10 @@ pub enum ExprKind<'hir> {
     /// A suspension point for coroutines (i.e., `yield <expr>`).
     Yield(&'hir Expr<'hir>, YieldSource),
 
+    /// Operators which can be used to interconvert `unsafe` binder types.
+    /// e.g. `unsafe<'a> &'a i32` <=> `&i32`.
+    UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),
+
     /// A placeholder for an expression that wasn't syntactically well formed in some way.
     Err(rustc_span::ErrorGuaranteed),
 }
@@ -2781,6 +3054,12 @@ pub struct BareFnTy<'hir> {
 }
 
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
+pub struct UnsafeBinderTy<'hir> {
+    pub generic_params: &'hir [GenericParam<'hir>],
+    pub inner_ty: &'hir Ty<'hir>,
+}
+
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct OpaqueTy<'hir> {
     pub hir_id: HirId,
     pub def_id: LocalDefId,
@@ -2878,6 +3157,8 @@ pub enum TyKind<'hir> {
     Ref(&'hir Lifetime, MutTy<'hir>),
     /// A bare function (e.g., `fn(usize) -> bool`).
     BareFn(&'hir BareFnTy<'hir>),
+    /// An unsafe binder type (e.g. `unsafe<'a> Foo<'a>`).
+    UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
     /// The never type (`!`).
     Never,
     /// A tuple (`(A, B, C, D, ...)`).
@@ -2889,6 +3170,8 @@ pub enum TyKind<'hir> {
     Path(QPath<'hir>),
     /// An opaque type definition itself. This is only used for `impl Trait`.
     OpaqueDef(&'hir OpaqueTy<'hir>),
+    /// A trait ascription type, which is `impl Trait` within a local binding.
+    TraitAscription(GenericBounds<'hir>),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
     TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
@@ -3399,6 +3682,19 @@ impl Safety {
             Self::Safe => "",
         }
     }
+
+    #[inline]
+    pub fn is_unsafe(self) -> bool {
+        !self.is_safe()
+    }
+
+    #[inline]
+    pub fn is_safe(self) -> bool {
+        match self {
+            Self::Unsafe => false,
+            Self::Safe => true,
+        }
+    }
 }
 
 impl fmt::Display for Safety {
@@ -3443,7 +3739,7 @@ impl FnHeader {
     }
 
     pub fn is_unsafe(&self) -> bool {
-        matches!(&self.safety, Safety::Unsafe)
+        self.safety.is_unsafe()
     }
 }
 
@@ -4042,9 +4338,7 @@ impl<'hir> Node<'hir> {
                 _ => None,
             },
             Node::TraitItem(ti) => match ti.kind {
-                TraitItemKind::Fn(ref sig, TraitFn::Provided(_)) => {
-                    Some(FnKind::Method(ti.ident, sig))
-                }
+                TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
                 _ => None,
             },
             Node::ImplItem(ii) => match ii.kind {
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 8dbfefffee4..5ed5a43d522 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -64,8 +64,8 @@
 //! This order consistency is required in a few places in rustc, for
 //! example coroutine inference, and possibly also HIR borrowck.
 
+use rustc_ast::Label;
 use rustc_ast::visit::{VisitorResult, try_visit, visit_opt, walk_list};
-use rustc_ast::{Attribute, Label};
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{Ident, Symbol};
@@ -857,6 +857,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         ExprKind::Yield(ref subexpression, _) => {
             try_visit!(visitor.visit_expr(subexpression));
         }
+        ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
+            try_visit!(visitor.visit_expr(expr));
+            visit_opt!(visitor, visit_ty, ty);
+        }
         ExprKind::Lit(_) | ExprKind::Err(_) => {}
     }
     V::Result::output()
@@ -886,12 +890,19 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
             walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
             try_visit!(visitor.visit_fn_decl(function_declaration.decl));
         }
+        TyKind::UnsafeBinder(ref unsafe_binder) => {
+            walk_list!(visitor, visit_generic_param, unsafe_binder.generic_params);
+            try_visit!(visitor.visit_ty(unsafe_binder.inner_ty));
+        }
         TyKind::Path(ref qpath) => {
             try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
         }
         TyKind::OpaqueDef(opaque) => {
             try_visit!(visitor.visit_opaque_ty(opaque));
         }
+        TyKind::TraitAscription(bounds) => {
+            walk_list!(visitor, visit_param_bound, bounds);
+        }
         TyKind::Array(ref ty, ref length) => {
             try_visit!(visitor.visit_ty(ty));
             try_visit!(visitor.visit_const_arg(length));
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 15cb331d07a..3684695774e 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -7,7 +7,7 @@
 //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
 //! * Functions called by the compiler itself.
 
-use rustc_ast as ast;
+use rustc_ast::attr::AttributeExt;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
@@ -153,11 +153,11 @@ impl<CTX> HashStable<CTX> for LangItem {
 
 /// Extracts the first `lang = "$name"` out of a list of attributes.
 /// The `#[panic_handler]` attribute is also extracted out when found.
-pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
+pub fn extract(attrs: &[impl AttributeExt]) -> Option<(Symbol, Span)> {
     attrs.iter().find_map(|attr| {
         Some(match attr {
-            _ if attr.has_name(sym::lang) => (attr.value_str()?, attr.span),
-            _ if attr.has_name(sym::panic_handler) => (sym::panic_impl, attr.span),
+            _ if attr.has_name(sym::lang) => (attr.value_str()?, attr.span()),
+            _ if attr.has_name(sym::panic_handler) => (sym::panic_impl, attr.span()),
             _ => return None,
         })
     })
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index fe169e989ec..db0d0fcf3b9 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -2,7 +2,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHas
 use rustc_span::def_id::DefPathHash;
 
 use crate::hir::{
-    AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
+    Attribute, AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes,
+    TraitItemId,
 };
 use crate::hir_id::{HirId, ItemLocalId};
 
@@ -12,6 +13,7 @@ use crate::hir_id::{HirId, ItemLocalId};
 pub trait HashStableContext:
     rustc_ast::HashStableContext + rustc_target::HashStableContext
 {
+    fn hash_attr(&mut self, _: &Attribute, hasher: &mut StableHasher);
 }
 
 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
@@ -113,3 +115,9 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Crate<'_> {
         opt_hir_hash.unwrap().hash_stable(hcx, hasher)
     }
 }
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Attribute {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_attr(self, hasher)
+    }
+}
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..0c3ed9b5c60 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -241,11 +241,23 @@ 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`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
+
+hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types =
     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`)
 
+hir_analysis_invalid_receiver_ty_help_nonnull_note =
+    `NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`
+
+hir_analysis_invalid_receiver_ty_help_weak_note =
+    `Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`
+
+hir_analysis_invalid_receiver_ty_no_arbitrary_self_types = invalid `self` parameter type: `{$receiver_ty}`
+    .note = type of `self` must be `Self` or a type that dereferences to it
+
 hir_analysis_invalid_union_field =
     field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
     .note = union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
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/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 022a6d457ec..8ff94fa566d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::MultiSpan;
 use rustc_errors::codes::*;
 use rustc_hir::def::{CtorKind, DefKind};
-use rustc_hir::{Node, Safety, intravisit};
+use rustc_hir::{Node, intravisit};
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::{Obligation, ObligationCauseCode};
 use rustc_lint_defs::builtin::{
@@ -161,7 +161,7 @@ fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
     };
     let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
     for field in def.all_fields() {
-        if field.safety != Safety::Unsafe {
+        if !field.safety.is_unsafe() {
             continue;
         }
         let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
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..95ad8225f61 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -44,6 +44,7 @@ use {rustc_ast as ast, rustc_hir as hir};
 use crate::autoderef::Autoderef;
 use crate::collect::CollectItemTypesVisitor;
 use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
+use crate::errors::InvalidReceiverTyHint;
 use crate::{errors, fluent_generated as fluent};
 
 pub(super) struct WfCheckingCtxt<'a, 'tcx> {
@@ -1748,8 +1749,25 @@ fn check_method_receiver<'tcx>(
             // Report error; would not have worked with `arbitrary_self_types[_pointers]`.
             {
                 match receiver_validity_err {
+                    ReceiverValidityError::DoesNotDeref if arbitrary_self_types_level.is_some() => {
+                        let hint = match receiver_ty
+                            .builtin_deref(false)
+                            .unwrap_or(receiver_ty)
+                            .ty_adt_def()
+                            .and_then(|adt_def| tcx.get_diagnostic_name(adt_def.did()))
+                        {
+                            Some(sym::RcWeak | sym::ArcWeak) => Some(InvalidReceiverTyHint::Weak),
+                            Some(sym::NonNull) => Some(InvalidReceiverTyHint::NonNull),
+                            _ => None,
+                        };
+
+                        tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty, hint })
+                    }
                     ReceiverValidityError::DoesNotDeref => {
-                        tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
+                        tcx.dcx().emit_err(errors::InvalidReceiverTyNoArbitrarySelfTypes {
+                            span,
+                            receiver_ty,
+                        })
                     }
                     ReceiverValidityError::MethodGenericParamUsed => {
                         tcx.dcx().emit_err(errors::InvalidGenericReceiverTy { span, receiver_ty })
@@ -1821,13 +1839,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 +1872,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 +1891,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 +1900,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 +1915,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_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 96d2714252a..8c9da78a659 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -29,7 +29,7 @@ use rustc_errors::{
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor, walk_generics};
-use rustc_hir::{self as hir, GenericParamKind, Node};
+use rustc_hir::{self as hir, GenericParamKind, HirId, Node};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::hir::nested_filter;
@@ -201,12 +201,13 @@ pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>(
         placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();
 
     if let Some(generics) = generics {
-        if let Some(arg) = params.iter().find(|arg| {
-            matches!(arg.name, hir::ParamName::Plain(Ident { name: kw::Underscore, .. }))
+        if let Some(span) = params.iter().find_map(|arg| match arg.name {
+            hir::ParamName::Plain(Ident { name: kw::Underscore, span }) => Some(span),
+            _ => None,
         }) {
             // Account for `_` already present in cases like `struct S<_>(_);` and suggest
             // `struct S<T>(T);` instead of `struct S<_, T>(T);`.
-            sugg.push((arg.span, (*type_name).to_string()));
+            sugg.push((span, (*type_name).to_string()));
         } else if let Some(span) = generics.span_for_param_suggestion() {
             // Account for bounds, we want `fn foo<T: E, K>(_: K)` not `fn foo<T, K: E>(_: K)`.
             sugg.push((span, format!(", {type_name}")));
@@ -436,6 +437,15 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
         ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
     }
 
+    fn register_trait_ascription_bounds(
+        &self,
+        _: Vec<(ty::Clause<'tcx>, Span)>,
+        _: HirId,
+        span: Span,
+    ) {
+        self.dcx().span_delayed_bug(span, "trait ascription type not allowed here");
+    }
+
     fn probe_ty_param_bounds(
         &self,
         span: Span,
@@ -1330,7 +1340,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
             ..
         })
         | Item(hir::Item { kind: ItemKind::Fn(sig, generics, _), .. }) => {
-            infer_return_ty_for_fn_sig(sig, generics, def_id, &icx)
+            lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
         }
 
         ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
@@ -1347,7 +1357,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
                     None,
                 )
             } else {
-                infer_return_ty_for_fn_sig(sig, generics, def_id, &icx)
+                lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
             }
         }
 
@@ -1397,99 +1407,108 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
     ty::EarlyBinder::bind(output)
 }
 
-fn infer_return_ty_for_fn_sig<'tcx>(
-    sig: &hir::FnSig<'tcx>,
-    generics: &hir::Generics<'_>,
+fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
+    icx: &ItemCtxt<'tcx>,
+    sig: &'tcx hir::FnSig<'tcx>,
+    generics: &'tcx hir::Generics<'tcx>,
     def_id: LocalDefId,
+) -> ty::PolyFnSig<'tcx> {
+    if let Some(infer_ret_ty) = sig.decl.output.get_infer_ret_ty() {
+        return recover_infer_ret_ty(icx, infer_ret_ty, generics, def_id);
+    }
+
+    icx.lowerer().lower_fn_ty(
+        icx.tcx().local_def_id_to_hir_id(def_id),
+        sig.header.safety,
+        sig.header.abi,
+        sig.decl,
+        Some(generics),
+        None,
+    )
+}
+
+fn recover_infer_ret_ty<'tcx>(
     icx: &ItemCtxt<'tcx>,
+    infer_ret_ty: &'tcx hir::Ty<'tcx>,
+    generics: &'tcx hir::Generics<'tcx>,
+    def_id: LocalDefId,
 ) -> ty::PolyFnSig<'tcx> {
     let tcx = icx.tcx;
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
 
-    match sig.decl.output.get_infer_ret_ty() {
-        Some(ty) => {
-            let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
-            // Typeck doesn't expect erased regions to be returned from `type_of`.
-            // This is a heuristic approach. If the scope has region parameters,
-            // we should change fn_sig's lifetime from `ReErased` to `ReError`,
-            // otherwise to `ReStatic`.
-            let has_region_params = generics.params.iter().any(|param| match param.kind {
-                GenericParamKind::Lifetime { .. } => true,
-                _ => false,
-            });
-            let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r {
-                ty::ReErased => {
-                    if has_region_params {
-                        ty::Region::new_error_with_message(
-                            tcx,
-                            DUMMY_SP,
-                            "erased region is not allowed here in return type",
-                        )
-                    } else {
-                        tcx.lifetimes.re_static
-                    }
-                }
-                _ => r,
-            });
+    let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
 
-            let mut visitor = HirPlaceholderCollector::default();
-            visitor.visit_ty(ty);
-
-            let mut diag = bad_placeholder(icx.lowerer(), visitor.0, "return type");
-            let ret_ty = fn_sig.output();
-            // Don't leak types into signatures unless they're nameable!
-            // For example, if a function returns itself, we don't want that
-            // recursive function definition to leak out into the fn sig.
-            let mut recovered_ret_ty = None;
-
-            if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
-                diag.span_suggestion(
-                    ty.span,
-                    "replace with the correct return type",
-                    suggestable_ret_ty,
-                    Applicability::MachineApplicable,
-                );
-                recovered_ret_ty = Some(suggestable_ret_ty);
-            } else if let Some(sugg) = suggest_impl_trait(
-                &tcx.infer_ctxt().build(TypingMode::non_body_analysis()),
-                tcx.param_env(def_id),
-                ret_ty,
-            ) {
-                diag.span_suggestion(
-                    ty.span,
-                    "replace with an appropriate return type",
-                    sugg,
-                    Applicability::MachineApplicable,
-                );
-            } else if ret_ty.is_closure() {
-                diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
-            }
-            // Also note how `Fn` traits work just in case!
-            if ret_ty.is_closure() {
-                diag.note(
-                    "for more information on `Fn` traits and closure types, see \
-                     https://doc.rust-lang.org/book/ch13-01-closures.html",
-                );
+    // Typeck doesn't expect erased regions to be returned from `type_of`.
+    // This is a heuristic approach. If the scope has region parameters,
+    // we should change fn_sig's lifetime from `ReErased` to `ReError`,
+    // otherwise to `ReStatic`.
+    let has_region_params = generics.params.iter().any(|param| match param.kind {
+        GenericParamKind::Lifetime { .. } => true,
+        _ => false,
+    });
+    let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r {
+        ty::ReErased => {
+            if has_region_params {
+                ty::Region::new_error_with_message(
+                    tcx,
+                    DUMMY_SP,
+                    "erased region is not allowed here in return type",
+                )
+            } else {
+                tcx.lifetimes.re_static
             }
-
-            let guar = diag.emit();
-            ty::Binder::dummy(tcx.mk_fn_sig(
-                fn_sig.inputs().iter().copied(),
-                recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
-                fn_sig.c_variadic,
-                fn_sig.safety,
-                fn_sig.abi,
-            ))
         }
-        None => icx.lowerer().lower_fn_ty(
-            hir_id,
-            sig.header.safety,
-            sig.header.abi,
-            sig.decl,
-            Some(generics),
-            None,
-        ),
+        _ => r,
+    });
+
+    let mut visitor = HirPlaceholderCollector::default();
+    visitor.visit_ty(infer_ret_ty);
+
+    let mut diag = bad_placeholder(icx.lowerer(), visitor.0, "return type");
+    let ret_ty = fn_sig.output();
+
+    // Don't leak types into signatures unless they're nameable!
+    // For example, if a function returns itself, we don't want that
+    // recursive function definition to leak out into the fn sig.
+    let mut recovered_ret_ty = None;
+    if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
+        diag.span_suggestion(
+            infer_ret_ty.span,
+            "replace with the correct return type",
+            suggestable_ret_ty,
+            Applicability::MachineApplicable,
+        );
+        recovered_ret_ty = Some(suggestable_ret_ty);
+    } else if let Some(sugg) = suggest_impl_trait(
+        &tcx.infer_ctxt().build(TypingMode::non_body_analysis()),
+        tcx.param_env(def_id),
+        ret_ty,
+    ) {
+        diag.span_suggestion(
+            infer_ret_ty.span,
+            "replace with an appropriate return type",
+            sugg,
+            Applicability::MachineApplicable,
+        );
+    } else if ret_ty.is_closure() {
+        diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
     }
+
+    // Also note how `Fn` traits work just in case!
+    if ret_ty.is_closure() {
+        diag.note(
+            "for more information on `Fn` traits and closure types, see \
+                     https://doc.rust-lang.org/book/ch13-01-closures.html",
+        );
+    }
+    let guar = diag.emit();
+    ty::Binder::dummy(tcx.mk_fn_sig(
+        fn_sig.inputs().iter().copied(),
+        recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
+        fn_sig.c_variadic,
+        fn_sig.safety,
+        fn_sig.abi,
+    ))
 }
 
 pub fn suggest_impl_trait<'tcx>(
@@ -1611,7 +1630,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
     impl_.of_trait.as_ref().map(|ast_trait_ref| {
         let selfty = tcx.type_of(def_id).instantiate_identity();
 
-        check_impl_constness(tcx, tcx.is_const_trait_impl(def_id.to_def_id()), ast_trait_ref);
+        check_impl_constness(tcx, impl_.constness, ast_trait_ref);
 
         let trait_ref = icx.lowerer().lower_impl_trait_ref(ast_trait_ref, selfty);
 
@@ -1619,22 +1638,23 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
             trait_ref: ty::EarlyBinder::bind(trait_ref),
             safety: impl_.safety,
             polarity: polarity_of_impl(tcx, def_id, impl_, item.span),
+            constness: impl_.constness,
         }
     })
 }
 
 fn check_impl_constness(
     tcx: TyCtxt<'_>,
-    is_const: bool,
+    constness: hir::Constness,
     hir_trait_ref: &hir::TraitRef<'_>,
-) -> Option<ErrorGuaranteed> {
-    if !is_const {
-        return None;
+) {
+    if let hir::Constness::NotConst = constness {
+        return;
     }
 
-    let trait_def_id = hir_trait_ref.trait_def_id()?;
+    let Some(trait_def_id) = hir_trait_ref.trait_def_id() else { return };
     if tcx.is_const_trait(trait_def_id) {
-        return None;
+        return;
     }
 
     let trait_name = tcx.item_name(trait_def_id).to_string();
@@ -1650,14 +1670,14 @@ fn check_impl_constness(
             ),
             (false, _) | (_, false) => (None, ""),
         };
-    Some(tcx.dcx().emit_err(errors::ConstImplForNonConstTrait {
+    tcx.dcx().emit_err(errors::ConstImplForNonConstTrait {
         trait_ref_span: hir_trait_ref.path.span,
         trait_name,
         local_trait_span,
         suggestion_pre,
         marking: (),
         adding: (),
-    }))
+    });
 }
 
 fn polarity_of_impl(
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 1d9114b0ef3..f52d4f42eca 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -470,6 +470,12 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
                     self.outer_index.shift_out(1);
                     res
                 }
+                hir::TyKind::UnsafeBinder(_) => {
+                    self.outer_index.shift_in(1);
+                    let res = intravisit::walk_ty(self, ty);
+                    self.outer_index.shift_out(1);
+                    res
+                }
                 _ => intravisit::walk_ty(self, ty),
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 74f381d2661..0f797bcdae4 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -781,6 +781,36 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     intravisit::walk_ty(this, ty);
                 });
             }
+            hir::TyKind::UnsafeBinder(binder) => {
+                let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
+                    binder
+                        .generic_params
+                        .iter()
+                        .enumerate()
+                        .map(|(late_bound_idx, param)| {
+                            (
+                                (param.def_id, ResolvedArg::late(late_bound_idx as u32, param)),
+                                late_arg_as_bound_arg(self.tcx, param),
+                            )
+                        })
+                        .unzip();
+
+                deny_non_region_late_bound(self.tcx, &mut bound_vars, "function pointer types");
+
+                self.record_late_bound_vars(ty.hir_id, binders);
+                let scope = Scope::Binder {
+                    hir_id: ty.hir_id,
+                    bound_vars,
+                    s: self.scope,
+                    scope_type: BinderScopeType::Normal,
+                    where_bound_origin: None,
+                };
+                self.with(scope, |this| {
+                    // a bare fn has no bounds, so everything
+                    // contained within is scoped within its binder.
+                    intravisit::walk_ty(this, ty);
+                });
+            }
             hir::TyKind::TraitObject(bounds, lifetime, _) => {
                 debug!(?bounds, ?lifetime, "TraitObject");
                 let scope = Scope::TraitRefBoundary { s: self.scope };
@@ -822,6 +852,21 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 };
                 self.with(scope, |this| this.visit_ty(mt.ty));
             }
+            hir::TyKind::TraitAscription(bounds) => {
+                let scope = Scope::TraitRefBoundary { s: self.scope };
+                self.with(scope, |this| {
+                    let scope = Scope::LateBoundary {
+                        s: this.scope,
+                        what: "`impl Trait` in binding",
+                        deny_late_regions: true,
+                    };
+                    this.with(scope, |this| {
+                        for bound in bounds {
+                            this.visit_param_bound(bound);
+                        }
+                    })
+                });
+            }
             _ => intravisit::walk_ty(self, ty),
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 7f62ccc91f0..d46f60b16f5 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1655,6 +1655,24 @@ pub(crate) struct NonConstRange {
     pub span: Span,
 }
 
+#[derive(Subdiagnostic)]
+pub(crate) enum InvalidReceiverTyHint {
+    #[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
+    Weak,
+    #[note(hir_analysis_invalid_receiver_ty_help_nonnull_note)]
+    NonNull,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_invalid_receiver_ty_no_arbitrary_self_types, code = E0307)]
+#[note]
+#[help(hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types)]
+pub(crate) struct InvalidReceiverTyNoArbitrarySelfTypes<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub receiver_ty: Ty<'tcx>,
+}
+
 #[derive(Diagnostic)]
 #[diag(hir_analysis_invalid_receiver_ty, code = E0307)]
 #[note]
@@ -1663,6 +1681,8 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
     #[primary_span]
     pub span: Span,
     pub receiver_ty: Ty<'tcx>,
+    #[subdiagnostic]
+    pub hint: Option<InvalidReceiverTyHint>,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index d3c86989440..71a5727ed6c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -1,9 +1,8 @@
-use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_errors::codes::*;
 use rustc_errors::struct_span_code_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::DefId;
 use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
 use rustc_middle::span_bug;
 use rustc_middle::ty::fold::BottomUpFolder;
@@ -11,7 +10,7 @@ use rustc_middle::ty::{
     self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
     TypeVisitableExt, Upcast,
 };
-use rustc_span::{ErrorGuaranteed, Span};
+use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
 use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
 use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
 use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
@@ -128,8 +127,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
-        let mut associated_types: FxIndexMap<Span, FxIndexSet<DefId>> = FxIndexMap::default();
+        let mut needed_associated_types = FxIndexSet::default();
 
+        let principal_span = regular_traits.first().map_or(DUMMY_SP, |info| info.bottom().1);
         let regular_traits_refs_spans = trait_bounds
             .into_iter()
             .filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
@@ -145,13 +145,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let bound_predicate = pred.kind();
                 match bound_predicate.skip_binder() {
                     ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
-                        let pred = bound_predicate.rebind(pred);
-                        associated_types.entry(original_span).or_default().extend(
-                            tcx.associated_items(pred.def_id())
+                        // FIXME(negative_bounds): Handle this correctly...
+                        let trait_ref =
+                            tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
+                        needed_associated_types.extend(
+                            tcx.associated_items(trait_ref.def_id())
                                 .in_definition_order()
                                 .filter(|item| item.kind == ty::AssocKind::Type)
                                 .filter(|item| !item.is_impl_trait_in_trait())
-                                .map(|item| item.def_id),
+                                // If the associated type has a `where Self: Sized` bound,
+                                // we do not need to constrain the associated type.
+                                .filter(|item| !tcx.generics_require_sized_self(item.def_id))
+                                .map(|item| (item.def_id, trait_ref)),
                         );
                     }
                     ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
@@ -201,26 +206,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
         // types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
         // corresponding `Projection` clause
-        for def_ids in associated_types.values_mut() {
-            for (projection_bound, span) in &projection_bounds {
-                let def_id = projection_bound.item_def_id();
-                def_ids.swap_remove(&def_id);
-                if tcx.generics_require_sized_self(def_id) {
-                    tcx.emit_node_span_lint(
-                        UNUSED_ASSOCIATED_TYPE_BOUNDS,
-                        hir_id,
-                        *span,
-                        crate::errors::UnusedAssociatedTypeBounds { span: *span },
-                    );
-                }
+        for (projection_bound, span) in &projection_bounds {
+            let def_id = projection_bound.item_def_id();
+            let trait_ref = tcx.anonymize_bound_vars(
+                projection_bound.map_bound(|p| p.projection_term.trait_ref(tcx)),
+            );
+            needed_associated_types.swap_remove(&(def_id, trait_ref));
+            if tcx.generics_require_sized_self(def_id) {
+                tcx.emit_node_span_lint(
+                    UNUSED_ASSOCIATED_TYPE_BOUNDS,
+                    hir_id,
+                    *span,
+                    crate::errors::UnusedAssociatedTypeBounds { span: *span },
+                );
             }
-            // If the associated type has a `where Self: Sized` bound, we do not need to constrain the associated
-            // type in the `dyn Trait`.
-            def_ids.retain(|def_id| !tcx.generics_require_sized_self(def_id));
         }
 
         if let Err(guar) = self.check_for_required_assoc_tys(
-            associated_types,
+            principal_span,
+            needed_associated_types,
             potential_assoc_types,
             hir_trait_bounds,
         ) {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 2e227ead14a..00c1f9b332b 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -9,7 +9,6 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
-use rustc_middle::query::Key;
 use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
 use rustc_middle::ty::{
     self, AdtDef, Binder, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeVisitableExt,
@@ -722,51 +721,42 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// emit a generic note suggesting using a `where` clause to constraint instead.
     pub(crate) fn check_for_required_assoc_tys(
         &self,
-        associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
+        principal_span: Span,
+        missing_assoc_types: FxIndexSet<(DefId, ty::PolyTraitRef<'tcx>)>,
         potential_assoc_types: Vec<usize>,
         trait_bounds: &[hir::PolyTraitRef<'_>],
     ) -> Result<(), ErrorGuaranteed> {
-        if associated_types.values().all(|v| v.is_empty()) {
+        if missing_assoc_types.is_empty() {
             return Ok(());
         }
 
         let tcx = self.tcx();
-        // FIXME: Marked `mut` so that we can replace the spans further below with a more
-        // appropriate one, but this should be handled earlier in the span assignment.
-        let associated_types: FxIndexMap<Span, Vec<_>> = associated_types
+        // FIXME: This logic needs some more care w.r.t handling of conflicts
+        let missing_assoc_types: Vec<_> = missing_assoc_types
             .into_iter()
-            .map(|(span, def_ids)| {
-                (span, def_ids.into_iter().map(|did| tcx.associated_item(did)).collect())
-            })
+            .map(|(def_id, trait_ref)| (tcx.associated_item(def_id), trait_ref))
             .collect();
-        let mut names: FxIndexMap<String, Vec<Symbol>> = Default::default();
+        let mut names: FxIndexMap<_, Vec<Symbol>> = Default::default();
         let mut names_len = 0;
 
         // Account for things like `dyn Foo + 'a`, like in tests `issue-22434.rs` and
         // `issue-22560.rs`.
-        let mut trait_bound_spans: Vec<Span> = vec![];
         let mut dyn_compatibility_violations = Ok(());
-        for (span, items) in &associated_types {
-            if !items.is_empty() {
-                trait_bound_spans.push(*span);
-            }
-            for assoc_item in items {
-                let trait_def_id = assoc_item.container_id(tcx);
-                names.entry(tcx.def_path_str(trait_def_id)).or_default().push(assoc_item.name);
-                names_len += 1;
-
-                let violations =
-                    dyn_compatibility_violations_for_assoc_item(tcx, trait_def_id, *assoc_item);
-                if !violations.is_empty() {
-                    dyn_compatibility_violations = Err(report_dyn_incompatibility(
-                        tcx,
-                        *span,
-                        None,
-                        trait_def_id,
-                        &violations,
-                    )
-                    .emit());
-                }
+        for (assoc_item, trait_ref) in &missing_assoc_types {
+            names.entry(trait_ref).or_default().push(assoc_item.name);
+            names_len += 1;
+
+            let violations =
+                dyn_compatibility_violations_for_assoc_item(tcx, trait_ref.def_id(), *assoc_item);
+            if !violations.is_empty() {
+                dyn_compatibility_violations = Err(report_dyn_incompatibility(
+                    tcx,
+                    principal_span,
+                    None,
+                    trait_ref.def_id(),
+                    &violations,
+                )
+                .emit());
             }
         }
 
@@ -814,6 +804,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .into_iter()
             .map(|(trait_, mut assocs)| {
                 assocs.sort();
+                let trait_ = trait_.print_trait_sugared();
                 format!("{} in `{trait_}`", match &assocs[..] {
                     [] => String::new(),
                     [only] => format!("`{only}`"),
@@ -827,10 +818,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         names.sort();
         let names = names.join(", ");
 
-        trait_bound_spans.sort();
         let mut err = struct_span_code_err!(
             self.dcx(),
-            trait_bound_spans,
+            principal_span,
             E0191,
             "the value of the associated type{} {} must be specified",
             pluralize!(names_len),
@@ -840,81 +830,83 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let mut types_count = 0;
         let mut where_constraints = vec![];
         let mut already_has_generics_args_suggestion = false;
-        for (span, assoc_items) in &associated_types {
-            let mut names: UnordMap<_, usize> = Default::default();
-            for item in assoc_items {
-                types_count += 1;
-                *names.entry(item.name).or_insert(0) += 1;
-            }
-            let mut dupes = false;
-            let mut shadows = false;
-            for item in assoc_items {
-                let prefix = if names[&item.name] > 1 {
-                    let trait_def_id = item.container_id(tcx);
-                    dupes = true;
-                    format!("{}::", tcx.def_path_str(trait_def_id))
-                } else if bound_names.get(&item.name).is_some_and(|x| x != &item) {
-                    let trait_def_id = item.container_id(tcx);
-                    shadows = true;
-                    format!("{}::", tcx.def_path_str(trait_def_id))
-                } else {
-                    String::new()
-                };
 
-                let mut is_shadowed = false;
-
-                if let Some(assoc_item) = bound_names.get(&item.name)
-                    && assoc_item != &item
-                {
-                    is_shadowed = true;
+        let mut names: UnordMap<_, usize> = Default::default();
+        for (item, _) in &missing_assoc_types {
+            types_count += 1;
+            *names.entry(item.name).or_insert(0) += 1;
+        }
+        let mut dupes = false;
+        let mut shadows = false;
+        for (item, trait_ref) in &missing_assoc_types {
+            let prefix = if names[&item.name] > 1 {
+                let trait_def_id = trait_ref.def_id();
+                dupes = true;
+                format!("{}::", tcx.def_path_str(trait_def_id))
+            } else if bound_names.get(&item.name).is_some_and(|x| *x != item) {
+                let trait_def_id = trait_ref.def_id();
+                shadows = true;
+                format!("{}::", tcx.def_path_str(trait_def_id))
+            } else {
+                String::new()
+            };
 
-                    let rename_message =
-                        if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" };
-                    err.span_label(
-                        tcx.def_span(assoc_item.def_id),
-                        format!("`{}{}` shadowed here{}", prefix, item.name, rename_message),
-                    );
-                }
+            let mut is_shadowed = false;
 
-                let rename_message = if is_shadowed { ", consider renaming it" } else { "" };
+            if let Some(assoc_item) = bound_names.get(&item.name)
+                && *assoc_item != item
+            {
+                is_shadowed = true;
 
-                if let Some(sp) = tcx.hir().span_if_local(item.def_id) {
-                    err.span_label(
-                        sp,
-                        format!("`{}{}` defined here{}", prefix, item.name, rename_message),
-                    );
-                }
+                let rename_message =
+                    if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" };
+                err.span_label(
+                    tcx.def_span(assoc_item.def_id),
+                    format!("`{}{}` shadowed here{}", prefix, item.name, rename_message),
+                );
             }
-            if potential_assoc_types.len() == assoc_items.len() {
-                // When the amount of missing associated types equals the number of
-                // extra type arguments present. A suggesting to replace the generic args with
-                // associated types is already emitted.
-                already_has_generics_args_suggestion = true;
-            } else if let (Ok(snippet), false, false) =
-                (tcx.sess.source_map().span_to_snippet(*span), dupes, shadows)
-            {
-                let types: Vec<_> =
-                    assoc_items.iter().map(|item| format!("{} = Type", item.name)).collect();
-                let code = if snippet.ends_with('>') {
-                    // The user wrote `Trait<'a>` or similar and we don't have a type we can
-                    // suggest, but at least we can clue them to the correct syntax
-                    // `Trait<'a, Item = Type>` while accounting for the `<'a>` in the
-                    // suggestion.
-                    format!("{}, {}>", &snippet[..snippet.len() - 1], types.join(", "))
-                } else if in_expr_or_pat {
-                    // The user wrote `Iterator`, so we don't have a type we can suggest, but at
-                    // least we can clue them to the correct syntax `Iterator::<Item = Type>`.
-                    format!("{}::<{}>", snippet, types.join(", "))
-                } else {
-                    // The user wrote `Iterator`, so we don't have a type we can suggest, but at
-                    // least we can clue them to the correct syntax `Iterator<Item = Type>`.
-                    format!("{}<{}>", snippet, types.join(", "))
-                };
-                suggestions.push((*span, code));
-            } else if dupes {
-                where_constraints.push(*span);
+
+            let rename_message = if is_shadowed { ", consider renaming it" } else { "" };
+
+            if let Some(sp) = tcx.hir().span_if_local(item.def_id) {
+                err.span_label(
+                    sp,
+                    format!("`{}{}` defined here{}", prefix, item.name, rename_message),
+                );
             }
         }
+        if potential_assoc_types.len() == missing_assoc_types.len() {
+            // When the amount of missing associated types equals the number of
+            // extra type arguments present. A suggesting to replace the generic args with
+            // associated types is already emitted.
+            already_has_generics_args_suggestion = true;
+        } else if let (Ok(snippet), false, false) =
+            (tcx.sess.source_map().span_to_snippet(principal_span), dupes, shadows)
+        {
+            let types: Vec<_> = missing_assoc_types
+                .iter()
+                .map(|(item, _)| format!("{} = Type", item.name))
+                .collect();
+            let code = if snippet.ends_with('>') {
+                // The user wrote `Trait<'a>` or similar and we don't have a type we can
+                // suggest, but at least we can clue them to the correct syntax
+                // `Trait<'a, Item = Type>` while accounting for the `<'a>` in the
+                // suggestion.
+                format!("{}, {}>", &snippet[..snippet.len() - 1], types.join(", "))
+            } else if in_expr_or_pat {
+                // The user wrote `Iterator`, so we don't have a type we can suggest, but at
+                // least we can clue them to the correct syntax `Iterator::<Item = Type>`.
+                format!("{}::<{}>", snippet, types.join(", "))
+            } else {
+                // The user wrote `Iterator`, so we don't have a type we can suggest, but at
+                // least we can clue them to the correct syntax `Iterator<Item = Type>`.
+                format!("{}<{}>", snippet, types.join(", "))
+            };
+            suggestions.push((principal_span, code));
+        } else if dupes {
+            where_constraints.push(principal_span);
+        }
+
         let where_msg = "consider introducing a new type parameter, adding `where` constraints \
                          using the fully-qualified path to the associated types";
         if !where_constraints.is_empty() && suggestions.is_empty() {
@@ -925,32 +917,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
         if suggestions.len() != 1 || already_has_generics_args_suggestion {
             // We don't need this label if there's an inline suggestion, show otherwise.
-            for (span, assoc_items) in &associated_types {
-                let mut names: FxIndexMap<_, usize> = FxIndexMap::default();
-                for item in assoc_items {
-                    types_count += 1;
-                    *names.entry(item.name).or_insert(0) += 1;
-                }
-                let mut label = vec![];
-                for item in assoc_items {
-                    let postfix = if names[&item.name] > 1 {
-                        let trait_def_id = item.container_id(tcx);
-                        format!(" (from trait `{}`)", tcx.def_path_str(trait_def_id))
-                    } else {
-                        String::new()
-                    };
-                    label.push(format!("`{}`{}", item.name, postfix));
-                }
-                if !label.is_empty() {
-                    err.span_label(
-                        *span,
-                        format!(
-                            "associated type{} {} must be specified",
-                            pluralize!(label.len()),
-                            label.join(", "),
-                        ),
-                    );
-                }
+            let mut names: FxIndexMap<_, usize> = FxIndexMap::default();
+            for (item, _) in &missing_assoc_types {
+                types_count += 1;
+                *names.entry(item.name).or_insert(0) += 1;
+            }
+            let mut label = vec![];
+            for (item, trait_ref) in &missing_assoc_types {
+                let postfix = if names[&item.name] > 1 {
+                    format!(" (from trait `{}`)", trait_ref.print_trait_sugared())
+                } else {
+                    String::new()
+                };
+                label.push(format!("`{}`{}", item.name, postfix));
+            }
+            if !label.is_empty() {
+                err.span_label(
+                    principal_span,
+                    format!(
+                        "associated type{} {} must be specified",
+                        pluralize!(label.len()),
+                        label.join(", "),
+                    ),
+                );
             }
         }
         suggestions.sort_by_key(|&(span, _)| span);
@@ -1007,8 +996,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     )),
                 ..
             }) = node
-            && let Some(ty_def_id) = qself_ty.ty_def_id()
-            && let [inherent_impl] = tcx.inherent_impls(ty_def_id)
+            && let Some(adt_def) = qself_ty.ty_adt_def()
+            && let [inherent_impl] = tcx.inherent_impls(adt_def.did())
             && let name = format!("{ident2}_{ident3}")
             && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
                 .associated_items(inherent_impl)
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 7683c87168b..a357ade0294 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -123,6 +123,13 @@ pub trait HirTyLowerer<'tcx> {
     /// Returns the const to use when a const is omitted.
     fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
 
+    fn register_trait_ascription_bounds(
+        &self,
+        bounds: Vec<(ty::Clause<'tcx>, Span)>,
+        hir_id: HirId,
+        span: Span,
+    );
+
     /// Probe bounds in scope where the bounded type coincides with the given type parameter.
     ///
     /// Rephrased, this returns bounds of the form `T: Trait`, where `T` is a type parameter
@@ -2312,6 +2319,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
                 )
             }
+            hir::TyKind::UnsafeBinder(_binder) => {
+                let guar = self
+                    .dcx()
+                    .struct_span_err(hir_ty.span, "unsafe binders are not yet implemented")
+                    .emit();
+                Ty::new_error(tcx, guar)
+            }
             hir::TyKind::TraitObject(bounds, lifetime, repr) => {
                 if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
                     // Don't continue with type analysis if the `dyn` keyword is missing
@@ -2368,6 +2382,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
                 self.lower_opaque_ty(opaque_ty.def_id, in_trait)
             }
+            hir::TyKind::TraitAscription(hir_bounds) => {
+                // Impl trait in bindings lower as an infer var with additional
+                // set of type bounds.
+                let self_ty = self.ty_infer(None, hir_ty.span);
+                let mut bounds = Bounds::default();
+                self.lower_bounds(
+                    self_ty,
+                    hir_bounds.iter(),
+                    &mut bounds,
+                    ty::List::empty(),
+                    PredicateFilter::All,
+                );
+                self.register_trait_ascription_bounds(
+                    bounds.clauses().collect(),
+                    hir_ty.hir_id,
+                    hir_ty.span,
+                );
+                self_ty
+            }
             // If we encounter a type relative path with RTN generics, then it must have
             // *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
             // it's certainly in an illegal position.
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 20ba9ae2632..feb483a8bbb 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -11,16 +11,18 @@ use std::vec;
 
 use rustc_abi::ExternAbi;
 use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity};
+use rustc_ast::{DUMMY_NODE_ID, DelimArgs};
 use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
 use rustc_ast_pretty::pp::{self, Breaks};
+use rustc_ast_pretty::pprust::state::MacHeader;
 use rustc_ast_pretty::pprust::{Comments, PrintState};
 use rustc_hir::{
     BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
     HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term,
 };
-use rustc_span::FileName;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{Ident, Symbol, kw};
+use rustc_span::{FileName, Span};
 use {rustc_ast as ast, rustc_hir as hir};
 
 pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String {
@@ -68,15 +70,115 @@ impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
 pub struct State<'a> {
     pub s: pp::Printer,
     comments: Option<Comments<'a>>,
-    attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute],
+    attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute],
     ann: &'a (dyn PpAnn + 'a),
 }
 
 impl<'a> State<'a> {
-    fn attrs(&self, id: HirId) -> &'a [ast::Attribute] {
+    fn attrs(&self, id: HirId) -> &'a [hir::Attribute] {
         (self.attrs)(id)
     }
 
+    fn print_inner_attributes(&mut self, attrs: &[hir::Attribute]) -> bool {
+        self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true)
+    }
+
+    fn print_outer_attributes(&mut self, attrs: &[hir::Attribute]) -> bool {
+        self.print_either_attributes(attrs, ast::AttrStyle::Outer, false, true)
+    }
+
+    fn print_either_attributes(
+        &mut self,
+        attrs: &[hir::Attribute],
+        kind: ast::AttrStyle,
+        is_inline: bool,
+        trailing_hardbreak: bool,
+    ) -> bool {
+        let mut printed = false;
+        for attr in attrs {
+            if attr.style == kind {
+                self.print_attribute_inline(attr, is_inline);
+                if is_inline {
+                    self.nbsp();
+                }
+                printed = true;
+            }
+        }
+        if printed && trailing_hardbreak && !is_inline {
+            self.hardbreak_if_not_bol();
+        }
+        printed
+    }
+
+    fn print_attribute_inline(&mut self, attr: &hir::Attribute, is_inline: bool) {
+        if !is_inline {
+            self.hardbreak_if_not_bol();
+        }
+        self.maybe_print_comment(attr.span.lo());
+        match &attr.kind {
+            hir::AttrKind::Normal(normal) => {
+                match attr.style {
+                    ast::AttrStyle::Inner => self.word("#!["),
+                    ast::AttrStyle::Outer => self.word("#["),
+                }
+                if normal.unsafety == hir::Safety::Unsafe {
+                    self.word("unsafe(");
+                }
+                self.print_attr_item(&normal, attr.span);
+                if normal.unsafety == hir::Safety::Unsafe {
+                    self.word(")");
+                }
+                self.word("]");
+            }
+            hir::AttrKind::DocComment(comment_kind, data) => {
+                self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string(
+                    *comment_kind,
+                    attr.style,
+                    *data,
+                ));
+                self.hardbreak()
+            }
+        }
+    }
+
+    fn print_attr_item(&mut self, item: &hir::AttrItem, span: Span) {
+        self.ibox(0);
+        let path = ast::Path {
+            span,
+            segments: item
+                .path
+                .segments
+                .iter()
+                .map(|i| ast::PathSegment { ident: *i, args: None, id: DUMMY_NODE_ID })
+                .collect(),
+            tokens: None,
+        };
+
+        match &item.args {
+            hir::AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self
+                .print_mac_common(
+                    Some(MacHeader::Path(&path)),
+                    false,
+                    None,
+                    *delim,
+                    tokens,
+                    true,
+                    span,
+                ),
+            hir::AttrArgs::Empty => {
+                PrintState::print_path(self, &path, false, 0);
+            }
+            hir::AttrArgs::Eq { eq_span: _, expr } => {
+                PrintState::print_path(self, &path, false, 0);
+                self.space();
+                self.word_space("=");
+                let token_str = self.meta_item_lit_to_string(expr);
+                self.word(token_str);
+            }
+        }
+        self.end();
+    }
+
     fn print_node(&mut self, node: Node<'_>) {
         match node {
             Node::Param(a) => self.print_param(a),
@@ -164,7 +266,7 @@ pub fn print_crate<'a>(
     krate: &hir::Mod<'_>,
     filename: FileName,
     input: String,
-    attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute],
+    attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute],
     ann: &'a dyn PpAnn,
 ) -> String {
     let mut s = State {
@@ -191,6 +293,10 @@ where
     printer.s.eof()
 }
 
+pub fn attribute_to_string(ann: &dyn PpAnn, attr: &hir::Attribute) -> String {
+    to_string(ann, |s| s.print_attribute_inline(attr, false))
+}
+
 pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String {
     to_string(ann, |s| s.print_type(ty))
 }
@@ -242,7 +348,7 @@ impl<'a> State<'a> {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span);
     }
 
-    fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[ast::Attribute]) {
+    fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[hir::Attribute]) {
         self.print_inner_attributes(attrs);
         for &item_id in _mod.item_ids {
             self.ann.nested(self, Nested::Item(item_id));
@@ -288,7 +394,13 @@ impl<'a> State<'a> {
             hir::TyKind::BareFn(f) => {
                 self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_names);
             }
+            hir::TyKind::UnsafeBinder(unsafe_binder) => {
+                self.print_unsafe_binder(unsafe_binder);
+            }
             hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
+            hir::TyKind::TraitAscription(bounds) => {
+                self.print_bounds("impl", bounds);
+            }
             hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
             hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
                 if syntax == ast::TraitObjectSyntax::Dyn {
@@ -339,6 +451,15 @@ impl<'a> State<'a> {
         self.end()
     }
 
+    fn print_unsafe_binder(&mut self, unsafe_binder: &hir::UnsafeBinderTy<'_>) {
+        self.ibox(INDENT_UNIT);
+        self.word("unsafe");
+        self.print_generic_params(unsafe_binder.generic_params);
+        self.nbsp();
+        self.print_type(unsafe_binder.inner_ty);
+        self.end();
+    }
+
     fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(item.span.lo());
@@ -911,14 +1032,14 @@ impl<'a> State<'a> {
         self.print_block_maybe_unclosed(blk, &[], false)
     }
 
-    fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[ast::Attribute]) {
+    fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[hir::Attribute]) {
         self.print_block_maybe_unclosed(blk, attrs, true)
     }
 
     fn print_block_maybe_unclosed(
         &mut self,
         blk: &hir::Block<'_>,
-        attrs: &[ast::Attribute],
+        attrs: &[hir::Attribute],
         close_box: bool,
     ) {
         match blk.rules {
@@ -1530,6 +1651,19 @@ impl<'a> State<'a> {
 
                 self.word(")");
             }
+            hir::ExprKind::UnsafeBinderCast(kind, expr, ty) => {
+                match kind {
+                    hir::UnsafeBinderCastKind::Wrap => self.word("wrap_binder!("),
+                    hir::UnsafeBinderCastKind::Unwrap => self.word("unwrap_binder!("),
+                }
+                self.print_expr(expr);
+                if let Some(ty) = ty {
+                    self.word(",");
+                    self.space();
+                    self.print_type(ty);
+                }
+                self.word(")");
+            }
             hir::ExprKind::Yield(expr, _) => {
                 self.word_space("yield");
                 self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Jump);
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index bf41dcbe4a3..7d7c9331edf 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -863,7 +863,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             let outer_universe = self.infcx.universe();
 
             let result = if let ty::FnPtr(_, hdr_b) = b.kind()
-                && let (hir::Safety::Safe, hir::Safety::Unsafe) = (fn_ty_a.safety(), hdr_b.safety)
+                && fn_ty_a.safety().is_safe()
+                && hdr_b.safety.is_unsafe()
             {
                 let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
                 self.unify_and(unsafe_a, b, to_unsafe)
@@ -925,7 +926,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
                     // Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
 
-                    if b_hdr.safety == hir::Safety::Safe
+                    if b_hdr.safety.is_safe()
                         && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                     {
                         return Err(TypeError::TargetFeatureCast(def_id));
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..66978399efb 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -72,12 +72,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if self.try_structurally_resolve_type(expr.span, ty).is_never()
             && self.expr_guaranteed_to_constitute_read_for_never(expr)
         {
-            if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
+            if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
                 let reported = self.dcx().span_delayed_bug(
                     expr.span,
                     "expression with never type wound up being adjusted",
                 );
-                return Ty::new_error(self.tcx(), reported);
+
+                return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] {
+                    target.to_owned()
+                } else {
+                    Ty::new_error(self.tcx(), reported)
+                };
             }
 
             let adj_ty = self.next_ty_var(expr.span);
@@ -329,6 +334,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // Assignment does call `drop_in_place`, though, but its safety
                     // requirements are not the same.
                     ExprKind::AddrOf(..) | hir::ExprKind::Field(..) => false,
+
+                    // Place-preserving expressions only constitute reads if their
+                    // parent expression constitutes a read.
+                    ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) => {
+                        self.expr_guaranteed_to_constitute_read_for_never(expr)
+                    }
+
                     ExprKind::Assign(lhs, _, _) => {
                         // Only the LHS does not constitute a read
                         expr.hir_id != lhs.hir_id
@@ -353,7 +365,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     | ExprKind::Binary(_, _, _)
                     | ExprKind::Unary(_, _)
                     | ExprKind::Cast(_, _)
-                    | ExprKind::Type(_, _)
                     | ExprKind::DropTemps(_)
                     | ExprKind::If(_, _, _)
                     | ExprKind::Closure(_)
@@ -564,7 +575,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_expr_index(base, idx, expr, brackets_span)
             }
             ExprKind::Yield(value, _) => self.check_expr_yield(value, expr),
-            hir::ExprKind::Err(guar) => Ty::new_error(tcx, guar),
+            ExprKind::UnsafeBinderCast(kind, expr, ty) => {
+                self.check_expr_unsafe_binder_cast(kind, expr, ty, expected)
+            }
+            ExprKind::Err(guar) => Ty::new_error(tcx, guar),
         }
     }
 
@@ -1634,6 +1648,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    fn check_expr_unsafe_binder_cast(
+        &self,
+        _kind: hir::UnsafeBinderCastKind,
+        expr: &'tcx hir::Expr<'tcx>,
+        _hir_ty: Option<&'tcx hir::Ty<'tcx>>,
+        _expected: Expectation<'tcx>,
+    ) -> Ty<'tcx> {
+        let guar =
+            self.dcx().struct_span_err(expr.span, "unsafe binders are not yet implemented").emit();
+        Ty::new_error(self.tcx, guar)
+    }
+
     fn check_expr_array(
         &self,
         args: &'tcx [hir::Expr<'tcx>],
@@ -3076,7 +3102,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/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 27ec2e9e0d4..ecbae6ac72f 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -341,6 +341,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 self.walk_expr(subexpr)?;
             }
 
+            hir::ExprKind::UnsafeBinderCast(_, subexpr, _) => {
+                self.walk_expr(subexpr)?;
+            }
+
             hir::ExprKind::Unary(hir::UnOp::Deref, base) => {
                 // *base
                 self.walk_expr(base)?;
@@ -1360,7 +1364,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 self.cat_res(expr.hir_id, expr.span, expr_ty, res)
             }
 
+            // both type ascription and unsafe binder casts don't affect
+            // the place-ness of the subexpression.
             hir::ExprKind::Type(e, _) => self.cat_expr(e),
+            hir::ExprKind::UnsafeBinderCast(_, e, _) => self.cat_expr(e),
 
             hir::ExprKind::AddrOf(..)
             | hir::ExprKind::Call(..)
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index ddd146fe785..c128485d93e 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)
@@ -765,7 +762,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
                     if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id)
                         && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity()
                         && let sig = method_ty.fn_sig(self.fcx.tcx)
-                        && let hir::Safety::Unsafe = sig.safety()
+                        && sig.safety().is_unsafe()
                     {
                         let mut collector = InferVarCollector {
                             value: (ex.hir_id, ex.span, UnsafeUseReason::Method),
@@ -785,7 +782,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
 
                     if func_ty.is_fn()
                         && let sig = func_ty.fn_sig(self.fcx.tcx)
-                        && let hir::Safety::Unsafe = sig.safety()
+                        && sig.safety().is_unsafe()
                     {
                         let mut collector = InferVarCollector {
                             value: (ex.hir_id, ex.span, UnsafeUseReason::Call),
@@ -816,7 +813,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
                     // `is_fn` excludes closures, but those can't be unsafe.
                     if ty.is_fn()
                         && let sig = ty.fn_sig(self.fcx.tcx)
-                        && let hir::Safety::Unsafe = sig.safety()
+                        && sig.safety().is_unsafe()
                     {
                         let mut collector = InferVarCollector {
                             value: (ex.hir_id, ex.span, UnsafeUseReason::Path),
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 863be3bdcb2..0dacfc9b7bf 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -4,11 +4,11 @@ use std::slice;
 use rustc_abi::FieldIdx;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey};
-use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
+use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{ExprKind, GenericArg, HirId, Node, QPath};
+use rustc_hir::{self as hir, ExprKind, GenericArg, HirId, Node, QPath, intravisit};
 use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend;
 use rustc_hir_analysis::hir_ty_lowering::generics::{
     check_generic_arg_count_for_call, lower_generic_args,
@@ -25,7 +25,7 @@ use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{
     self, AdtKind, CanonicalUserType, GenericArgKind, GenericArgsRef, GenericParamDefKind,
-    IsIdentity, Ty, TyCtxt, UserArgs, UserSelfTy, UserType,
+    IsIdentity, Ty, TyCtxt, UserArgs, UserSelfTy,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
@@ -216,11 +216,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         debug!("fcx {}", self.tag());
 
         if Self::can_contain_user_lifetime_bounds((args, user_self_ty)) {
-            let canonicalized =
-                self.canonicalize_user_type_annotation(UserType::TypeOf(def_id, UserArgs {
-                    args,
-                    user_self_ty,
-                }));
+            let canonicalized = self.canonicalize_user_type_annotation(ty::UserType::new(
+                ty::UserTypeKind::TypeOf(def_id, UserArgs { args, user_self_ty }),
+            ));
             debug!(?canonicalized);
             self.write_user_type_annotation(hir_id, canonicalized);
         }
@@ -462,13 +460,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         LoweredTy::from_raw(self, hir_ty.span, ty)
     }
 
+    /// Walk a `hir_ty` and collect any clauses that may have come from a type
+    /// within the `hir_ty`. These clauses will be canonicalized with a user type
+    /// annotation so that we can enforce these bounds in borrowck, too.
+    pub(crate) fn collect_impl_trait_clauses_from_hir_ty(
+        &self,
+        hir_ty: &'tcx hir::Ty<'tcx>,
+    ) -> ty::Clauses<'tcx> {
+        struct CollectClauses<'a, 'tcx> {
+            clauses: Vec<ty::Clause<'tcx>>,
+            fcx: &'a FnCtxt<'a, 'tcx>,
+        }
+
+        impl<'tcx> intravisit::Visitor<'tcx> for CollectClauses<'_, 'tcx> {
+            fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
+                if let Some(clauses) = self.fcx.trait_ascriptions.borrow().get(&ty.hir_id.local_id)
+                {
+                    self.clauses.extend(clauses.iter().cloned());
+                }
+                intravisit::walk_ty(self, ty)
+            }
+        }
+
+        let mut clauses = CollectClauses { clauses: vec![], fcx: self };
+        clauses.visit_ty(hir_ty);
+        self.tcx.mk_clauses(&clauses.clauses)
+    }
+
     #[instrument(level = "debug", skip_all)]
-    pub(crate) fn lower_ty_saving_user_provided_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
+    pub(crate) fn lower_ty_saving_user_provided_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> Ty<'tcx> {
         let ty = self.lower_ty(hir_ty);
         debug!(?ty);
 
         if Self::can_contain_user_lifetime_bounds(ty.raw) {
-            let c_ty = self.canonicalize_response(UserType::Ty(ty.raw));
+            let c_ty = self.canonicalize_response(ty::UserType::new(ty::UserTypeKind::Ty(ty.raw)));
             debug!(?c_ty);
             self.typeck_results.borrow_mut().user_provided_types_mut().insert(hir_ty.hir_id, c_ty);
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index aacdcf027b6..b9011e89f04 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -10,10 +10,11 @@ use std::ops::Deref;
 
 use hir::def_id::CRATE_DEF_ID;
 use rustc_errors::DiagCtxtHandle;
-use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::{self as hir, HirId, ItemLocalMap};
 use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
 use rustc_infer::infer;
+use rustc_infer::traits::Obligation;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
@@ -114,6 +115,12 @@ pub(crate) struct FnCtxt<'a, 'tcx> {
 
     pub(super) diverging_fallback_behavior: DivergingFallbackBehavior,
     pub(super) diverging_block_behavior: DivergingBlockBehavior,
+
+    /// Clauses that we lowered as part of the `impl_trait_in_bindings` feature.
+    ///
+    /// These are stored here so we may collect them when canonicalizing user
+    /// type ascriptions later.
+    pub(super) trait_ascriptions: RefCell<ItemLocalMap<Vec<ty::Clause<'tcx>>>>,
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -141,6 +148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             fallback_has_occurred: Cell::new(false),
             diverging_fallback_behavior,
             diverging_block_behavior,
+            trait_ascriptions: Default::default(),
         }
     }
 
@@ -252,6 +260,30 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
         }
     }
 
+    fn register_trait_ascription_bounds(
+        &self,
+        bounds: Vec<(ty::Clause<'tcx>, Span)>,
+        hir_id: HirId,
+        _span: Span,
+    ) {
+        for (clause, span) in bounds {
+            if clause.has_escaping_bound_vars() {
+                self.dcx().span_delayed_bug(span, "clause should have no escaping bound vars");
+                continue;
+            }
+
+            self.trait_ascriptions.borrow_mut().entry(hir_id.local_id).or_default().push(clause);
+
+            let clause = self.normalize(span, clause);
+            self.register_predicate(Obligation::new(
+                self.tcx,
+                self.misc(span),
+                self.param_env,
+                clause,
+            ));
+        }
+    }
+
     fn probe_ty_param_bounds(
         &self,
         _: Span,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index ddcd90a2a9d..21b1768ae6f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -10,7 +10,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{
     Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId,
-    Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicateKind,
+    Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicateKind, expr_needs_parens,
 };
 use rustc_hir_analysis::collect::suggest_impl_trait;
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
@@ -35,7 +35,6 @@ use tracing::{debug, instrument};
 
 use super::FnCtxt;
 use crate::fn_ctxt::rustc_span::BytePos;
-use crate::hir::is_range_literal;
 use crate::method::probe;
 use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
 use crate::{errors, fluent_generated as fluent};
@@ -2648,7 +2647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
 
                     let make_sugg = |expr: &Expr<'_>, span: Span, sugg: &str| {
-                        if self.needs_parentheses(expr) {
+                        if expr_needs_parens(expr) {
                             (
                                 vec![
                                     (span.shrink_to_lo(), format!("{prefix}{sugg}(")),
@@ -2861,7 +2860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             return None;
                         }
 
-                        if self.needs_parentheses(expr) {
+                        if expr_needs_parens(expr) {
                             return Some((
                                 vec![
                                     (span, format!("{suggestion}(")),
@@ -2902,16 +2901,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         false
     }
 
-    fn needs_parentheses(&self, expr: &hir::Expr<'_>) -> bool {
-        match expr.kind {
-            // parenthesize if needed (Issue #46756)
-            hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
-            // parenthesize borrows of range literals (Issue #54505)
-            _ if is_range_literal(expr) => true,
-            _ => false,
-        }
-    }
-
     pub(crate) fn suggest_cast(
         &self,
         err: &mut Diag<'_>,
diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs
index f427b0b805e..48fd5f1f982 100644
--- a/compiler/rustc_hir_typeck/src/gather_locals.rs
+++ b/compiler/rustc_hir_typeck/src/gather_locals.rs
@@ -2,7 +2,7 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{HirId, PatKind};
 use rustc_infer::traits::ObligationCauseCode;
-use rustc_middle::ty::{Ty, UserType};
+use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use tracing::debug;
@@ -92,7 +92,12 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
             Some(ref ty) => {
                 let o_ty = self.fcx.lower_ty(ty);
 
-                let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw));
+                let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(
+                    ty::UserType::new_with_bounds(
+                        ty::UserTypeKind::Ty(o_ty.raw),
+                        self.fcx.collect_impl_trait_clauses_from_hir_ty(ty),
+                    ),
+                );
                 debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
                 self.fcx
                     .typeck_results
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index b31ee1a55d6..ef431c852e9 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -17,7 +17,6 @@ use rustc_middle::ty::adjustment::{
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{
     self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, UserArgs,
-    UserType,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::{DUMMY_SP, Span};
@@ -491,9 +490,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                     user_self_ty: None, // not relevant here
                 };
 
-                self.fcx.canonicalize_user_type_annotation(UserType::TypeOf(
-                    pick.item.def_id,
-                    user_args,
+                self.fcx.canonicalize_user_type_annotation(ty::UserType::new(
+                    ty::UserTypeKind::TypeOf(pick.item.def_id, user_args),
                 ))
             });
 
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/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 2a8ed26aa2b..e7726845652 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -10,8 +10,12 @@ use rustc_errors::{
 };
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
-use rustc_hir::{self as hir, BindingMode, ByRef, HirId, LangItem, Mutability, Pat, PatKind};
+use rustc_hir::{
+    self as hir, BindingMode, ByRef, ExprKind, HirId, LangItem, Mutability, Pat, PatKind,
+    expr_needs_parens,
+};
 use rustc_infer::infer;
+use rustc_middle::traits::PatternOriginExpr;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
@@ -94,10 +98,32 @@ struct PatInfo<'a, 'tcx> {
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
+        // If origin_expr exists, then expected represents the type of origin_expr.
+        // If span also exists, then span == origin_expr.span (although it doesn't need to exist).
+        // In that case, we can peel away references from both and treat them
+        // as the same.
+        let origin_expr_info = ti.origin_expr.map(|mut cur_expr| {
+            let mut count = 0;
+
+            // cur_ty may have more layers of references than cur_expr.
+            // We can only make suggestions about cur_expr, however, so we'll
+            // use that as our condition for stopping.
+            while let ExprKind::AddrOf(.., inner) = &cur_expr.kind {
+                cur_expr = inner;
+                count += 1;
+            }
+
+            PatternOriginExpr {
+                peeled_span: cur_expr.span,
+                peeled_count: count,
+                peeled_prefix_suggestion_parentheses: expr_needs_parens(cur_expr),
+            }
+        });
+
         let code = ObligationCauseCode::Pattern {
             span: ti.span,
             root_ty: ti.expected,
-            origin_expr: ti.origin_expr.is_some(),
+            origin_expr: origin_expr_info,
         };
         self.cause(cause_span, code)
     }
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_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index e17a68c8692..6f1e3a0cf8c 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -476,7 +476,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
             for (local_id, c_ty) in sorted_user_provided_types {
                 let hir_id = HirId { owner: common_hir_owner, local_id };
 
-                if let ty::UserType::TypeOf(_, user_args) = c_ty.value {
+                if let ty::UserTypeKind::TypeOf(_, user_args) = c_ty.value.kind {
                     // This is a unit-testing mechanism.
                     let span = self.tcx().hir().span(hir_id);
                     // We need to buffer the errors in order to guarantee a consistent
diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs
index 1f46155abc8..031c50c45d4 100644
--- a/compiler/rustc_incremental/src/assert_dep_graph.rs
+++ b/compiler/rustc_incremental/src/assert_dep_graph.rs
@@ -50,7 +50,7 @@ use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 use rustc_span::symbol::{Symbol, sym};
 use tracing::debug;
-use {rustc_ast as ast, rustc_graphviz as dot, rustc_hir as hir};
+use {rustc_graphviz as dot, rustc_hir as hir};
 
 use crate::errors;
 
@@ -106,7 +106,7 @@ struct IfThisChanged<'tcx> {
 }
 
 impl<'tcx> IfThisChanged<'tcx> {
-    fn argument(&self, attr: &ast::Attribute) -> Option<Symbol> {
+    fn argument(&self, attr: &hir::Attribute) -> Option<Symbol> {
         let mut value = None;
         for list_item in attr.meta_item_list().unwrap_or_default() {
             match list_item.ident() {
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 2075d4214c1..a85686e590b 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -19,11 +19,13 @@
 //! Errors are reported if we are in the suitable configuration but
 //! the required condition is not met.
 
-use rustc_ast::{self as ast, Attribute, MetaItemInner};
+use rustc_ast::{self as ast, MetaItemInner};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::unord::UnordSet;
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::{ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit};
+use rustc_hir::{
+    Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit,
+};
 use rustc_middle::dep_graph::{DepNode, DepNodeExt, label_strs};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 07ae24ee6d3..91f190c6a28 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -371,7 +371,6 @@ pub(crate) fn initialize_checked_jobserver(early_dcx: &EarlyDiagCtxt) {
 
 // JUSTIFICATION: before session exists, only config
 #[allow(rustc::bad_opt_access)]
-#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
 pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
     trace!("run_compiler");
 
@@ -425,7 +424,11 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
                 config.opts.unstable_opts.translate_directionality_markers,
             ) {
                 Ok(bundle) => bundle,
-                Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")),
+                Err(e) => {
+                    // We can't translate anything if we failed to load translations
+                    #[allow(rustc::untranslatable_diagnostic)]
+                    early_dcx.early_fatal(format!("failed to load fluent bundle: {e}"))
+                }
             };
 
             let mut locale_resources = config.locale_resources;
@@ -479,7 +482,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
             let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
             if let Some(register_lints) = config.register_lints.as_deref() {
                 register_lints(&sess, &mut lint_store);
-                sess.registered_lints = true;
             }
             sess.lint_store = Some(Lrc::new(lint_store));
 
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 62f35333015..f8351a81bec 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -76,6 +76,7 @@ fn pre_expansion_lint<'a>(
         || {
             rustc_lint::check_ast_node(
                 sess,
+                None,
                 features,
                 true,
                 lint_store,
@@ -310,6 +311,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
     let lint_store = unerased_lint_store(tcx.sess);
     rustc_lint::check_ast_node(
         sess,
+        Some(tcx),
         tcx.features(),
         false,
         lint_store,
@@ -1125,6 +1127,18 @@ pub(crate) fn start_codegen<'tcx>(
         }
     }
 
+    // This must run after monomorphization so that all generic types
+    // have been instantiated.
+    if tcx.sess.opts.unstable_opts.print_type_sizes {
+        tcx.sess.code_stats.print_type_sizes();
+    }
+
+    if tcx.sess.opts.unstable_opts.print_vtable_sizes {
+        let crate_name = tcx.crate_name(LOCAL_CRATE);
+
+        tcx.sess.code_stats.print_vtable_sizes(crate_name);
+    }
+
     codegen
 }
 
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 7e3a1332630..bb2ad3b3dd0 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -127,18 +127,6 @@ impl Linker {
     ) -> Linker {
         let ongoing_codegen = passes::start_codegen(codegen_backend, tcx);
 
-        // This must run after monomorphization so that all generic types
-        // have been instantiated.
-        if tcx.sess.opts.unstable_opts.print_type_sizes {
-            tcx.sess.code_stats.print_type_sizes();
-        }
-
-        if tcx.sess.opts.unstable_opts.print_vtable_sizes {
-            let crate_name = tcx.crate_name(LOCAL_CRATE);
-
-            tcx.sess.code_stats.print_vtable_sizes(crate_name);
-        }
-
         Linker {
             dep_graph: tcx.dep_graph.clone(),
             output_filenames: Arc::clone(tcx.output_filenames(())),
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index d3213b1263c..2af25bfd3aa 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -35,10 +35,10 @@ pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
 pub fn add_configuration(cfg: &mut Cfg, sess: &mut Session, codegen_backend: &dyn CodegenBackend) {
     let tf = sym::target_feature;
 
-    let unstable_target_features = codegen_backend.target_features(sess, true);
+    let unstable_target_features = codegen_backend.target_features_cfg(sess, true);
     sess.unstable_target_features.extend(unstable_target_features.iter().cloned());
 
-    let target_features = codegen_backend.target_features(sess, false);
+    let target_features = codegen_backend.target_features_cfg(sess, false);
     sess.target_features.extend(target_features.iter().cloned());
 
     cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat))));
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 49e6b763590..2ecd5051f9e 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -806,10 +806,14 @@ lint_unexpected_cfg_add_build_rs_println = or consider adding `{$build_rs_printl
 lint_unexpected_cfg_add_cargo_feature = consider using a Cargo feature instead
 lint_unexpected_cfg_add_cargo_toml_lint_cfg = or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:{$cargo_toml_lint_cfg}
 lint_unexpected_cfg_add_cmdline_arg = to expect this configuration use `{$cmdline_arg}`
+lint_unexpected_cfg_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}`
+
 lint_unexpected_cfg_define_features = consider defining some features in `Cargo.toml`
 lint_unexpected_cfg_doc_cargo = see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
 lint_unexpected_cfg_doc_rustc = see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
+lint_unexpected_cfg_from_external_macro_origin = using a cfg inside a {$macro_kind} will use the cfgs from the destination crate and not the ones from the defining crate
+lint_unexpected_cfg_from_external_macro_refer = try referring to `{$macro_name}` crate for guidance on how handle this unexpected cfg
 lint_unexpected_cfg_name = unexpected `cfg` condition name: `{$name}`
 lint_unexpected_cfg_name_expected_names = expected names are: {$possibilities}{$and_more ->
         [0] {""}
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/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 093cc16fb4c..2d3ecb6943c 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -387,7 +387,7 @@ pub struct MissingDoc;
 
 impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
 
-fn has_doc(attr: &ast::Attribute) -> bool {
+fn has_doc(attr: &hir::Attribute) -> bool {
     if attr.is_doc_comment() {
         return true;
     }
@@ -1012,7 +1012,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN
 impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
         let attrs = cx.tcx.hir().attrs(it.hir_id());
-        let check_no_mangle_on_generic_fn = |no_mangle_attr: &ast::Attribute,
+        let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute,
                                              impl_generics: Option<&hir::Generics<'_>>,
                                              generics: &hir::Generics<'_>,
                                              span| {
@@ -1176,7 +1176,7 @@ declare_lint_pass!(
 );
 
 impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
-    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
+    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) {
         if attr.has_name(sym::feature)
             && let Some(items) = attr.meta_item_list()
         {
@@ -3038,7 +3038,7 @@ impl EarlyLintPass for SpecialModuleName {
         for item in &krate.items {
             if let ast::ItemKind::Mod(
                 _,
-                ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _),
+                ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _, _),
             ) = item.kind
             {
                 if item.attrs.iter().any(|a| a.has_name(sym::path)) {
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 44c7888a530..d8d901698d6 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -20,7 +20,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
 use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
 use rustc_session::lint::{
-    BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
+    FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
 };
 use rustc_session::{LintStoreMarker, Session};
 use rustc_span::Span;
@@ -33,8 +33,6 @@ use self::TargetLint::*;
 use crate::levels::LintLevelsBuilder;
 use crate::passes::{EarlyLintPassObject, LateLintPassObject};
 
-mod diagnostics;
-
 type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::DynSend + sync::DynSync;
 type LateLintPassFactory =
     dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::DynSend + sync::DynSync;
@@ -511,38 +509,6 @@ pub struct EarlyContext<'a> {
     pub buffered: LintBuffer,
 }
 
-impl EarlyContext<'_> {
-    /// Emit a lint at the appropriate level, with an associated span and an existing
-    /// diagnostic.
-    ///
-    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
-    #[rustc_lint_diagnostics]
-    pub fn span_lint_with_diagnostics(
-        &self,
-        lint: &'static Lint,
-        span: MultiSpan,
-        diagnostic: BuiltinLintDiag,
-    ) {
-        self.opt_span_lint_with_diagnostics(lint, Some(span), diagnostic);
-    }
-
-    /// Emit a lint at the appropriate level, with an optional associated span and an existing
-    /// diagnostic.
-    ///
-    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
-    #[rustc_lint_diagnostics]
-    pub fn opt_span_lint_with_diagnostics(
-        &self,
-        lint: &'static Lint,
-        span: Option<MultiSpan>,
-        diagnostic: BuiltinLintDiag,
-    ) {
-        self.opt_span_lint(lint, span, |diag| {
-            diagnostics::decorate_lint(self.sess(), diagnostic, diag);
-        });
-    }
-}
-
 pub trait LintContext {
     fn sess(&self) -> &Session;
 
diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs
index 7e298a9a63c..10769b57a76 100644
--- a/compiler/rustc_lint/src/dangling.rs
+++ b/compiler/rustc_lint/src/dangling.rs
@@ -192,6 +192,8 @@ fn is_temporary_rvalue(expr: &Expr<'_>) -> bool {
         | ExprKind::DropTemps(..)
         | ExprKind::Let(..) => false,
 
+        ExprKind::UnsafeBinderCast(..) => false,
+
         // Not applicable
         ExprKind::Type(..) | ExprKind::Err(..) => false,
     }
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index a68a2a7f983..a15aab32aee 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -9,35 +9,40 @@ use rustc_ast::visit::{self as ast_visit, Visitor, walk_list};
 use rustc_ast::{self as ast, HasAttrs};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_feature::Features;
-use rustc_middle::ty::RegisteredTools;
+use rustc_middle::ty::{RegisteredTools, TyCtxt};
 use rustc_session::Session;
 use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
 use rustc_span::Span;
 use rustc_span::symbol::Ident;
 use tracing::debug;
 
-use crate::context::{EarlyContext, LintStore};
+use crate::context::{EarlyContext, LintContext, LintStore};
 use crate::passes::{EarlyLintPass, EarlyLintPassObject};
 
+mod diagnostics;
+
 macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
     $cx.pass.$f(&$cx.context, $($args),*);
 }) }
 
 /// Implements the AST traversal for early lint passes. `T` provides the
 /// `check_*` methods.
-pub struct EarlyContextAndPass<'a, T: EarlyLintPass> {
-    context: EarlyContext<'a>,
+pub struct EarlyContextAndPass<'ecx, 'tcx, T: EarlyLintPass> {
+    context: EarlyContext<'ecx>,
+    tcx: Option<TyCtxt<'tcx>>,
     pass: T,
 }
 
-impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
+impl<'ecx, 'tcx, T: EarlyLintPass> EarlyContextAndPass<'ecx, 'tcx, T> {
     // This always-inlined function is for the hot call site.
     #[inline(always)]
     #[allow(rustc::diagnostic_outside_of_impl)]
     fn inlined_check_id(&mut self, id: ast::NodeId) {
         for early_lint in self.context.buffered.take(id) {
             let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint;
-            self.context.opt_span_lint_with_diagnostics(lint_id.lint, span, diagnostic);
+            self.context.opt_span_lint(lint_id.lint, span, |diag| {
+                diagnostics::decorate_lint(self.context.sess(), self.tcx, diagnostic, diag);
+            });
         }
     }
 
@@ -49,7 +54,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
     /// Merge the lints specified by any lint attributes into the
     /// current lint context, call the provided function, then reset the
     /// lints in effect to their previous state.
-    fn with_lint_attrs<F>(&mut self, id: ast::NodeId, attrs: &'a [ast::Attribute], f: F)
+    fn with_lint_attrs<F>(&mut self, id: ast::NodeId, attrs: &'_ [ast::Attribute], f: F)
     where
         F: FnOnce(&mut Self),
     {
@@ -67,19 +72,21 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
     }
 }
 
-impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
-    fn visit_coroutine_kind(&mut self, coroutine_kind: &'a ast::CoroutineKind) -> Self::Result {
+impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
+    for EarlyContextAndPass<'ecx, 'tcx, T>
+{
+    fn visit_coroutine_kind(&mut self, coroutine_kind: &'ast ast::CoroutineKind) -> Self::Result {
         self.check_id(coroutine_kind.closure_id());
     }
 
-    fn visit_param(&mut self, param: &'a ast::Param) {
+    fn visit_param(&mut self, param: &'ast ast::Param) {
         self.with_lint_attrs(param.id, &param.attrs, |cx| {
             lint_callback!(cx, check_param, param);
             ast_visit::walk_param(cx, param);
         });
     }
 
-    fn visit_item(&mut self, it: &'a ast::Item) {
+    fn visit_item(&mut self, it: &'ast ast::Item) {
         self.with_lint_attrs(it.id, &it.attrs, |cx| {
             lint_callback!(cx, check_item, it);
             ast_visit::walk_item(cx, it);
@@ -87,31 +94,31 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         })
     }
 
-    fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) {
+    fn visit_foreign_item(&mut self, it: &'ast ast::ForeignItem) {
         self.with_lint_attrs(it.id, &it.attrs, |cx| {
             ast_visit::walk_item(cx, it);
         })
     }
 
-    fn visit_pat(&mut self, p: &'a ast::Pat) {
+    fn visit_pat(&mut self, p: &'ast ast::Pat) {
         lint_callback!(self, check_pat, p);
         self.check_id(p.id);
         ast_visit::walk_pat(self, p);
         lint_callback!(self, check_pat_post, p);
     }
 
-    fn visit_pat_field(&mut self, field: &'a ast::PatField) {
+    fn visit_pat_field(&mut self, field: &'ast ast::PatField) {
         self.with_lint_attrs(field.id, &field.attrs, |cx| {
             ast_visit::walk_pat_field(cx, field);
         });
     }
 
-    fn visit_anon_const(&mut self, c: &'a ast::AnonConst) {
+    fn visit_anon_const(&mut self, c: &'ast ast::AnonConst) {
         self.check_id(c.id);
         ast_visit::walk_anon_const(self, c);
     }
 
-    fn visit_expr(&mut self, e: &'a ast::Expr) {
+    fn visit_expr(&mut self, e: &'ast ast::Expr) {
         self.with_lint_attrs(e.id, &e.attrs, |cx| {
             lint_callback!(cx, check_expr, e);
             ast_visit::walk_expr(cx, e);
@@ -119,13 +126,13 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         })
     }
 
-    fn visit_expr_field(&mut self, f: &'a ast::ExprField) {
+    fn visit_expr_field(&mut self, f: &'ast ast::ExprField) {
         self.with_lint_attrs(f.id, &f.attrs, |cx| {
             ast_visit::walk_expr_field(cx, f);
         })
     }
 
-    fn visit_stmt(&mut self, s: &'a ast::Stmt) {
+    fn visit_stmt(&mut self, s: &'ast ast::Stmt) {
         // Add the statement's lint attributes to our
         // current state when checking the statement itself.
         // This allows us to handle attributes like
@@ -145,33 +152,33 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         ast_visit::walk_stmt(self, s);
     }
 
-    fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, span: Span, id: ast::NodeId) {
+    fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, span: Span, id: ast::NodeId) {
         lint_callback!(self, check_fn, fk, span, id);
         self.check_id(id);
         ast_visit::walk_fn(self, fk);
     }
 
-    fn visit_variant_data(&mut self, s: &'a ast::VariantData) {
+    fn visit_variant_data(&mut self, s: &'ast ast::VariantData) {
         if let Some(ctor_node_id) = s.ctor_node_id() {
             self.check_id(ctor_node_id);
         }
         ast_visit::walk_struct_def(self, s);
     }
 
-    fn visit_field_def(&mut self, s: &'a ast::FieldDef) {
+    fn visit_field_def(&mut self, s: &'ast ast::FieldDef) {
         self.with_lint_attrs(s.id, &s.attrs, |cx| {
             ast_visit::walk_field_def(cx, s);
         })
     }
 
-    fn visit_variant(&mut self, v: &'a ast::Variant) {
+    fn visit_variant(&mut self, v: &'ast ast::Variant) {
         self.with_lint_attrs(v.id, &v.attrs, |cx| {
             lint_callback!(cx, check_variant, v);
             ast_visit::walk_variant(cx, v);
         })
     }
 
-    fn visit_ty(&mut self, t: &'a ast::Ty) {
+    fn visit_ty(&mut self, t: &'ast ast::Ty) {
         lint_callback!(self, check_ty, t);
         self.check_id(t.id);
         ast_visit::walk_ty(self, t);
@@ -181,55 +188,55 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         lint_callback!(self, check_ident, ident);
     }
 
-    fn visit_local(&mut self, l: &'a ast::Local) {
+    fn visit_local(&mut self, l: &'ast ast::Local) {
         self.with_lint_attrs(l.id, &l.attrs, |cx| {
             lint_callback!(cx, check_local, l);
             ast_visit::walk_local(cx, l);
         })
     }
 
-    fn visit_block(&mut self, b: &'a ast::Block) {
+    fn visit_block(&mut self, b: &'ast ast::Block) {
         lint_callback!(self, check_block, b);
         self.check_id(b.id);
         ast_visit::walk_block(self, b);
     }
 
-    fn visit_arm(&mut self, a: &'a ast::Arm) {
+    fn visit_arm(&mut self, a: &'ast ast::Arm) {
         self.with_lint_attrs(a.id, &a.attrs, |cx| {
             lint_callback!(cx, check_arm, a);
             ast_visit::walk_arm(cx, a);
         })
     }
 
-    fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {
+    fn visit_generic_arg(&mut self, arg: &'ast ast::GenericArg) {
         lint_callback!(self, check_generic_arg, arg);
         ast_visit::walk_generic_arg(self, arg);
     }
 
-    fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
+    fn visit_generic_param(&mut self, param: &'ast ast::GenericParam) {
         self.with_lint_attrs(param.id, &param.attrs, |cx| {
             lint_callback!(cx, check_generic_param, param);
             ast_visit::walk_generic_param(cx, param);
         });
     }
 
-    fn visit_generics(&mut self, g: &'a ast::Generics) {
+    fn visit_generics(&mut self, g: &'ast ast::Generics) {
         lint_callback!(self, check_generics, g);
         ast_visit::walk_generics(self, g);
     }
 
-    fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
+    fn visit_where_predicate(&mut self, p: &'ast ast::WherePredicate) {
         lint_callback!(self, enter_where_predicate, p);
         ast_visit::walk_where_predicate(self, p);
         lint_callback!(self, exit_where_predicate, p);
     }
 
-    fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) {
+    fn visit_poly_trait_ref(&mut self, t: &'ast ast::PolyTraitRef) {
         lint_callback!(self, check_poly_trait_ref, t);
         ast_visit::walk_poly_trait_ref(self, t);
     }
 
-    fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
+    fn visit_assoc_item(&mut self, item: &'ast ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
         self.with_lint_attrs(item.id, &item.attrs, |cx| {
             match ctxt {
                 ast_visit::AssocCtxt::Trait => {
@@ -243,32 +250,32 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         });
     }
 
-    fn visit_lifetime(&mut self, lt: &'a ast::Lifetime, _: ast_visit::LifetimeCtxt) {
+    fn visit_lifetime(&mut self, lt: &'ast ast::Lifetime, _: ast_visit::LifetimeCtxt) {
         self.check_id(lt.id);
         ast_visit::walk_lifetime(self, lt);
     }
 
-    fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) {
+    fn visit_path(&mut self, p: &'ast ast::Path, id: ast::NodeId) {
         self.check_id(id);
         ast_visit::walk_path(self, p);
     }
 
-    fn visit_path_segment(&mut self, s: &'a ast::PathSegment) {
+    fn visit_path_segment(&mut self, s: &'ast ast::PathSegment) {
         self.check_id(s.id);
         ast_visit::walk_path_segment(self, s);
     }
 
-    fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
+    fn visit_attribute(&mut self, attr: &'ast ast::Attribute) {
         lint_callback!(self, check_attribute, attr);
         ast_visit::walk_attribute(self, attr);
     }
 
-    fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) {
+    fn visit_mac_def(&mut self, mac: &'ast ast::MacroDef, id: ast::NodeId) {
         lint_callback!(self, check_mac_def, mac);
         self.check_id(id);
     }
 
-    fn visit_mac_call(&mut self, mac: &'a ast::MacCall) {
+    fn visit_mac_call(&mut self, mac: &'ast ast::MacCall) {
         lint_callback!(self, check_mac, mac);
         ast_visit::walk_mac(self, mac);
     }
@@ -310,28 +317,18 @@ crate::early_lint_methods!(impl_early_lint_pass, []);
 /// This trait generalizes over those nodes.
 pub trait EarlyCheckNode<'a>: Copy {
     fn id(self) -> ast::NodeId;
-    fn attrs<'b>(self) -> &'b [ast::Attribute]
-    where
-        'a: 'b;
-    fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
-    where
-        'a: 'b;
+    fn attrs(self) -> &'a [ast::Attribute];
+    fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx, 'tcx, T>);
 }
 
 impl<'a> EarlyCheckNode<'a> for (&'a ast::Crate, &'a [ast::Attribute]) {
     fn id(self) -> ast::NodeId {
         ast::CRATE_NODE_ID
     }
-    fn attrs<'b>(self) -> &'b [ast::Attribute]
-    where
-        'a: 'b,
-    {
+    fn attrs(self) -> &'a [ast::Attribute] {
         self.1
     }
-    fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
-    where
-        'a: 'b,
-    {
+    fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx, 'tcx, T>) {
         lint_callback!(cx, check_crate, self.0);
         ast_visit::walk_crate(cx, self.0);
         lint_callback!(cx, check_crate_post, self.0);
@@ -342,16 +339,10 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
     fn id(self) -> ast::NodeId {
         self.0
     }
-    fn attrs<'b>(self) -> &'b [ast::Attribute]
-    where
-        'a: 'b,
-    {
+    fn attrs(self) -> &'a [ast::Attribute] {
         self.1
     }
-    fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
-    where
-        'a: 'b,
-    {
+    fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx, 'tcx, T>) {
         walk_list!(cx, visit_attribute, self.1);
         walk_list!(cx, visit_item, self.2);
     }
@@ -359,6 +350,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
 
 pub fn check_ast_node<'a>(
     sess: &Session,
+    tcx: Option<TyCtxt<'_>>,
     features: &Features,
     pre_expansion: bool,
     lint_store: &LintStore,
@@ -382,22 +374,23 @@ pub fn check_ast_node<'a>(
     let passes =
         if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes };
     if passes.is_empty() {
-        check_ast_node_inner(sess, check_node, context, builtin_lints);
+        check_ast_node_inner(sess, tcx, check_node, context, builtin_lints);
     } else {
         let mut passes: Vec<_> = passes.iter().map(|mk_pass| (mk_pass)()).collect();
         passes.push(Box::new(builtin_lints));
         let pass = RuntimeCombinedEarlyLintPass { passes: &mut passes[..] };
-        check_ast_node_inner(sess, check_node, context, pass);
+        check_ast_node_inner(sess, tcx, check_node, context, pass);
     }
 }
 
 fn check_ast_node_inner<'a, T: EarlyLintPass>(
     sess: &Session,
+    tcx: Option<TyCtxt<'_>>,
     check_node: impl EarlyCheckNode<'a>,
     context: EarlyContext<'_>,
     pass: T,
 ) {
-    let mut cx = EarlyContextAndPass { context, pass };
+    let mut cx = EarlyContextAndPass { context, tcx, pass };
 
     cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));
 
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs
index a3731e31c2b..b0fb1e4af76 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/early/diagnostics.rs
@@ -8,6 +8,7 @@ use rustc_errors::{
     Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion,
 };
 use rustc_middle::middle::stability;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
 use rustc_span::BytePos;
@@ -18,7 +19,12 @@ use crate::lints::{self, ElidedNamedLifetime};
 
 mod check_cfg;
 
-pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) {
+pub(super) fn decorate_lint(
+    sess: &Session,
+    tcx: Option<TyCtxt<'_>>,
+    diagnostic: BuiltinLintDiag,
+    diag: &mut Diag<'_, ()>,
+) {
     match diagnostic {
         BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => {
             let spans: Vec<_> = content
@@ -199,10 +205,10 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
             .decorate_lint(diag);
         }
         BuiltinLintDiag::UnexpectedCfgName(name, value) => {
-            check_cfg::unexpected_cfg_name(sess, name, value).decorate_lint(diag);
+            check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag);
         }
         BuiltinLintDiag::UnexpectedCfgValue(name, value) => {
-            check_cfg::unexpected_cfg_value(sess, name, value).decorate_lint(diag);
+            check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag);
         }
         BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => {
             let suggestion = match sugg {
diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
index 16994846545..033c0fa4c88 100644
--- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
+++ b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
@@ -1,9 +1,11 @@
+use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::bug;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_session::config::ExpectedValues;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::symbol::Ident;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{ExpnKind, Span, Symbol, sym};
 
 use crate::lints;
 
@@ -60,8 +62,41 @@ fn cargo_help_sub(
     }
 }
 
+fn rustc_macro_help(span: Span) -> Option<lints::UnexpectedCfgRustcMacroHelp> {
+    let oexpn = span.ctxt().outer_expn_data();
+    if let Some(def_id) = oexpn.macro_def_id
+        && let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
+        && def_id.krate != LOCAL_CRATE
+    {
+        Some(lints::UnexpectedCfgRustcMacroHelp { macro_kind: macro_kind.descr(), macro_name })
+    } else {
+        None
+    }
+}
+
+fn cargo_macro_help(
+    tcx: Option<TyCtxt<'_>>,
+    span: Span,
+) -> Option<lints::UnexpectedCfgCargoMacroHelp> {
+    let oexpn = span.ctxt().outer_expn_data();
+    if let Some(def_id) = oexpn.macro_def_id
+        && let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
+        && def_id.krate != LOCAL_CRATE
+        && let Some(tcx) = tcx
+    {
+        Some(lints::UnexpectedCfgCargoMacroHelp {
+            macro_kind: macro_kind.descr(),
+            macro_name,
+            crate_name: tcx.crate_name(def_id.krate),
+        })
+    } else {
+        None
+    }
+}
+
 pub(super) fn unexpected_cfg_name(
     sess: &Session,
+    tcx: Option<TyCtxt<'_>>,
     (name, name_span): (Symbol, Span),
     value: Option<(Symbol, Span)>,
 ) -> lints::UnexpectedCfgName {
@@ -85,6 +120,7 @@ pub(super) fn unexpected_cfg_name(
     };
 
     let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
+    let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
     let mut is_feature_cfg = name == sym::feature;
 
     let code_sugg = if is_feature_cfg && is_from_cargo {
@@ -185,12 +221,21 @@ pub(super) fn unexpected_cfg_name(
     };
 
     let invocation_help = if is_from_cargo {
-        let sub = if !is_feature_cfg { Some(cargo_help_sub(sess, &inst)) } else { None };
-        lints::unexpected_cfg_name::InvocationHelp::Cargo { sub }
+        let help = if !is_feature_cfg && !is_from_external_macro {
+            Some(cargo_help_sub(sess, &inst))
+        } else {
+            None
+        };
+        lints::unexpected_cfg_name::InvocationHelp::Cargo {
+            help,
+            macro_help: cargo_macro_help(tcx, name_span),
+        }
     } else {
-        lints::unexpected_cfg_name::InvocationHelp::Rustc(lints::UnexpectedCfgRustcHelp::new(
-            &inst(EscapeQuotes::No),
-        ))
+        let help = lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No));
+        lints::unexpected_cfg_name::InvocationHelp::Rustc {
+            help,
+            macro_help: rustc_macro_help(name_span),
+        }
     };
 
     lints::UnexpectedCfgName { code_sugg, invocation_help, name }
@@ -198,6 +243,7 @@ pub(super) fn unexpected_cfg_name(
 
 pub(super) fn unexpected_cfg_value(
     sess: &Session,
+    tcx: Option<TyCtxt<'_>>,
     (name, name_span): (Symbol, Span),
     value: Option<(Symbol, Span)>,
 ) -> lints::UnexpectedCfgValue {
@@ -216,7 +262,9 @@ pub(super) fn unexpected_cfg_value(
         .copied()
         .flatten()
         .collect();
+
     let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
+    let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
 
     // Show the full list if all possible values for a given name, but don't do it
     // for names as the possibilities could be very long
@@ -284,25 +332,31 @@ pub(super) fn unexpected_cfg_value(
     };
 
     let invocation_help = if is_from_cargo {
-        let help = if name == sym::feature {
+        let help = if name == sym::feature && !is_from_external_macro {
             if let Some((value, _value_span)) = value {
                 Some(lints::unexpected_cfg_value::CargoHelp::AddFeature { value })
             } else {
                 Some(lints::unexpected_cfg_value::CargoHelp::DefineFeatures)
             }
-        } else if can_suggest_adding_value {
+        } else if can_suggest_adding_value && !is_from_external_macro {
             Some(lints::unexpected_cfg_value::CargoHelp::Other(cargo_help_sub(sess, &inst)))
         } else {
             None
         };
-        lints::unexpected_cfg_value::InvocationHelp::Cargo(help)
+        lints::unexpected_cfg_value::InvocationHelp::Cargo {
+            help,
+            macro_help: cargo_macro_help(tcx, name_span),
+        }
     } else {
         let help = if can_suggest_adding_value {
             Some(lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No)))
         } else {
             None
         };
-        lints::unexpected_cfg_value::InvocationHelp::Rustc(help)
+        lints::unexpected_cfg_value::InvocationHelp::Rustc {
+            help,
+            macro_help: rustc_macro_help(name_span),
+        }
     };
 
     lints::UnexpectedCfgValue {
diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs
index 2db229ed133..1402129195f 100644
--- a/compiler/rustc_lint/src/if_let_rescope.rs
+++ b/compiler/rustc_lint/src/if_let_rescope.rs
@@ -422,6 +422,7 @@ impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> {
             hir::ExprKind::Unary(_, expr)
             | hir::ExprKind::Cast(expr, _)
             | hir::ExprKind::Type(expr, _)
+            | hir::ExprKind::UnsafeBinderCast(_, expr, _)
             | hir::ExprKind::Yield(expr, _)
             | hir::ExprKind::AddrOf(_, _, expr)
             | hir::ExprKind::Match(expr, _, _)
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 4b1dafbdbee..7ea6c63dbe6 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -1,4 +1,5 @@
 use rustc_ast_pretty::pprust;
+use rustc_attr::AttributeExt;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::{Diag, LintDiagnostic, MultiSpan};
 use rustc_feature::{Features, GateIssue};
@@ -371,7 +372,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> {
 
     /// FIXME(blyxyas): In a future revision, we should also graph #![allow]s,
     /// but that is handled with more care
-    fn visit_attribute(&mut self, attribute: &'tcx ast::Attribute) {
+    fn visit_attribute(&mut self, attribute: &'tcx hir::Attribute) {
         if matches!(
             Level::from_attr(attribute),
             Some(
@@ -383,10 +384,9 @@ impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> {
             )
         ) {
             let store = unerased_lint_store(self.tcx.sess);
-            let Some(meta) = attribute.meta() else { return };
             // Lint attributes are always a metalist inside a
             // metalist (even with just one lint).
-            let Some(meta_item_list) = meta.meta_item_list() else { return };
+            let Some(meta_item_list) = attribute.meta_item_list() else { return };
 
             for meta_list in meta_item_list {
                 // Convert Path to String
@@ -686,7 +686,12 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         };
     }
 
-    fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id: Option<HirId>) {
+    fn add(
+        &mut self,
+        attrs: &[impl AttributeExt],
+        is_crate_node: bool,
+        source_hir_id: Option<HirId>,
+    ) {
         let sess = self.sess;
         for (attr_index, attr) in attrs.iter().enumerate() {
             if attr.has_name(sym::automatically_derived) {
@@ -910,7 +915,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
 
                 let src = LintLevelSource::Node { name, span: sp, reason };
                 for &id in ids {
-                    if self.check_gated_lint(id, attr.span, false) {
+                    if self.check_gated_lint(id, attr.span(), false) {
                         self.insert_spec(id, (level, src));
                     }
                 }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 20822f23bf1..df89fe6f701 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1816,14 +1816,14 @@ pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
 }
 
 #[derive(LintDiagnostic)]
-pub(crate) enum UnpredictableFunctionPointerComparisons<'a> {
+pub(crate) enum UnpredictableFunctionPointerComparisons<'a, 'tcx> {
     #[diag(lint_unpredictable_fn_pointer_comparisons)]
     #[note(lint_note_duplicated_fn)]
     #[note(lint_note_deduplicated_fn)]
     #[note(lint_note_visit_fn_addr_eq)]
     Suggestion {
         #[subdiagnostic]
-        sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a>,
+        sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx>,
     },
     #[diag(lint_unpredictable_fn_pointer_comparisons)]
     #[note(lint_note_duplicated_fn)]
@@ -1833,22 +1833,40 @@ pub(crate) enum UnpredictableFunctionPointerComparisons<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(
-    lint_fn_addr_eq_suggestion,
-    style = "verbose",
-    applicability = "maybe-incorrect"
-)]
-pub(crate) struct UnpredictableFunctionPointerComparisonsSuggestion<'a> {
-    pub ne: &'a str,
-    pub cast_right: String,
-    pub deref_left: &'a str,
-    pub deref_right: &'a str,
-    #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
-    pub left: Span,
-    #[suggestion_part(code = ", {deref_right}")]
-    pub middle: Span,
-    #[suggestion_part(code = "{cast_right})")]
-    pub right: Span,
+pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
+    #[multipart_suggestion(
+        lint_fn_addr_eq_suggestion,
+        style = "verbose",
+        applicability = "maybe-incorrect"
+    )]
+    FnAddrEq {
+        ne: &'a str,
+        deref_left: &'a str,
+        deref_right: &'a str,
+        #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
+        left: Span,
+        #[suggestion_part(code = ", {deref_right}")]
+        middle: Span,
+        #[suggestion_part(code = ")")]
+        right: Span,
+    },
+    #[multipart_suggestion(
+        lint_fn_addr_eq_suggestion,
+        style = "verbose",
+        applicability = "maybe-incorrect"
+    )]
+    FnAddrEqWithCast {
+        ne: &'a str,
+        deref_left: &'a str,
+        deref_right: &'a str,
+        fn_sig: rustc_middle::ty::PolyFnSig<'tcx>,
+        #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
+        left: Span,
+        #[suggestion_part(code = ", {deref_right}")]
+        middle: Span,
+        #[suggestion_part(code = " as {fn_sig})")]
+        right: Span,
+    },
 }
 
 pub(crate) struct ImproperCTypes<'a> {
@@ -2172,6 +2190,24 @@ impl UnexpectedCfgRustcHelp {
     }
 }
 
+#[derive(Subdiagnostic)]
+#[note(lint_unexpected_cfg_from_external_macro_origin)]
+#[help(lint_unexpected_cfg_from_external_macro_refer)]
+pub(crate) struct UnexpectedCfgRustcMacroHelp {
+    pub macro_kind: &'static str,
+    pub macro_name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
+#[note(lint_unexpected_cfg_from_external_macro_origin)]
+#[help(lint_unexpected_cfg_from_external_macro_refer)]
+#[help(lint_unexpected_cfg_cargo_update)]
+pub(crate) struct UnexpectedCfgCargoMacroHelp {
+    pub macro_kind: &'static str,
+    pub macro_name: Symbol,
+    pub crate_name: Symbol,
+}
+
 #[derive(LintDiagnostic)]
 #[diag(lint_unexpected_cfg_name)]
 pub(crate) struct UnexpectedCfgName {
@@ -2276,10 +2312,17 @@ pub(crate) mod unexpected_cfg_name {
         #[note(lint_unexpected_cfg_doc_cargo)]
         Cargo {
             #[subdiagnostic]
-            sub: Option<super::UnexpectedCfgCargoHelp>,
+            macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
+            #[subdiagnostic]
+            help: Option<super::UnexpectedCfgCargoHelp>,
         },
         #[note(lint_unexpected_cfg_doc_rustc)]
-        Rustc(#[subdiagnostic] super::UnexpectedCfgRustcHelp),
+        Rustc {
+            #[subdiagnostic]
+            macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
+            #[subdiagnostic]
+            help: super::UnexpectedCfgRustcHelp,
+        },
     }
 }
 
@@ -2382,9 +2425,19 @@ pub(crate) mod unexpected_cfg_value {
     #[derive(Subdiagnostic)]
     pub(crate) enum InvocationHelp {
         #[note(lint_unexpected_cfg_doc_cargo)]
-        Cargo(#[subdiagnostic] Option<CargoHelp>),
+        Cargo {
+            #[subdiagnostic]
+            help: Option<CargoHelp>,
+            #[subdiagnostic]
+            macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
+        },
         #[note(lint_unexpected_cfg_doc_rustc)]
-        Rustc(#[subdiagnostic] Option<super::UnexpectedCfgRustcHelp>),
+        Rustc {
+            #[subdiagnostic]
+            help: Option<super::UnexpectedCfgRustcHelp>,
+            #[subdiagnostic]
+            macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
+        },
     }
 
     #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 4d8ebf2909e..ff464b76c0d 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -1,7 +1,7 @@
 use rustc_abi::ExternAbi;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{GenericParamKind, PatKind};
+use rustc_hir::{AttrArgs, AttrItem, AttrKind, GenericParamKind, PatKind};
 use rustc_middle::ty;
 use rustc_session::config::CrateType;
 use rustc_session::{declare_lint, declare_lint_pass};
@@ -342,36 +342,37 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
         let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
             Some(Ident::from_str(name))
         } else {
-            attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name)
-                .and_then(|attr| attr.meta())
-                .and_then(|meta| {
-                    meta.name_value_literal().and_then(|lit| {
-                        if let ast::LitKind::Str(name, ..) = lit.kind {
-                            // Discard the double quotes surrounding the literal.
-                            let sp = cx
-                                .sess()
-                                .source_map()
-                                .span_to_snippet(lit.span)
-                                .ok()
-                                .and_then(|snippet| {
-                                    let left = snippet.find('"')?;
-                                    let right =
-                                        snippet.rfind('"').map(|pos| snippet.len() - pos)?;
-
-                                    Some(
-                                        lit.span
-                                            .with_lo(lit.span.lo() + BytePos(left as u32 + 1))
-                                            .with_hi(lit.span.hi() - BytePos(right as u32)),
-                                    )
-                                })
-                                .unwrap_or(lit.span);
-
-                            Some(Ident::new(name, sp))
-                        } else {
-                            None
-                        }
-                    })
-                })
+            attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then(
+                |attr| {
+                    if let AttrKind::Normal(n) = &attr.kind
+                        && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: ref lit }, .. } =
+                            n.as_ref()
+                        && let ast::LitKind::Str(name, ..) = lit.kind
+                    {
+                        // Discard the double quotes surrounding the literal.
+                        let sp = cx
+                            .sess()
+                            .source_map()
+                            .span_to_snippet(lit.span)
+                            .ok()
+                            .and_then(|snippet| {
+                                let left = snippet.find('"')?;
+                                let right = snippet.rfind('"').map(|pos| snippet.len() - pos)?;
+
+                                Some(
+                                    lit.span
+                                        .with_lo(lit.span.lo() + BytePos(left as u32 + 1))
+                                        .with_hi(lit.span.hi() - BytePos(right as u32)),
+                                )
+                            })
+                            .unwrap_or(lit.span);
+
+                        Some(Ident::new(name, sp))
+                    } else {
+                        None
+                    }
+                },
+            )
         };
 
         if let Some(ident) = &crate_ident {
diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs
index 9d84d36e779..380cbe650f0 100644
--- a/compiler/rustc_lint/src/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
@@ -42,9 +42,9 @@ macro_rules! late_lint_methods {
             fn check_field_def(a: &'tcx rustc_hir::FieldDef<'tcx>);
             fn check_variant(a: &'tcx rustc_hir::Variant<'tcx>);
             fn check_path(a: &rustc_hir::Path<'tcx>, b: rustc_hir::HirId);
-            fn check_attribute(a: &'tcx rustc_ast::Attribute);
-            fn check_attributes(a: &'tcx [rustc_ast::Attribute]);
-            fn check_attributes_post(a: &'tcx [rustc_ast::Attribute]);
+            fn check_attribute(a: &'tcx rustc_hir::Attribute);
+            fn check_attributes(a: &'tcx [rustc_hir::Attribute]);
+            fn check_attributes_post(a: &'tcx [rustc_hir::Attribute]);
         ]);
     )
 }
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_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 33650be056d..33d31d27c73 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -483,29 +483,36 @@ fn lint_fn_pointer<'tcx>(
     let middle = l_span.shrink_to_hi().until(r_span.shrink_to_lo());
     let right = r_span.shrink_to_hi().until(e.span.shrink_to_hi());
 
-    // We only check for a right cast as `FnDef` == `FnPtr` is not possible,
-    // only `FnPtr == FnDef` is possible.
-    let cast_right = if !r_ty.is_fn_ptr() {
-        let fn_sig = r_ty.fn_sig(cx.tcx);
-        format!(" as {fn_sig}")
-    } else {
-        String::new()
-    };
+    let sugg =
+        // We only check for a right cast as `FnDef` == `FnPtr` is not possible,
+        // only `FnPtr == FnDef` is possible.
+        if !r_ty.is_fn_ptr() {
+            let fn_sig = r_ty.fn_sig(cx.tcx);
 
-    cx.emit_span_lint(
-        UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
-        e.span,
-        UnpredictableFunctionPointerComparisons::Suggestion {
-            sugg: UnpredictableFunctionPointerComparisonsSuggestion {
+            UnpredictableFunctionPointerComparisonsSuggestion::FnAddrEqWithCast {
                 ne,
+                fn_sig,
                 deref_left,
                 deref_right,
                 left,
                 middle,
                 right,
-                cast_right,
-            },
-        },
+            }
+        } else {
+            UnpredictableFunctionPointerComparisonsSuggestion::FnAddrEq {
+                ne,
+                deref_left,
+                deref_right,
+                left,
+                middle,
+                right,
+            }
+        };
+
+    cx.emit_span_lint(
+        UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
+        e.span,
+        UnpredictableFunctionPointerComparisons::Suggestion { sugg },
     );
 }
 
diff --git a/compiler/rustc_lint/src/unqualified_local_imports.rs b/compiler/rustc_lint/src/unqualified_local_imports.rs
index bea01a33bd6..d4b39d91a71 100644
--- a/compiler/rustc_lint/src/unqualified_local_imports.rs
+++ b/compiler/rustc_lint/src/unqualified_local_imports.rs
@@ -31,7 +31,7 @@ declare_lint! {
     ///
     /// This lint is meant to be used with the (unstable) rustfmt setting `group_imports = "StdExternalCrate"`.
     /// That setting makes rustfmt group `self::`, `super::`, and `crate::` imports separately from those
-    /// refering to other crates. However, rustfmt cannot know whether `use c::S;` refers to a local module `c`
+    /// referring to other crates. However, rustfmt cannot know whether `use c::S;` refers to a local module `c`
     /// or an external crate `c`, so it always gets categorized as an import from another crate.
     /// To ensure consistent grouping of imports from the local crate, all local imports must
     /// start with `self::`, `super::`, or `crate::`. This lint can be used to enforce that style.
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index eb761bd6475..7edb1d2ffe8 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -3,8 +3,9 @@
 // tidy-alphabetical-end
 
 use rustc_abi::ExternAbi;
+use rustc_ast::AttrId;
+use rustc_ast::attr::AttributeExt;
 use rustc_ast::node_id::NodeId;
-use rustc_ast::{AttrId, Attribute};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::stable_hasher::{
     HashStable, StableCompare, StableHasher, ToStableHashKey,
@@ -221,8 +222,8 @@ impl Level {
     }
 
     /// Converts an `Attribute` to a level.
-    pub fn from_attr(attr: &Attribute) -> Option<Self> {
-        Self::from_symbol(attr.name_or_empty(), Some(attr.id))
+    pub fn from_attr(attr: &impl AttributeExt) -> Option<Self> {
+        Self::from_symbol(attr.name_or_empty(), Some(attr.id()))
     }
 
     /// Converts a `Symbol` to a level.
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 06550728f0f..b79205ff946 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1535,7 +1535,7 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
 
 extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(LLVMDiagnosticInfoRef DI,
-                                                       unsigned *Cookie) {
+                                                       uint64_t *Cookie) {
   llvm::DiagnosticInfoSrcMgr *SM =
       static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
   *Cookie = SM->getLocCookie();
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 29dba2bca61..fd1535094c9 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -17,6 +17,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard};
 use rustc_errors::DiagCtxtHandle;
 use rustc_expand::base::SyntaxExtension;
 use rustc_fs_util::try_canonicalize;
+use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE, LocalDefId, StableCrateId};
 use rustc_hir::definitions::Definitions;
 use rustc_index::IndexVec;
@@ -97,7 +98,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
 }
 
 pub enum LoadedMacro {
-    MacroDef { def: MacroDef, ident: Ident, attrs: AttrVec, span: Span, edition: Edition },
+    MacroDef {
+        def: MacroDef,
+        ident: Ident,
+        attrs: Vec<hir::Attribute>,
+        span: Span,
+        edition: Edition,
+    },
     ProcMacro(SyntaxExtension),
 }
 
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index 641d1d8e798..e8de0acb7c9 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -77,7 +77,7 @@ pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
             verify_ok(tcx, &linkage);
             (ty, linkage)
         })
-        .collect::<Vec<_>>()
+        .collect()
 }
 
 fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index b9586338655..6eae4f9a8d6 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1369,7 +1369,7 @@ impl<'a> CrateMetadataRef<'a> {
         self,
         id: DefIndex,
         sess: &'a Session,
-    ) -> impl Iterator<Item = ast::Attribute> + 'a {
+    ) -> impl Iterator<Item = hir::Attribute> + 'a {
         self.root
             .tables
             .attributes
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index f01ad31d0bb..3077312ccf9 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -344,7 +344,7 @@ provide! { tcx, def_id, other, cdata,
     }
     associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
     inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
-    item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
+    attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
     is_mir_available => { cdata.is_item_mir_available(def_id.index) }
     is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
     cross_crate_inlinable => { table_direct }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 5c80d24f502..92c0e8c3a50 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -4,7 +4,7 @@ use std::fs::File;
 use std::io::{Read, Seek, Write};
 use std::path::{Path, PathBuf};
 
-use rustc_ast::Attribute;
+use rustc_ast::attr::AttributeExt;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::memmap::{Mmap, MmapMut};
 use rustc_data_structures::sync::{Lrc, join, par_for_each_in};
@@ -814,7 +814,7 @@ struct AnalyzeAttrState<'a> {
 /// visibility: this is a piece of data that can be computed once per defid, and not once per
 /// attribute. Some attributes would only be usable downstream if they are public.
 #[inline]
-fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState<'_>) -> bool {
+fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> bool {
     let mut should_encode = false;
     if !rustc_feature::encode_cross_crate(attr.name_or_empty()) {
         // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates.
@@ -1264,12 +1264,7 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool {
 
 fn should_encode_constness(def_kind: DefKind) -> bool {
     match def_kind {
-        DefKind::Fn
-        | DefKind::AssocFn
-        | DefKind::Closure
-        | DefKind::Impl { of_trait: true }
-        | DefKind::Variant
-        | DefKind::Ctor(..) => true,
+        DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Ctor(_, CtorKind::Fn) => true,
 
         DefKind::Struct
         | DefKind::Union
@@ -1281,7 +1276,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
         | DefKind::Static { .. }
         | DefKind::TyAlias
         | DefKind::OpaqueTy
-        | DefKind::Impl { of_trait: false }
+        | DefKind::Impl { .. }
         | DefKind::ForeignTy
         | DefKind::ConstParam
         | DefKind::InlineConst
@@ -1296,6 +1291,8 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
         | DefKind::ExternCrate
+        | DefKind::Ctor(_, CtorKind::Const)
+        | DefKind::Variant
         | DefKind::SyntheticCoroutineBody => false,
     }
 }
@@ -1357,7 +1354,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             .hir()
             .attrs(tcx.local_def_id_to_hir_id(def_id))
             .iter()
-            .filter(|attr| analyze_attr(attr, &mut state));
+            .filter(|attr| analyze_attr(*attr, &mut state));
 
         record_array!(self.tables.attributes[def_id.to_def_id()] <- attr_iter);
 
@@ -2164,10 +2161,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_dylib_dependency_formats(&mut self) -> LazyArray<Option<LinkagePreference>> {
         empty_proc_macro!(self);
         let formats = self.tcx.dependency_formats(());
-        for (ty, arr) in formats.iter() {
-            if *ty != CrateType::Dylib {
-                continue;
-            }
+        if let Some(arr) = formats.get(&CrateType::Dylib) {
             return self.lazy_array(arr.iter().map(|slot| match *slot {
                 Linkage::NotLinked | Linkage::IncludedFromDylib => None,
 
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 4961464833a..fa843a10adf 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -403,7 +403,7 @@ define_tables! {
     cross_crate_inlinable: Table<DefIndex, bool>,
 
 - optional:
-    attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
+    attributes: Table<DefIndex, LazyArray<hir::Attribute>>,
     // For non-reexported names in a module every name is associated with a separate `DefId`,
     // so we can take their names, visibilities etc from other encoded tables.
     module_children_non_reexports: Table<DefIndex, LazyArray<DefIndex>>,
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index b664230d10b..52233d407f2 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -85,7 +85,7 @@ macro_rules! arena_types {
             [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
             [] dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation,
             [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>,
-            [decode] attribute: rustc_ast::Attribute,
+            [decode] attribute: rustc_hir::Attribute,
             [] name_set: rustc_data_structures::unord::UnordSet<rustc_span::symbol::Symbol>,
             [] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::symbol::Symbol>,
             [] pats: rustc_middle::ty::PatternKind<'tcx>,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 0c701c834f2..fc3cbfd7b3e 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -9,11 +9,11 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::*;
+use rustc_hir_pretty as pprust_hir;
 use rustc_middle::hir::nested_filter;
 use rustc_span::def_id::StableCrateId;
 use rustc_span::symbol::{Ident, Symbol, kw, sym};
 use rustc_span::{ErrorGuaranteed, Span};
-use {rustc_ast as ast, rustc_hir_pretty as pprust_hir};
 
 use crate::hir::ModuleItems;
 use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
@@ -381,7 +381,7 @@ impl<'hir> Map<'hir> {
     /// Gets the attributes on the crate. This is preferable to
     /// invoking `krate.attrs` because it registers a tighter
     /// dep-graph access.
-    pub fn krate_attrs(self) -> &'hir [ast::Attribute] {
+    pub fn krate_attrs(self) -> &'hir [Attribute] {
         self.attrs(CRATE_HIR_ID)
     }
 
@@ -792,7 +792,7 @@ impl<'hir> Map<'hir> {
 
     /// Given a node ID, gets a list of attributes associated with the AST
     /// corresponding to the node-ID.
-    pub fn attrs(self, id: HirId) -> &'hir [ast::Attribute] {
+    pub fn attrs(self, id: HirId) -> &'hir [Attribute] {
         self.tcx.hir_attrs(id.owner).get(id.local_id)
     }
 
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index ad0d70152e1..ffefd81cd08 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -151,7 +151,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self,
         node: OwnerNode<'_>,
         bodies: &SortedMap<ItemLocalId, &Body<'_>>,
-        attrs: &SortedMap<ItemLocalId, &[rustc_ast::Attribute]>,
+        attrs: &SortedMap<ItemLocalId, &[Attribute]>,
     ) -> (Option<Fingerprint>, Option<Fingerprint>) {
         if self.needs_crate_hash() {
             self.with_stable_hashing_context(|mut hcx| {
diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs
index a3aff9a1101..e3b40b64157 100644
--- a/compiler/rustc_middle/src/middle/dependency_format.rs
+++ b/compiler/rustc_middle/src/middle/dependency_format.rs
@@ -7,6 +7,7 @@
 // FIXME: move this file to rustc_metadata::dependency_format, but
 // this will introduce circular dependency between rustc_metadata and rustc_middle
 
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_session::config::CrateType;
 
@@ -18,7 +19,7 @@ pub type DependencyList = Vec<Linkage>;
 /// A mapping of all required dependencies for a particular flavor of output.
 ///
 /// This is local to the tcx, and is generally relevant to one session.
-pub type Dependencies = Vec<(CrateType, DependencyList)>;
+pub type Dependencies = FxIndexMap<CrateType, DependencyList>;
 
 #[derive(Copy, Clone, PartialEq, Debug, HashStable, Encodable, Decodable)]
 pub enum Linkage {
diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs
index 270bcabcc86..3a3e84a87af 100644
--- a/compiler/rustc_middle/src/middle/limits.rs
+++ b/compiler/rustc_middle/src/middle/limits.rs
@@ -10,7 +10,7 @@
 
 use std::num::IntErrorKind;
 
-use rustc_ast::Attribute;
+use rustc_ast::attr::AttributeExt;
 use rustc_session::{Limit, Limits, Session};
 use rustc_span::symbol::{Symbol, sym};
 
@@ -35,32 +35,36 @@ pub fn provide(providers: &mut Providers) {
     }
 }
 
-pub fn get_recursion_limit(krate_attrs: &[Attribute], sess: &Session) -> Limit {
+pub fn get_recursion_limit(krate_attrs: &[impl AttributeExt], sess: &Session) -> Limit {
     get_limit(krate_attrs, sess, sym::recursion_limit, 128)
 }
 
-fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: usize) -> Limit {
+fn get_limit(
+    krate_attrs: &[impl AttributeExt],
+    sess: &Session,
+    name: Symbol,
+    default: usize,
+) -> Limit {
     match get_limit_size(krate_attrs, sess, name) {
         Some(size) => Limit::new(size),
         None => Limit::new(default),
     }
 }
 
-pub fn get_limit_size(krate_attrs: &[Attribute], sess: &Session, name: Symbol) -> Option<usize> {
+pub fn get_limit_size(
+    krate_attrs: &[impl AttributeExt],
+    sess: &Session,
+    name: Symbol,
+) -> Option<usize> {
     for attr in krate_attrs {
         if !attr.has_name(name) {
             continue;
         }
 
-        if let Some(s) = attr.value_str() {
-            match s.as_str().parse() {
+        if let Some(sym) = attr.value_str() {
+            match sym.as_str().parse() {
                 Ok(n) => return Some(n),
                 Err(e) => {
-                    let value_span = attr
-                        .meta()
-                        .and_then(|meta| meta.name_value_literal_span())
-                        .unwrap_or(attr.span);
-
                     let error_str = match e.kind() {
                         IntErrorKind::PosOverflow => "`limit` is too large",
                         IntErrorKind::Empty => "`limit` must be a non-negative integer",
@@ -71,7 +75,11 @@ pub fn get_limit_size(krate_attrs: &[Attribute], sess: &Session, name: Symbol) -
                         IntErrorKind::Zero => bug!("zero is a valid `limit`"),
                         kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),
                     };
-                    sess.dcx().emit_err(LimitInvalid { span: attr.span, value_span, error_str });
+                    sess.dcx().emit_err(LimitInvalid {
+                        span: attr.span(),
+                        value_span: attr.value_span().unwrap(),
+                        error_str,
+                    });
                 }
             }
         }
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 52009422d98..d8a39191920 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -467,6 +467,9 @@ impl<'tcx> Const<'tcx> {
                 let const_val = tcx.valtree_to_const_val((ty, valtree));
                 Self::Val(const_val, ty)
             }
+            ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
+                Self::Unevaluated(UnevaluatedConst { def, args, promoted: None }, ty)
+            }
             _ => Self::Ty(ty, c),
         }
     }
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 161716610fe..266dc7ad2b3 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -19,6 +19,7 @@ use rustc_target::spec::SymbolVisibility;
 use tracing::debug;
 
 use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
+use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::ty::{GenericArgs, Instance, InstanceKind, SymbolName, TyCtxt};
 
 /// Describes how a monomorphization will be instantiated in object files.
@@ -104,7 +105,9 @@ impl<'tcx> MonoItem<'tcx> {
                 let entry_def_id = tcx.entry_fn(()).map(|(id, _)| id);
                 // If this function isn't inlined or otherwise has an extern
                 // indicator, then we'll be creating a globally shared version.
-                if tcx.codegen_fn_attrs(instance.def_id()).contains_extern_indicator()
+                let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
+                if codegen_fn_attrs.contains_extern_indicator()
+                    || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
                     || !instance.def.generates_cgu_internal_copy(tcx)
                     || Some(instance.def_id()) == entry_def_id
                 {
@@ -291,10 +294,22 @@ pub enum Linkage {
     Common,
 }
 
+/// Specifies the symbol visibility with regards to dynamic linking.
+///
+/// Visibility doesn't have any effect when linkage is internal.
+///
+/// DSO means dynamic shared object, that is a dynamically linked executable or dylib.
 #[derive(Copy, Clone, PartialEq, Debug, HashStable)]
 pub enum Visibility {
+    /// Export the symbol from the DSO and apply overrides of the symbol by outside DSOs to within
+    /// the DSO if the object file format supports this.
     Default,
+    /// Hide the symbol outside of the defining DSO even when external linkage is used to export it
+    /// from the object file.
     Hidden,
+    /// Export the symbol from the DSO, but don't apply overrides of the symbol by outside DSOs to
+    /// within the DSO. Equivalent to default visibility with object file formats that don't support
+    /// overriding exported symbols by another DSO.
     Protected,
 }
 
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index 970dc72e1ff..66fec2dd0f7 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -41,7 +41,8 @@ pub trait Key: Sized {
         None
     }
 
-    fn ty_def_id(&self) -> Option<DefId> {
+    /// Used to detect when ADT def ids are used as keys in a cycle for better error reporting.
+    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
         None
     }
 }
@@ -423,7 +424,7 @@ impl<'tcx> Key for Ty<'tcx> {
         DUMMY_SP
     }
 
-    fn ty_def_id(&self) -> Option<DefId> {
+    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
         match *self.kind() {
             ty::Adt(adt, _) => Some(adt.did()),
             ty::Coroutine(def_id, ..) => Some(def_id),
@@ -471,8 +472,8 @@ impl<'tcx, T: Key> Key for ty::PseudoCanonicalInput<'tcx, T> {
         self.value.default_span(tcx)
     }
 
-    fn ty_def_id(&self) -> Option<DefId> {
-        self.value.ty_def_id()
+    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
+        self.value.def_id_for_ty_in_cycle()
     }
 }
 
@@ -593,7 +594,7 @@ impl<'tcx> Key for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>
         DUMMY_SP
     }
 
-    fn ty_def_id(&self) -> Option<DefId> {
+    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
         match self.1.value.kind() {
             ty::Adt(adt, _) => Some(adt.did()),
             _ => None,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index fc3d690a8a9..906a47713f4 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -746,7 +746,10 @@ rustc_queries! {
         desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) }
     }
 
-    /// Returns `true` if this is a const fn / const impl.
+    /// Returns the constness of function-like things (tuple struct/variant constructors, functions,
+    /// methods)
+    ///
+    /// Will ICE if used on things that are always const or never const.
     ///
     /// **Do not call this function manually.** It is only meant to cache the base data for the
     /// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead.
@@ -1264,7 +1267,7 @@ rustc_queries! {
     /// Returns the attributes on the item at `def_id`.
     ///
     /// Do not use this directly, use `tcx.get_attrs` instead.
-    query item_attrs(def_id: DefId) -> &'tcx [ast::Attribute] {
+    query attrs_for_def(def_id: DefId) -> &'tcx [hir::Attribute] {
         desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) }
         separate_provide_extern
     }
@@ -2230,7 +2233,7 @@ rustc_queries! {
     }
 
     /// Returns the Rust target features for the current target. These are not always the same as LLVM target features!
-    query rust_target_features(_: CrateNum) -> &'tcx UnordMap<String, rustc_target::target_features::Stability> {
+    query rust_target_features(_: CrateNum) -> &'tcx UnordMap<String, rustc_target::target_features::StabilityComputed> {
         arena_cache
         eval_always
         desc { "looking up Rust target features" }
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index 119a99e1bf7..2c22f7b8f49 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -798,7 +798,7 @@ macro_rules! impl_ref_decoder {
 
 impl_ref_decoder! {<'tcx>
     Span,
-    rustc_ast::Attribute,
+    rustc_hir::Attribute,
     rustc_span::symbol::Ident,
     ty::Variance,
     rustc_span::def_id::DefId,
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index c8675660e0f..3337f7ceee7 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -44,16 +44,16 @@ pub struct DynamicQuery<'tcx, C: QueryCache> {
     pub format_value: fn(&C::Value) -> String,
 }
 
-pub struct QuerySystemFns<'tcx> {
+pub struct QuerySystemFns {
     pub engine: QueryEngine,
     pub local_providers: Providers,
     pub extern_providers: ExternProviders,
-    pub encode_query_results: fn(
+    pub encode_query_results: for<'tcx> fn(
         tcx: TyCtxt<'tcx>,
         encoder: &mut CacheEncoder<'_, 'tcx>,
         query_result_index: &mut EncodedDepNodeIndex,
     ),
-    pub try_mark_green: fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool,
+    pub try_mark_green: for<'tcx> fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool,
 }
 
 pub struct QuerySystem<'tcx> {
@@ -68,7 +68,7 @@ pub struct QuerySystem<'tcx> {
     /// This is `None` if we are not incremental compilation mode
     pub on_disk_cache: Option<OnDiskCache>,
 
-    pub fns: QuerySystemFns<'tcx>,
+    pub fns: QuerySystemFns,
 
     pub jobs: AtomicU64,
 }
@@ -323,7 +323,7 @@ macro_rules! define_callbacks {
                 // Increase this limit if necessary, but do try to keep the size low if possible
                 #[cfg(target_pointer_width = "64")]
                 const _: () = {
-                    if mem::size_of::<Key<'static>>() > 80 {
+                    if mem::size_of::<Key<'static>>() > 88 {
                         panic!("{}", concat!(
                             "the query `",
                             stringify!($name),
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 0a77c3bc42f..8c434265d27 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -316,8 +316,8 @@ pub enum ObligationCauseCode<'tcx> {
         span: Option<Span>,
         /// The root expected type induced by a scrutinee or type expression.
         root_ty: Ty<'tcx>,
-        /// Whether the `Span` came from an expression or a type expression.
-        origin_expr: bool,
+        /// Information about the `Span`, if it came from an expression, otherwise `None`.
+        origin_expr: Option<PatternOriginExpr>,
     },
 
     /// Computing common supertype in an if expression
@@ -530,6 +530,25 @@ pub struct MatchExpressionArmCause<'tcx> {
     pub tail_defines_return_position_impl_trait: Option<LocalDefId>,
 }
 
+/// Information about the origin expression of a pattern, relevant to diagnostics.
+/// Fields here refer to the scrutinee of a pattern.
+/// If the scrutinee isn't given in the diagnostic, then this won't exist.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
+pub struct PatternOriginExpr {
+    /// A span representing the scrutinee expression, with all leading references
+    /// peeled from the expression.
+    /// Only references in the expression are peeled - if the expression refers to a variable
+    /// whose type is a reference, then that reference is kept because it wasn't created
+    /// in the expression.
+    pub peeled_span: Span,
+    /// The number of references that were peeled to produce `peeled_span`.
+    pub peeled_count: usize,
+    /// Does the peeled expression need to be wrapped in parentheses for
+    /// a prefix suggestion (i.e., dereference) to be valid.
+    pub peeled_prefix_suggestion_parentheses: bool,
+}
+
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
 pub struct IfExpressionCause<'tcx> {
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/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 2841470d248..f32656decd2 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -13,7 +13,7 @@ use std::ops::{Bound, Deref};
 use std::{fmt, iter, mem};
 
 use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
-use rustc_ast::{self as ast, attr};
+use rustc_ast as ast;
 use rustc_data_structures::defer;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
@@ -29,13 +29,12 @@ use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
 };
-use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
 use rustc_hir::definitions::Definitions;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{HirId, Node, TraitCandidate};
+use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
 use rustc_index::IndexVec;
 use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_query_system::cache::WithDepNode;
@@ -586,7 +585,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     }
 
     fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
-        self.trait_def(trait_def_id).safety == hir::Safety::Unsafe
+        self.trait_def(trait_def_id).safety.is_unsafe()
     }
 
     fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
@@ -722,7 +721,7 @@ impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
     }
 
     fn is_safe(self) -> bool {
-        matches!(self, hir::Safety::Safe)
+        self.is_safe()
     }
 
     fn prefix_str(self) -> &'static str {
@@ -2521,7 +2520,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// that is, a `fn` type that is equivalent in every way for being
     /// unsafe.
     pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
-        assert_eq!(sig.safety(), hir::Safety::Safe);
+        assert!(sig.safety().is_safe());
         Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
     }
 
@@ -3141,7 +3140,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Whether the trait impl is marked const. This does not consider stability or feature gates.
     pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
         self.def_kind(def_id) == DefKind::Impl { of_trait: true }
-            && self.constness(def_id) == hir::Constness::Const
+            && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
     }
 
     pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
@@ -3239,12 +3238,16 @@ pub fn provide(providers: &mut Providers) {
     providers.extern_mod_stmt_cnum =
         |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
     providers.is_panic_runtime =
-        |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime);
+        |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::panic_runtime);
     providers.is_compiler_builtins =
-        |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins);
+        |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins);
     providers.has_panic_handler = |tcx, LocalCrate| {
         // We want to check if the panic handler was defined in this crate
         tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
     };
     providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
 }
+
+pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
+    attrs.iter().any(|x| x.has_name(name))
+}
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 65c909e70f6..0ba187bf105 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -277,7 +277,7 @@ impl<'tcx> InstanceKind<'tcx> {
         &self,
         tcx: TyCtxt<'tcx>,
         attr: Symbol,
-    ) -> impl Iterator<Item = &'tcx rustc_ast::Attribute> {
+    ) -> impl Iterator<Item = &'tcx hir::Attribute> {
         tcx.get_attrs(self.def_id(), attr)
     }
 
@@ -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..cf8b6b5901a 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -33,9 +33,9 @@ use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
 use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
+use rustc_hir::LangItem;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
-use rustc_hir::{LangItem, Safety};
 use rustc_index::IndexVec;
 use rustc_macros::{
     Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
@@ -95,7 +95,7 @@ pub use self::sty::{
 pub use self::trait_def::TraitDef;
 pub use self::typeck_results::{
     CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
-    TypeckResults, UserType, UserTypeAnnotationIndex,
+    TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
 };
 pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
 use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
@@ -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)]
@@ -253,6 +254,7 @@ pub struct ImplTraitHeader<'tcx> {
     pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>,
     pub polarity: ImplPolarity,
     pub safety: hir::Safety,
+    pub constness: hir::Constness,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
@@ -1279,7 +1281,7 @@ impl VariantDef {
 
     /// Returns whether this variant has unsafe fields.
     pub fn has_unsafe_fields(&self) -> bool {
-        self.fields.iter().any(|x| x.safety == Safety::Unsafe)
+        self.fields.iter().any(|x| x.safety.is_unsafe())
     }
 }
 
@@ -1743,11 +1745,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     // FIXME(@lcnr): Remove this function.
-    pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [ast::Attribute] {
+    pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [hir::Attribute] {
         if let Some(did) = did.as_local() {
             self.hir().attrs(self.local_def_id_to_hir_id(did))
         } else {
-            self.item_attrs(did)
+            self.attrs_for_def(did)
         }
     }
 
@@ -1756,14 +1758,14 @@ impl<'tcx> TyCtxt<'tcx> {
         self,
         did: impl Into<DefId>,
         attr: Symbol,
-    ) -> impl Iterator<Item = &'tcx ast::Attribute> {
+    ) -> impl Iterator<Item = &'tcx hir::Attribute> {
         let did: DefId = did.into();
-        let filter_fn = move |a: &&ast::Attribute| a.has_name(attr);
+        let filter_fn = move |a: &&hir::Attribute| a.has_name(attr);
         if let Some(did) = did.as_local() {
             self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
         } else {
             debug_assert!(rustc_feature::encode_cross_crate(attr));
-            self.item_attrs(did).iter().filter(filter_fn)
+            self.attrs_for_def(did).iter().filter(filter_fn)
         }
     }
 
@@ -1779,7 +1781,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self,
         did: impl Into<DefId>,
         attr: Symbol,
-    ) -> Option<&'tcx ast::Attribute> {
+    ) -> Option<&'tcx hir::Attribute> {
         let did: DefId = did.into();
         if did.as_local().is_some() {
             // it's a crate local item, we need to check feature flags
@@ -1792,7 +1794,7 @@ impl<'tcx> TyCtxt<'tcx> {
             // we filter out unstable diagnostic attributes before
             // encoding attributes
             debug_assert!(rustc_feature::encode_cross_crate(attr));
-            self.item_attrs(did)
+            self.attrs_for_def(did)
                 .iter()
                 .find(|a| matches!(a.path().as_ref(), [sym::diagnostic, a] if *a == attr))
         }
@@ -1802,19 +1804,19 @@ impl<'tcx> TyCtxt<'tcx> {
         self,
         did: DefId,
         attr: &'attr [Symbol],
-    ) -> impl Iterator<Item = &'tcx ast::Attribute> + 'attr
+    ) -> impl Iterator<Item = &'tcx hir::Attribute> + 'attr
     where
         'tcx: 'attr,
     {
-        let filter_fn = move |a: &&ast::Attribute| a.path_matches(attr);
+        let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr);
         if let Some(did) = did.as_local() {
             self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
         } else {
-            self.item_attrs(did).iter().filter(filter_fn)
+            self.attrs_for_def(did).iter().filter(filter_fn)
         }
     }
 
-    pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx ast::Attribute> {
+    pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx hir::Attribute> {
         if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
             let did: DefId = did.into();
             bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
@@ -2004,17 +2006,25 @@ impl<'tcx> TyCtxt<'tcx> {
         let def_id: DefId = def_id.into();
         match self.def_kind(def_id) {
             DefKind::Impl { of_trait: true } => {
-                self.constness(def_id) == hir::Constness::Const
-                    && self.is_const_trait(
-                        self.trait_id_of_impl(def_id)
-                            .expect("expected trait for trait implementation"),
-                    )
+                let header = self.impl_trait_header(def_id).unwrap();
+                header.constness == hir::Constness::Const
+                    && self.is_const_trait(header.trait_ref.skip_binder().def_id)
             }
             DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
                 self.constness(def_id) == hir::Constness::Const
             }
             DefKind::Trait => self.is_const_trait(def_id),
-            DefKind::AssocTy | DefKind::AssocFn => {
+            DefKind::AssocTy => {
+                let parent_def_id = self.parent(def_id);
+                match self.def_kind(parent_def_id) {
+                    DefKind::Impl { of_trait: false } => false,
+                    DefKind::Impl { of_trait: true } | DefKind::Trait => {
+                        self.is_conditionally_const(parent_def_id)
+                    }
+                    _ => bug!("unexpected parent item of associated type: {parent_def_id:?}"),
+                }
+            }
+            DefKind::AssocFn => {
                 let parent_def_id = self.parent(def_id);
                 match self.def_kind(parent_def_id) {
                     DefKind::Impl { of_trait: false } => {
@@ -2023,7 +2033,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     DefKind::Impl { of_trait: true } | DefKind::Trait => {
                         self.is_conditionally_const(parent_def_id)
                     }
-                    _ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
+                    _ => bug!("unexpected parent item of associated fn: {parent_def_id:?}"),
                 }
             }
             DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index f7322217aa3..348f25c8f90 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -111,6 +111,7 @@ trivially_parameterized_over_tcx! {
     rustc_span::hygiene::SyntaxContextData,
     rustc_span::symbol::Ident,
     rustc_type_ir::Variance,
+    rustc_hir::Attribute,
 }
 
 // HACK(compiler-errors): This macro rule can only take a fake path,
@@ -140,5 +141,5 @@ parameterized_over_tcx! {
     ty::Predicate,
     ty::Clause,
     ty::ClauseKind,
-    ty::ImplTraitHeader
+    ty::ImplTraitHeader,
 }
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_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 8cba5f33278..551c113aa59 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -700,12 +700,31 @@ pub struct CanonicalUserTypeAnnotation<'tcx> {
 /// Canonical user type annotation.
 pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
 
+#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
+#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
+pub struct UserType<'tcx> {
+    pub kind: UserTypeKind<'tcx>,
+    pub bounds: ty::Clauses<'tcx>,
+}
+
+impl<'tcx> UserType<'tcx> {
+    pub fn new(kind: UserTypeKind<'tcx>) -> UserType<'tcx> {
+        UserType { kind, bounds: ty::ListWithCachedTypeInfo::empty() }
+    }
+
+    /// A user type annotation with additional bounds that need to be enforced.
+    /// These bounds are lowered from `impl Trait` in bindings.
+    pub fn new_with_bounds(kind: UserTypeKind<'tcx>, bounds: ty::Clauses<'tcx>) -> UserType<'tcx> {
+        UserType { kind, bounds }
+    }
+}
+
 /// A user-given type annotation attached to a constant. These arise
 /// from constants that are named via paths, like `Foo::<A>::new` and
 /// so forth.
 #[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
 #[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
-pub enum UserType<'tcx> {
+pub enum UserTypeKind<'tcx> {
     Ty(Ty<'tcx>),
 
     /// The canonical type is the result of `type_of(def_id)` with the
@@ -721,9 +740,13 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
     /// Returns `true` if this represents the generic parameters of the form `[?0, ?1, ?2]`,
     /// i.e., each thing is mapped to a canonical variable with the same index.
     fn is_identity(&self) -> bool {
-        match self.value {
-            UserType::Ty(_) => false,
-            UserType::TypeOf(_, user_args) => {
+        if !self.value.bounds.is_empty() {
+            return false;
+        }
+
+        match self.value.kind {
+            UserTypeKind::Ty(_) => false,
+            UserTypeKind::TypeOf(_, user_args) => {
                 if user_args.user_self_ty.is_some() {
                     return false;
                 }
@@ -765,6 +788,18 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
 
 impl<'tcx> std::fmt::Display for UserType<'tcx> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        if self.bounds.is_empty() {
+            self.kind.fmt(f)
+        } else {
+            self.kind.fmt(f)?;
+            write!(f, " + ")?;
+            std::fmt::Debug::fmt(&self.bounds, f)
+        }
+    }
+}
+
+impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
             Self::Ty(arg0) => {
                 ty::print::with_no_trimmed_paths!(write!(f, "Ty({})", arg0))
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index b9a45ea3c2c..fc3530e3dde 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -389,7 +389,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     .delay_as_bug();
             }
 
-            dtor_candidate = Some((*item_id, self.constness(impl_did)));
+            dtor_candidate = Some((*item_id, self.impl_trait_header(impl_did).unwrap().constness));
         });
 
         let (did, constness) = dtor_candidate?;
@@ -1291,7 +1291,7 @@ impl<'tcx> Ty<'tcx> {
     /// Checks whether this type is an ADT that has unsafe fields.
     pub fn has_unsafe_fields(self) -> bool {
         if let ty::Adt(adt_def, ..) = self.kind() {
-            adt_def.all_fields().any(|x| x.safety == hir::Safety::Unsafe)
+            adt_def.all_fields().any(|x| x.safety.is_unsafe())
         } else {
             false
         }
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 48d744a9ef6..390909bb0ab 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -100,7 +100,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for Representability {
         }
         for info in &cycle_error.cycle {
             if info.query.dep_kind == dep_kinds::representability_adt_ty
-                && let Some(def_id) = info.query.ty_def_id
+                && let Some(def_id) = info.query.def_id_for_ty_in_cycle
                 && let Some(def_id) = def_id.as_local()
                 && !item_and_field_ids.iter().any(|&(id, _)| id == def_id)
             {
@@ -182,7 +182,7 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
             &cycle_error.cycle,
             |cycle| {
                 if cycle[0].query.dep_kind == dep_kinds::layout_of
-                    && let Some(def_id) = cycle[0].query.ty_def_id
+                    && let Some(def_id) = cycle[0].query.def_id_for_ty_in_cycle
                     && let Some(def_id) = def_id.as_local()
                     && let def_kind = tcx.def_kind(def_id)
                     && matches!(def_kind, DefKind::Closure)
@@ -209,7 +209,7 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
                         if frame.query.dep_kind != dep_kinds::layout_of {
                             continue;
                         }
-                        let Some(frame_def_id) = frame.query.ty_def_id else {
+                        let Some(frame_def_id) = frame.query.def_id_for_ty_in_cycle else {
                             continue;
                         };
                         let Some(frame_coroutine_kind) = tcx.coroutine_kind(frame_def_id) else {
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index e809c9a23f3..34cdc288f0b 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -17,10 +17,9 @@
 //! terminators, and everything below can be found in the `parse::instruction` submodule.
 //!
 
-use rustc_ast::Attribute;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::HirId;
 use rustc_hir::def_id::DefId;
+use rustc_hir::{Attribute, HirId};
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::mir::*;
 use rustc_middle::span_bug;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 6ce88cdc39d..70a74910a68 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
 use rustc_middle::{bug, span_bug};
-use rustc_span::Span;
+use rustc_span::{DesugaringKind, Span};
 use tracing::{debug, instrument, trace};
 
 use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -630,6 +630,80 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         block.and(base_place.index(idx))
     }
 
+    /// Given a place that's either an array or a slice, returns an operand
+    /// with the length of the array/slice.
+    ///
+    /// For arrays it'll be `Operand::Constant` with the actual length;
+    /// For slices it'll be `Operand::Move` of a local using `PtrMetadata`.
+    fn len_of_slice_or_array(
+        &mut self,
+        block: BasicBlock,
+        place: Place<'tcx>,
+        span: Span,
+        source_info: SourceInfo,
+    ) -> Operand<'tcx> {
+        let place_ty = place.ty(&self.local_decls, self.tcx).ty;
+        let usize_ty = self.tcx.types.usize;
+
+        match place_ty.kind() {
+            ty::Array(_elem_ty, len_const) => {
+                // We know how long an array is, so just use that as a constant
+                // directly -- no locals needed. We do need one statement so
+                // that borrow- and initialization-checking consider it used,
+                // though. FIXME: Do we really *need* to count this as a use?
+                // Could partial array tracking work off something else instead?
+                self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
+                let const_ = Const::from_ty_const(*len_const, usize_ty, self.tcx);
+                Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
+            }
+            ty::Slice(_elem_ty) => {
+                let ptr_or_ref = if let [PlaceElem::Deref] = place.projection[..]
+                    && let local_ty = self.local_decls[place.local].ty
+                    && local_ty.is_trivially_pure_clone_copy()
+                {
+                    // It's extremely common that we have something that can be
+                    // directly passed to `PtrMetadata`, so avoid an unnecessary
+                    // temporary and statement in those cases. Note that we can
+                    // only do that for `Copy` types -- not `&mut [_]` -- because
+                    // the MIR we're building here needs to pass NLL later.
+                    Operand::Copy(Place::from(place.local))
+                } else {
+                    let len_span = self.tcx.with_stable_hashing_context(|hcx| {
+                        let span = source_info.span;
+                        span.mark_with_reason(
+                            None,
+                            DesugaringKind::IndexBoundsCheckReborrow,
+                            span.edition(),
+                            hcx,
+                        )
+                    });
+                    let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
+                    let slice_ptr = self.temp(ptr_ty, span);
+                    self.cfg.push_assign(
+                        block,
+                        SourceInfo { span: len_span, ..source_info },
+                        slice_ptr,
+                        Rvalue::RawPtr(Mutability::Not, place),
+                    );
+                    Operand::Move(slice_ptr)
+                };
+
+                let len = self.temp(usize_ty, span);
+                self.cfg.push_assign(
+                    block,
+                    source_info,
+                    len,
+                    Rvalue::UnaryOp(UnOp::PtrMetadata, ptr_or_ref),
+                );
+
+                Operand::Move(len)
+            }
+            _ => {
+                span_bug!(span, "len called on place of type {place_ty:?}")
+            }
+        }
+    }
+
     fn bounds_check(
         &mut self,
         block: BasicBlock,
@@ -638,25 +712,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr_span: Span,
         source_info: SourceInfo,
     ) -> BasicBlock {
-        let usize_ty = self.tcx.types.usize;
-        let bool_ty = self.tcx.types.bool;
-        // bounds check:
-        let len = self.temp(usize_ty, expr_span);
-        let lt = self.temp(bool_ty, expr_span);
+        let slice = slice.to_place(self);
 
         // len = len(slice)
-        self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.to_place(self)));
+        let len = self.len_of_slice_or_array(block, slice, expr_span, source_info);
+
         // lt = idx < len
+        let bool_ty = self.tcx.types.bool;
+        let lt = self.temp(bool_ty, expr_span);
         self.cfg.push_assign(
             block,
             source_info,
             lt,
             Rvalue::BinaryOp(
                 BinOp::Lt,
-                Box::new((Operand::Copy(Place::from(index)), Operand::Copy(len))),
+                Box::new((Operand::Copy(Place::from(index)), len.to_copy())),
             ),
         );
-        let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) };
+        let msg = BoundsCheck { len, index: Operand::Copy(Place::from(index)) };
+
         // assert!(lt, "...")
         self.assert(block, Operand::Move(lt), true, msg, expr_span)
     }
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index a3d5376dcd4..0ac1ae56d59 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -367,14 +367,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             .collect()
                     }
                     AdtExprBase::DefaultFields(field_types) => {
-                        itertools::zip_eq(field_names, &**field_types)
-                            .map(|(n, ty)| match fields_map.get(&n) {
+                        itertools::zip_eq(field_names, field_types)
+                            .map(|(n, &ty)| match fields_map.get(&n) {
                                 Some(v) => v.clone(),
                                 None => match variant.fields[n].value {
                                     Some(def) => {
-                                        let value = Const::from_unevaluated(this.tcx, def)
-                                            .instantiate(this.tcx, args);
-                                        this.literal_operand(expr_span, value)
+                                        let value = Const::Unevaluated(
+                                            UnevaluatedConst::new(def, args),
+                                            ty,
+                                        );
+                                        Operand::Constant(Box::new(ConstOperand {
+                                            span: expr_span,
+                                            user_ty: None,
+                                            const_: value,
+                                        }))
                                     }
                                     None => {
                                         let name = variant.fields[n].name;
diff --git a/compiler/rustc_mir_build/src/build/matches/match_pair.rs b/compiler/rustc_mir_build/src/build/matches/match_pair.rs
index 2815b390375..33fbd7b1a3f 100644
--- a/compiler/rustc_mir_build/src/build/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/build/matches/match_pair.rs
@@ -176,9 +176,8 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
                         ty: cx.infcx.next_ty_var(span),
                     })
                     .args;
-                    let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
-                        def_id,
-                        ty::UserArgs { args, user_self_ty: None },
+                    let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::new(
+                        ty::UserTypeKind::TypeOf(def_id, ty::UserArgs { args, user_self_ty: None }),
                     ));
                     let annotation = ty::CanonicalUserTypeAnnotation {
                         inferred_ty: pattern.ty,
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index f37b3f977fa..90be690e034 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -4,7 +4,7 @@ use std::ops::Bound;
 
 use rustc_errors::DiagArgValue;
 use rustc_hir::def::DefKind;
-use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Safety};
+use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
 use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
 use rustc_middle::mir::BorrowKind;
 use rustc_middle::span_bug;
@@ -342,7 +342,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             PatKind::Leaf { subpatterns, .. } => {
                 if let ty::Adt(adt_def, ..) = pat.ty.kind() {
                     for pat in subpatterns {
-                        if adt_def.non_enum_variant().fields[pat.field].safety == Safety::Unsafe {
+                        if adt_def.non_enum_variant().fields[pat.field].safety.is_unsafe() {
                             self.requires_unsafe(pat.pattern.span, UseOfUnsafeField);
                         }
                     }
@@ -367,7 +367,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             PatKind::Variant { adt_def, args: _, variant_index, subpatterns } => {
                 for pat in subpatterns {
                     let field = &pat.field;
-                    if adt_def.variant(*variant_index).fields[*field].safety == Safety::Unsafe {
+                    if adt_def.variant(*variant_index).fields[*field].safety.is_unsafe() {
                         self.requires_unsafe(pat.pattern.span, UseOfUnsafeField);
                     }
                 }
@@ -479,7 +479,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 return; // don't visit the whole expression
             }
             ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
-                if self.thir[fun].ty.fn_sig(self.tcx).safety() == hir::Safety::Unsafe {
+                if self.thir[fun].ty.fn_sig(self.tcx).safety().is_unsafe() {
                     let func_id = if let ty::FnDef(func_id, _) = self.thir[fun].ty.kind() {
                         Some(*func_id)
                     } else {
@@ -623,7 +623,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             ExprKind::Field { lhs, variant_index, name } => {
                 let lhs = &self.thir[lhs];
                 if let ty::Adt(adt_def, _) = lhs.ty.kind() {
-                    if adt_def.variant(variant_index).fields[name].safety == Safety::Unsafe {
+                    if adt_def.variant(variant_index).fields[name].safety.is_unsafe() {
                         self.requires_unsafe(expr.span, UseOfUnsafeField);
                     } else if adt_def.is_union() {
                         if let Some(assigned_ty) = self.assignment_info {
@@ -1112,11 +1112,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
 
     let hir_id = tcx.local_def_id_to_hir_id(def);
     let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
-        if fn_sig.header.safety == hir::Safety::Unsafe {
-            SafetyContext::UnsafeFn
-        } else {
-            SafetyContext::Safe
-        }
+        if fn_sig.header.safety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe }
     });
     let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features;
     let mut warnings = Vec::new();
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index d75f01dfba0..65a91d003af 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -15,7 +15,6 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::{
     self, AdtKind, GenericArgs, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs,
-    UserType,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::{Span, sym};
@@ -26,6 +25,14 @@ use crate::thir::cx::Cx;
 use crate::thir::util::UserAnnotatedTyHelpers;
 
 impl<'tcx> Cx<'tcx> {
+    /// Create a THIR expression for the given HIR expression. This expands all
+    /// adjustments and directly adds the type information from the
+    /// `typeck_results`. See the [dev-guide] for more details.
+    ///
+    /// (The term "mirror" in this case does not refer to "flipped" or
+    /// "reversed".)
+    ///
+    /// [dev-guide]: https://rustc-dev-guide.rust-lang.org/thir.html
     pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId {
         // `mirror_expr` is recursing very deep. Make sure the stack doesn't overflow.
         ensure_sufficient_stack(|| self.mirror_expr_inner(expr))
@@ -443,7 +450,9 @@ impl<'tcx> Cx<'tcx> {
                         let user_provided_types = self.typeck_results().user_provided_types();
                         let user_ty =
                             user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
-                                if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value {
+                                if let ty::UserTypeKind::TypeOf(ref mut did, _) =
+                                    &mut u_ty.value.kind
+                                {
                                     *did = adt_def.did();
                                 }
                                 Box::new(u_ty)
@@ -915,6 +924,11 @@ impl<'tcx> Cx<'tcx> {
                     }
                 }
             }
+
+            hir::ExprKind::UnsafeBinderCast(_kind, _source, _ty) => {
+                unreachable!("unsafe binders are not yet implemented")
+            }
+
             hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) },
             hir::ExprKind::Array(fields) => ExprKind::Array { fields: self.mirror_exprs(fields) },
             hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index 53a2a0852eb..ed7c7e40993 100644
--- a/compiler/rustc_mir_build/src/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
@@ -1,6 +1,6 @@
 use rustc_hir as hir;
 use rustc_middle::bug;
-use rustc_middle::ty::{self, CanonicalUserType, TyCtxt, UserType};
+use rustc_middle::ty::{self, CanonicalUserType, TyCtxt};
 use tracing::debug;
 
 pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
@@ -21,7 +21,7 @@ pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
         let ty = self.typeck_results().node_type(hir_id);
         match ty.kind() {
             ty::Adt(adt_def, ..) => {
-                if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
+                if let ty::UserTypeKind::TypeOf(ref mut did, _) = &mut user_ty.value.kind {
                     *did = adt_def.did();
                 }
                 Some(user_ty)
diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
index 4a9bcdaddb3..89ff93d9943 100644
--- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
@@ -179,15 +179,15 @@ where
     /// Advances the cursor to hold the dataflow state at `target` before its "primary" effect is
     /// applied.
     ///
-    /// The "before" effect at the target location *will be* applied.
+    /// The "early" effect at the target location *will be* applied.
     pub fn seek_before_primary_effect(&mut self, target: Location) {
-        self.seek_after(target, Effect::Before)
+        self.seek_after(target, Effect::Early)
     }
 
     /// Advances the cursor to hold the dataflow state at `target` after its "primary" effect is
     /// applied.
     ///
-    /// The "before" effect at the target location will be applied as well.
+    /// The "early" effect at the target location will be applied as well.
     pub fn seek_after_primary_effect(&mut self, target: Location) {
         self.seek_after(target, Effect::Primary)
     }
@@ -222,12 +222,12 @@ where
         #[rustfmt::skip]
         let next_effect = if A::Direction::IS_FORWARD {
             self.pos.curr_effect_index.map_or_else(
-                || Effect::Before.at_index(0),
+                || Effect::Early.at_index(0),
                 EffectIndex::next_in_forward_order,
             )
         } else {
             self.pos.curr_effect_index.map_or_else(
-                || Effect::Before.at_index(block_data.statements.len()),
+                || Effect::Early.at_index(block_data.statements.len()),
                 EffectIndex::next_in_backward_order,
             )
         };
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 566a6b09b2b..9d943ebe327 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -66,12 +66,12 @@ impl Direction for Backward {
     {
         let terminator = block_data.terminator();
         let location = Location { block, statement_index: block_data.statements.len() };
-        analysis.apply_before_terminator_effect(state, terminator, location);
-        analysis.apply_terminator_effect(state, terminator, location);
+        analysis.apply_early_terminator_effect(state, terminator, location);
+        analysis.apply_primary_terminator_effect(state, terminator, location);
         for (statement_index, statement) in block_data.statements.iter().enumerate().rev() {
             let location = Location { block, statement_index };
-            analysis.apply_before_statement_effect(state, statement, location);
-            analysis.apply_statement_effect(state, statement, location);
+            analysis.apply_early_statement_effect(state, statement, location);
+            analysis.apply_primary_statement_effect(state, statement, location);
         }
 
         let exit_state = state;
@@ -159,14 +159,14 @@ impl Direction for Backward {
                 let location = Location { block, statement_index: from.statement_index };
                 let terminator = block_data.terminator();
 
-                if from.effect == Effect::Before {
-                    analysis.apply_before_terminator_effect(state, terminator, location);
-                    if to == Effect::Before.at_index(terminator_index) {
+                if from.effect == Effect::Early {
+                    analysis.apply_early_terminator_effect(state, terminator, location);
+                    if to == Effect::Early.at_index(terminator_index) {
                         return;
                     }
                 }
 
-                analysis.apply_terminator_effect(state, terminator, location);
+                analysis.apply_primary_terminator_effect(state, terminator, location);
                 if to == Effect::Primary.at_index(terminator_index) {
                     return;
                 }
@@ -180,7 +180,7 @@ impl Direction for Backward {
                 let location = Location { block, statement_index: from.statement_index };
                 let statement = &block_data.statements[from.statement_index];
 
-                analysis.apply_statement_effect(state, statement, location);
+                analysis.apply_primary_statement_effect(state, statement, location);
                 if to == Effect::Primary.at_index(from.statement_index) {
                     return;
                 }
@@ -188,7 +188,7 @@ impl Direction for Backward {
                 from.statement_index - 1
             }
 
-            Effect::Before => from.statement_index,
+            Effect::Early => from.statement_index,
         };
 
         // Handle all statements between `first_unapplied_idx` and `to.statement_index`.
@@ -196,21 +196,21 @@ impl Direction for Backward {
         for statement_index in (to.statement_index..next_effect).rev().map(|i| i + 1) {
             let location = Location { block, statement_index };
             let statement = &block_data.statements[statement_index];
-            analysis.apply_before_statement_effect(state, statement, location);
-            analysis.apply_statement_effect(state, statement, location);
+            analysis.apply_early_statement_effect(state, statement, location);
+            analysis.apply_primary_statement_effect(state, statement, location);
         }
 
         // Handle the statement at `to`.
 
         let location = Location { block, statement_index: to.statement_index };
         let statement = &block_data.statements[to.statement_index];
-        analysis.apply_before_statement_effect(state, statement, location);
+        analysis.apply_early_statement_effect(state, statement, location);
 
-        if to.effect == Effect::Before {
+        if to.effect == Effect::Early {
             return;
         }
 
-        analysis.apply_statement_effect(state, statement, location);
+        analysis.apply_primary_statement_effect(state, statement, location);
     }
 
     fn visit_results_in_block<'mir, 'tcx, A>(
@@ -228,17 +228,17 @@ impl Direction for Backward {
 
         let loc = Location { block, statement_index: block_data.statements.len() };
         let term = block_data.terminator();
-        results.analysis.apply_before_terminator_effect(state, term, loc);
-        vis.visit_terminator_before_primary_effect(results, state, term, loc);
-        results.analysis.apply_terminator_effect(state, term, loc);
-        vis.visit_terminator_after_primary_effect(results, state, term, loc);
+        results.analysis.apply_early_terminator_effect(state, term, loc);
+        vis.visit_after_early_terminator_effect(results, state, term, loc);
+        results.analysis.apply_primary_terminator_effect(state, term, loc);
+        vis.visit_after_primary_terminator_effect(results, state, term, loc);
 
         for (statement_index, stmt) in block_data.statements.iter().enumerate().rev() {
             let loc = Location { block, statement_index };
-            results.analysis.apply_before_statement_effect(state, stmt, loc);
-            vis.visit_statement_before_primary_effect(results, state, stmt, loc);
-            results.analysis.apply_statement_effect(state, stmt, loc);
-            vis.visit_statement_after_primary_effect(results, state, stmt, loc);
+            results.analysis.apply_early_statement_effect(state, stmt, loc);
+            vis.visit_after_early_statement_effect(results, state, stmt, loc);
+            results.analysis.apply_primary_statement_effect(state, stmt, loc);
+            vis.visit_after_primary_statement_effect(results, state, stmt, loc);
         }
 
         vis.visit_block_start(state);
@@ -294,13 +294,13 @@ impl Direction for Forward {
     {
         for (statement_index, statement) in block_data.statements.iter().enumerate() {
             let location = Location { block, statement_index };
-            analysis.apply_before_statement_effect(state, statement, location);
-            analysis.apply_statement_effect(state, statement, location);
+            analysis.apply_early_statement_effect(state, statement, location);
+            analysis.apply_primary_statement_effect(state, statement, location);
         }
         let terminator = block_data.terminator();
         let location = Location { block, statement_index: block_data.statements.len() };
-        analysis.apply_before_terminator_effect(state, terminator, location);
-        let edges = analysis.apply_terminator_effect(state, terminator, location);
+        analysis.apply_early_terminator_effect(state, terminator, location);
+        let edges = analysis.apply_primary_terminator_effect(state, terminator, location);
 
         let exit_state = state;
         match edges {
@@ -368,21 +368,21 @@ impl Direction for Forward {
         // after effect, do so now and start the loop below from the next statement.
 
         let first_unapplied_index = match from.effect {
-            Effect::Before => from.statement_index,
+            Effect::Early => from.statement_index,
 
             Effect::Primary if from.statement_index == terminator_index => {
                 debug_assert_eq!(from, to);
 
                 let location = Location { block, statement_index: terminator_index };
                 let terminator = block_data.terminator();
-                analysis.apply_terminator_effect(state, terminator, location);
+                analysis.apply_primary_terminator_effect(state, terminator, location);
                 return;
             }
 
             Effect::Primary => {
                 let location = Location { block, statement_index: from.statement_index };
                 let statement = &block_data.statements[from.statement_index];
-                analysis.apply_statement_effect(state, statement, location);
+                analysis.apply_primary_statement_effect(state, statement, location);
 
                 // If we only needed to apply the after effect of the statement at `idx`, we are
                 // done.
@@ -399,8 +399,8 @@ impl Direction for Forward {
         for statement_index in first_unapplied_index..to.statement_index {
             let location = Location { block, statement_index };
             let statement = &block_data.statements[statement_index];
-            analysis.apply_before_statement_effect(state, statement, location);
-            analysis.apply_statement_effect(state, statement, location);
+            analysis.apply_early_statement_effect(state, statement, location);
+            analysis.apply_primary_statement_effect(state, statement, location);
         }
 
         // Handle the statement or terminator at `to`.
@@ -408,17 +408,17 @@ impl Direction for Forward {
         let location = Location { block, statement_index: to.statement_index };
         if to.statement_index == terminator_index {
             let terminator = block_data.terminator();
-            analysis.apply_before_terminator_effect(state, terminator, location);
+            analysis.apply_early_terminator_effect(state, terminator, location);
 
             if to.effect == Effect::Primary {
-                analysis.apply_terminator_effect(state, terminator, location);
+                analysis.apply_primary_terminator_effect(state, terminator, location);
             }
         } else {
             let statement = &block_data.statements[to.statement_index];
-            analysis.apply_before_statement_effect(state, statement, location);
+            analysis.apply_early_statement_effect(state, statement, location);
 
             if to.effect == Effect::Primary {
-                analysis.apply_statement_effect(state, statement, location);
+                analysis.apply_primary_statement_effect(state, statement, location);
             }
         }
     }
@@ -438,18 +438,18 @@ impl Direction for Forward {
 
         for (statement_index, stmt) in block_data.statements.iter().enumerate() {
             let loc = Location { block, statement_index };
-            results.analysis.apply_before_statement_effect(state, stmt, loc);
-            vis.visit_statement_before_primary_effect(results, state, stmt, loc);
-            results.analysis.apply_statement_effect(state, stmt, loc);
-            vis.visit_statement_after_primary_effect(results, state, stmt, loc);
+            results.analysis.apply_early_statement_effect(state, stmt, loc);
+            vis.visit_after_early_statement_effect(results, state, stmt, loc);
+            results.analysis.apply_primary_statement_effect(state, stmt, loc);
+            vis.visit_after_primary_statement_effect(results, state, stmt, loc);
         }
 
         let loc = Location { block, statement_index: block_data.statements.len() };
         let term = block_data.terminator();
-        results.analysis.apply_before_terminator_effect(state, term, loc);
-        vis.visit_terminator_before_primary_effect(results, state, term, loc);
-        results.analysis.apply_terminator_effect(state, term, loc);
-        vis.visit_terminator_after_primary_effect(results, state, term, loc);
+        results.analysis.apply_early_terminator_effect(state, term, loc);
+        vis.visit_after_early_terminator_effect(results, state, term, loc);
+        results.analysis.apply_primary_terminator_effect(state, term, loc);
+        vis.visit_after_primary_terminator_effect(results, state, term, loc);
 
         vis.visit_block_end(state);
     }
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index f844e8fbe03..5b2b128e035 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -724,7 +724,7 @@ where
         }
     }
 
-    fn visit_statement_before_primary_effect(
+    fn visit_after_early_statement_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
         state: &A::Domain,
@@ -737,7 +737,7 @@ where
         }
     }
 
-    fn visit_statement_after_primary_effect(
+    fn visit_after_primary_statement_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
         state: &A::Domain,
@@ -748,7 +748,7 @@ where
         self.prev_state.clone_from(state)
     }
 
-    fn visit_terminator_before_primary_effect(
+    fn visit_after_early_terminator_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
         state: &A::Domain,
@@ -761,7 +761,7 @@ where
         }
     }
 
-    fn visit_terminator_after_primary_effect(
+    fn visit_after_primary_terminator_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
         state: &A::Domain,
diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
index e063eaf74bd..cb8159ce37b 100644
--- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
@@ -38,10 +38,8 @@
 //! [Hasse diagram]: https://en.wikipedia.org/wiki/Hasse_diagram
 //! [poset]: https://en.wikipedia.org/wiki/Partially_ordered_set
 
-use std::iter;
-
+use rustc_index::Idx;
 use rustc_index::bit_set::{BitSet, MixedBitSet};
-use rustc_index::{Idx, IndexVec};
 
 use crate::framework::BitSetExt;
 
@@ -70,53 +68,6 @@ pub trait HasTop {
     const TOP: Self;
 }
 
-/// A `bool` is a "two-point" lattice with `true` as the top element and `false` as the bottom:
-///
-/// ```text
-///      true
-///        |
-///      false
-/// ```
-impl JoinSemiLattice for bool {
-    fn join(&mut self, other: &Self) -> bool {
-        if let (false, true) = (*self, *other) {
-            *self = true;
-            return true;
-        }
-
-        false
-    }
-}
-
-impl HasBottom for bool {
-    const BOTTOM: Self = false;
-
-    fn is_bottom(&self) -> bool {
-        !self
-    }
-}
-
-impl HasTop for bool {
-    const TOP: Self = true;
-}
-
-/// A tuple (or list) of lattices is itself a lattice whose least upper bound is the concatenation
-/// of the least upper bounds of each element of the tuple (or list).
-///
-/// In other words:
-///     (A₀, A₁, ..., Aₙ) ∨ (B₀, B₁, ..., Bₙ) = (A₀∨B₀, A₁∨B₁, ..., Aₙ∨Bₙ)
-impl<I: Idx, T: JoinSemiLattice> JoinSemiLattice for IndexVec<I, T> {
-    fn join(&mut self, other: &Self) -> bool {
-        assert_eq!(self.len(), other.len());
-
-        let mut changed = false;
-        for (a, b) in iter::zip(self, other) {
-            changed |= a.join(b);
-        }
-        changed
-    }
-}
-
 /// A `BitSet` represents the lattice formed by the powerset of all possible values of
 /// the index type `T` ordered by inclusion. Equivalently, it is a tuple of "two-point" lattices,
 /// one for each possible value of `T`.
@@ -197,18 +148,6 @@ impl<T> MaybeReachable<T> {
     }
 }
 
-impl<T> HasBottom for MaybeReachable<T> {
-    const BOTTOM: Self = MaybeReachable::Unreachable;
-
-    fn is_bottom(&self) -> bool {
-        matches!(self, Self::Unreachable)
-    }
-}
-
-impl<T: HasTop> HasTop for MaybeReachable<T> {
-    const TOP: Self = MaybeReachable::Reachable(T::TOP);
-}
-
 impl<S> MaybeReachable<S> {
     /// Return whether the current state contains the given element. If the state is unreachable,
     /// it does no contain anything.
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index 7f5a68e884e..41df5fae0de 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -56,7 +56,7 @@ mod visitor;
 pub use self::cursor::ResultsCursor;
 pub use self::direction::{Backward, Direction, Forward};
 pub use self::lattice::{JoinSemiLattice, MaybeReachable};
-pub use self::results::{EntrySets, Results};
+pub use self::results::{EntryStates, Results};
 pub use self::visitor::{ResultsVisitor, visit_results};
 
 /// Analysis domains are all bitsets of various kinds. This trait holds
@@ -122,8 +122,23 @@ pub trait Analysis<'tcx> {
     // `resume`). It's not obvious how to handle `yield` points in coroutines, however.
     fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain);
 
+    /// Updates the current dataflow state with an "early" effect, i.e. one
+    /// that occurs immediately before the given statement.
+    ///
+    /// This method is useful if the consumer of the results of this analysis only needs to observe
+    /// *part* of the effect of a statement (e.g. for two-phase borrows). As a general rule,
+    /// analyses should not implement this without also implementing
+    /// `apply_primary_statement_effect`.
+    fn apply_early_statement_effect(
+        &mut self,
+        _state: &mut Self::Domain,
+        _statement: &mir::Statement<'tcx>,
+        _location: Location,
+    ) {
+    }
+
     /// Updates the current dataflow state with the effect of evaluating a statement.
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         statement: &mir::Statement<'tcx>,
@@ -131,15 +146,16 @@ pub trait Analysis<'tcx> {
     );
 
     /// Updates the current dataflow state with an effect that occurs immediately *before* the
-    /// given statement.
+    /// given terminator.
     ///
-    /// This method is useful if the consumer of the results of this analysis only needs to observe
-    /// *part* of the effect of a statement (e.g. for two-phase borrows). As a general rule,
-    /// analyses should not implement this without also implementing `apply_statement_effect`.
-    fn apply_before_statement_effect(
+    /// This method is useful if the consumer of the results of this analysis needs only to observe
+    /// *part* of the effect of a terminator (e.g. for two-phase borrows). As a general rule,
+    /// analyses should not implement this without also implementing
+    /// `apply_primary_terminator_effect`.
+    fn apply_early_terminator_effect(
         &mut self,
         _state: &mut Self::Domain,
-        _statement: &mir::Statement<'tcx>,
+        _terminator: &mir::Terminator<'tcx>,
         _location: Location,
     ) {
     }
@@ -150,7 +166,7 @@ pub trait Analysis<'tcx> {
     /// in this function. That should go in `apply_call_return_effect`. For example, in the
     /// `InitializedPlaces` analyses, the return place for a function call is not marked as
     /// initialized here.
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
         _state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
@@ -159,27 +175,13 @@ pub trait Analysis<'tcx> {
         terminator.edges()
     }
 
-    /// Updates the current dataflow state with an effect that occurs immediately *before* the
-    /// given terminator.
-    ///
-    /// This method is useful if the consumer of the results of this analysis needs only to observe
-    /// *part* of the effect of a terminator (e.g. for two-phase borrows). As a general rule,
-    /// analyses should not implement this without also implementing `apply_terminator_effect`.
-    fn apply_before_terminator_effect(
-        &mut self,
-        _state: &mut Self::Domain,
-        _terminator: &mir::Terminator<'tcx>,
-        _location: Location,
-    ) {
-    }
-
     /* Edge-specific effects */
 
     /// Updates the current dataflow state with the effect of a successful return from a `Call`
     /// terminator.
     ///
-    /// This is separate from `apply_terminator_effect` to properly track state across unwind
-    /// edges.
+    /// This is separate from `apply_primary_terminator_effect` to properly track state across
+    /// unwind edges.
     fn apply_call_return_effect(
         &mut self,
         _state: &mut Self::Domain,
@@ -234,11 +236,12 @@ pub trait Analysis<'tcx> {
         Self: Sized,
         Self::Domain: DebugWithContext<Self>,
     {
-        let mut entry_sets =
+        let mut entry_states =
             IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
-        self.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
+        self.initialize_start_block(body, &mut entry_states[mir::START_BLOCK]);
 
-        if Self::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != self.bottom_value(body) {
+        if Self::Direction::IS_BACKWARD && entry_states[mir::START_BLOCK] != self.bottom_value(body)
+        {
             bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
         }
 
@@ -262,9 +265,9 @@ pub trait Analysis<'tcx> {
         let mut state = self.bottom_value(body);
         while let Some(bb) = dirty_queue.pop() {
             // Set the state to the entry state of the block.
-            // This is equivalent to `state = entry_sets[bb].clone()`,
+            // This is equivalent to `state = entry_states[bb].clone()`,
             // but it saves an allocation, thus improving compile times.
-            state.clone_from(&entry_sets[bb]);
+            state.clone_from(&entry_states[bb]);
 
             Self::Direction::apply_effects_in_block(
                 &mut self,
@@ -273,7 +276,7 @@ pub trait Analysis<'tcx> {
                 bb,
                 &body[bb],
                 |target: BasicBlock, state: &Self::Domain| {
-                    let set_changed = entry_sets[target].join(state);
+                    let set_changed = entry_states[target].join(state);
                     if set_changed {
                         dirty_queue.insert(target);
                     }
@@ -281,7 +284,7 @@ pub trait Analysis<'tcx> {
             );
         }
 
-        let mut results = Results { analysis: self, entry_sets };
+        let mut results = Results { analysis: self, entry_states };
 
         if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
             let res = write_graphviz_results(tcx, body, &mut results, pass_name);
@@ -358,11 +361,10 @@ impl<T, S: GenKill<T>> GenKill<T> for MaybeReachable<S> {
 // NOTE: DO NOT CHANGE VARIANT ORDER. The derived `Ord` impls rely on the current order.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
 enum Effect {
-    /// The "before" effect (e.g., `apply_before_statement_effect`) for a statement (or
-    /// terminator).
-    Before,
+    /// The "early" effect (e.g., `apply_early_statement_effect`) for a statement/terminator.
+    Early,
 
-    /// The "primary" effect (e.g., `apply_statement_effect`) for a statement (or terminator).
+    /// The "primary" effect (e.g., `apply_primary_statement_effect`) for a statement/terminator.
     Primary,
 }
 
@@ -381,15 +383,15 @@ pub struct EffectIndex {
 impl EffectIndex {
     fn next_in_forward_order(self) -> Self {
         match self.effect {
-            Effect::Before => Effect::Primary.at_index(self.statement_index),
-            Effect::Primary => Effect::Before.at_index(self.statement_index + 1),
+            Effect::Early => Effect::Primary.at_index(self.statement_index),
+            Effect::Primary => Effect::Early.at_index(self.statement_index + 1),
         }
     }
 
     fn next_in_backward_order(self) -> Self {
         match self.effect {
-            Effect::Before => Effect::Primary.at_index(self.statement_index),
-            Effect::Primary => Effect::Before.at_index(self.statement_index - 1),
+            Effect::Early => Effect::Primary.at_index(self.statement_index),
+            Effect::Primary => Effect::Early.at_index(self.statement_index - 1),
         }
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs
index a7dbd99b8ab..8e2c3afddb3 100644
--- a/compiler/rustc_mir_dataflow/src/framework/results.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/results.rs
@@ -6,7 +6,7 @@ use rustc_middle::mir::{BasicBlock, Body, traversal};
 use super::{Analysis, ResultsCursor, ResultsVisitor, visit_results};
 use crate::framework::cursor::ResultsHandle;
 
-pub type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
+pub type EntryStates<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
 
 /// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the
 /// entry of each basic block. Domain values in other parts of the block are recomputed on the fly
@@ -17,7 +17,7 @@ where
     A: Analysis<'tcx>,
 {
     pub analysis: A,
-    pub entry_sets: EntrySets<'tcx, A>,
+    pub entry_states: EntryStates<'tcx, A>,
 }
 
 impl<'tcx, A> Results<'tcx, A>
@@ -40,7 +40,7 @@ where
 
     /// Gets the dataflow state for the given block.
     pub fn entry_set_for_block(&self, block: BasicBlock) -> &A::Domain {
-        &self.entry_sets[block]
+        &self.entry_states[block]
     }
 
     pub fn visit_with<'mir>(
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index 14fb6dfb50c..8e7d4ab0fa3 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -73,7 +73,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
 ///
 /// The `102` in the block's entry set is derived from the basic block index and ensures that the
 /// expected state is unique across all basic blocks. Remember, it is generated by
-/// `mock_entry_sets`, not from actually running `MockAnalysis` to fixpoint.
+/// `mock_entry_states`, not from actually running `MockAnalysis` to fixpoint.
 struct MockAnalysis<'tcx, D> {
     body: &'tcx mir::Body<'tcx>,
     dir: PhantomData<D>,
@@ -90,7 +90,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
         ret
     }
 
-    fn mock_entry_sets(&self) -> IndexVec<BasicBlock, BitSet<usize>> {
+    fn mock_entry_states(&self) -> IndexVec<BasicBlock, BitSet<usize>> {
         let empty = self.bottom_value(self.body);
         let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks);
 
@@ -104,7 +104,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
     /// Returns the index that should be added to the dataflow state at the given target.
     fn effect(&self, loc: EffectIndex) -> usize {
         let idx = match loc.effect {
-            Effect::Before => loc.statement_index * 2,
+            Effect::Early => loc.statement_index * 2,
             Effect::Primary => loc.statement_index * 2 + 1,
         };
 
@@ -128,14 +128,14 @@ impl<D: Direction> MockAnalysis<'_, D> {
 
         let target = match target {
             SeekTarget::BlockEntry { .. } => return ret,
-            SeekTarget::Before(loc) => Effect::Before.at_index(loc.statement_index),
+            SeekTarget::Early(loc) => Effect::Early.at_index(loc.statement_index),
             SeekTarget::After(loc) => Effect::Primary.at_index(loc.statement_index),
         };
 
         let mut pos = if D::IS_FORWARD {
-            Effect::Before.at_index(0)
+            Effect::Early.at_index(0)
         } else {
-            Effect::Before.at_index(self.body[block].statements.len())
+            Effect::Early.at_index(self.body[block].statements.len())
         };
 
         loop {
@@ -168,52 +168,52 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
         unimplemented!("This is never called since `MockAnalysis` is never iterated to fixpoint");
     }
 
-    fn apply_statement_effect(
+    fn apply_early_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         _statement: &mir::Statement<'tcx>,
         location: Location,
     ) {
-        let idx = self.effect(Effect::Primary.at_index(location.statement_index));
+        let idx = self.effect(Effect::Early.at_index(location.statement_index));
         assert!(state.insert(idx));
     }
 
-    fn apply_before_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         _statement: &mir::Statement<'tcx>,
         location: Location,
     ) {
-        let idx = self.effect(Effect::Before.at_index(location.statement_index));
+        let idx = self.effect(Effect::Primary.at_index(location.statement_index));
         assert!(state.insert(idx));
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_early_terminator_effect(
         &mut self,
         state: &mut Self::Domain,
-        terminator: &'mir mir::Terminator<'tcx>,
+        _terminator: &mir::Terminator<'tcx>,
         location: Location,
-    ) -> TerminatorEdges<'mir, 'tcx> {
-        let idx = self.effect(Effect::Primary.at_index(location.statement_index));
+    ) {
+        let idx = self.effect(Effect::Early.at_index(location.statement_index));
         assert!(state.insert(idx));
-        terminator.edges()
     }
 
-    fn apply_before_terminator_effect(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
         state: &mut Self::Domain,
-        _terminator: &mir::Terminator<'tcx>,
+        terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
-    ) {
-        let idx = self.effect(Effect::Before.at_index(location.statement_index));
+    ) -> TerminatorEdges<'mir, 'tcx> {
+        let idx = self.effect(Effect::Primary.at_index(location.statement_index));
         assert!(state.insert(idx));
+        terminator.edges()
     }
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 enum SeekTarget {
     BlockEntry(BasicBlock),
-    Before(Location),
+    Early(Location),
     After(Location),
 }
 
@@ -223,7 +223,7 @@ impl SeekTarget {
 
         match *self {
             BlockEntry(block) => block,
-            Before(loc) | After(loc) => loc.block,
+            Early(loc) | After(loc) => loc.block,
         }
     }
 
@@ -235,7 +235,7 @@ impl SeekTarget {
             .map(move |(i, kind)| {
                 let loc = Location { block, statement_index: i };
                 match kind {
-                    0 => SeekTarget::Before(loc),
+                    0 => SeekTarget::Early(loc),
                     1 => SeekTarget::After(loc),
                     _ => unreachable!(),
                 }
@@ -249,7 +249,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
     let body = analysis.body;
 
     let mut cursor =
-        Results { entry_sets: analysis.mock_entry_sets(), analysis }.into_results_cursor(body);
+        Results { entry_states: analysis.mock_entry_states(), analysis }.into_results_cursor(body);
 
     cursor.allow_unreachable();
 
@@ -262,7 +262,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
 
         match targ {
             BlockEntry(block) => cursor.seek_to_block_entry(block),
-            Before(loc) => cursor.seek_before_primary_effect(loc),
+            Early(loc) => cursor.seek_before_primary_effect(loc),
             After(loc) => cursor.seek_after_primary_effect(loc),
         }
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
index bde41974d47..d18e9fa33f0 100644
--- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
@@ -35,9 +35,9 @@ where
 {
     fn visit_block_start(&mut self, _state: &A::Domain) {}
 
-    /// Called with the `before_statement_effect` of the given statement applied to `state` but not
-    /// its `statement_effect`.
-    fn visit_statement_before_primary_effect(
+    /// // njn: grep for "before", "primary", etc.
+    /// Called after the "early" effect of the given statement is applied to `state`.
+    fn visit_after_early_statement_effect(
         &mut self,
         _results: &mut Results<'tcx, A>,
         _state: &A::Domain,
@@ -46,9 +46,8 @@ where
     ) {
     }
 
-    /// Called with both the `before_statement_effect` and the `statement_effect` of the given
-    /// statement applied to `state`.
-    fn visit_statement_after_primary_effect(
+    /// Called after the "primary" effect of the given statement is applied to `state`.
+    fn visit_after_primary_statement_effect(
         &mut self,
         _results: &mut Results<'tcx, A>,
         _state: &A::Domain,
@@ -57,9 +56,8 @@ where
     ) {
     }
 
-    /// Called with the `before_terminator_effect` of the given terminator applied to `state` but
-    /// not its `terminator_effect`.
-    fn visit_terminator_before_primary_effect(
+    /// Called after the "early" effect of the given terminator is applied to `state`.
+    fn visit_after_early_terminator_effect(
         &mut self,
         _results: &mut Results<'tcx, A>,
         _state: &A::Domain,
@@ -68,11 +66,10 @@ where
     ) {
     }
 
-    /// Called with both the `before_terminator_effect` and the `terminator_effect` of the given
-    /// terminator applied to `state`.
+    /// Called after the "primary" effect of the given terminator is applied to `state`.
     ///
     /// The `call_return_effect` (if one exists) will *not* be applied to `state`.
-    fn visit_terminator_after_primary_effect(
+    fn visit_after_primary_terminator_effect(
         &mut self,
         _results: &mut Results<'tcx, A>,
         _state: &A::Domain,
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index cec654cac72..568d8a5acaf 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -33,22 +33,22 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
         // No locals are aliased on function entry
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         statement: &Statement<'tcx>,
         location: Location,
     ) {
-        Self::transfer_function(trans).visit_statement(statement, location);
+        Self::transfer_function(state).visit_statement(statement, location);
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &'mir Terminator<'tcx>,
         location: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
-        Self::transfer_function(trans).visit_terminator(terminator, location);
+        Self::transfer_function(state).visit_terminator(terminator, location);
         terminator.edges()
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
index 91677657602..fb02408e17d 100644
--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
@@ -70,7 +70,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
     pub fn is_unwind_dead(
         &self,
         place: mir::Place<'tcx>,
-        state: &MaybeReachable<MixedBitSet<MovePathIndex>>,
+        state: &<Self as Analysis<'tcx>>::Domain,
     ) -> bool {
         if let LookupResult::Exact(path) = self.move_data().rev_lookup.find(place.as_ref()) {
             let mut maybe_live = false;
@@ -218,26 +218,26 @@ impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> {
 
 impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
     fn update_bits(
-        trans: &mut <Self as Analysis<'tcx>>::Domain,
+        state: &mut <Self as Analysis<'tcx>>::Domain,
         path: MovePathIndex,
-        state: DropFlagState,
+        dfstate: DropFlagState,
     ) {
-        match state {
-            DropFlagState::Absent => trans.kill(path),
-            DropFlagState::Present => trans.gen_(path),
+        match dfstate {
+            DropFlagState::Absent => state.kill(path),
+            DropFlagState::Present => state.gen_(path),
         }
     }
 }
 
 impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
     fn update_bits(
-        trans: &mut <Self as Analysis<'tcx>>::Domain,
+        state: &mut <Self as Analysis<'tcx>>::Domain,
         path: MovePathIndex,
-        state: DropFlagState,
+        dfstate: DropFlagState,
     ) {
-        match state {
-            DropFlagState::Absent => trans.gen_(path),
-            DropFlagState::Present => trans.kill(path),
+        match dfstate {
+            DropFlagState::Absent => state.gen_(path),
+            DropFlagState::Present => state.kill(path),
         }
     }
 }
@@ -263,14 +263,14 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         });
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         statement: &mir::Statement<'tcx>,
         location: Location,
     ) {
         drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
-            Self::update_bits(trans, path, s)
+            Self::update_bits(state, path, s)
         });
 
         // Mark all places as "maybe init" if they are mutably borrowed. See #90752.
@@ -282,12 +282,12 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
             && let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref())
         {
             on_all_children_bits(self.move_data(), mpi, |child| {
-                trans.gen_(child);
+                state.gen_(child);
             })
         }
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
         state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
@@ -309,7 +309,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
 
     fn apply_call_return_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _block: mir::BasicBlock,
         return_places: CallReturnPlaces<'_, 'tcx>,
     ) {
@@ -320,7 +320,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
                 self.move_data(),
                 self.move_data().rev_lookup.find(place.as_ref()),
                 |mpi| {
-                    trans.gen_(mpi);
+                    state.gen_(mpi);
                 },
             );
         });
@@ -345,7 +345,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         };
 
         let mut discriminants = enum_def.discriminants(self.tcx);
-        edge_effects.apply(|trans, edge| {
+        edge_effects.apply(|state, edge| {
             let Some(value) = edge.value else {
                 return;
             };
@@ -363,25 +363,27 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
                 self.move_data(),
                 enum_place,
                 variant,
-                |mpi| trans.kill(mpi),
+                |mpi| state.kill(mpi),
             );
         });
     }
 }
 
+/// There can be many more `MovePathIndex` than there are locals in a MIR body.
+/// We use a mixed bitset to avoid paying too high a memory footprint.
+pub type MaybeUninitializedPlacesDomain = MixedBitSet<MovePathIndex>;
+
 impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
-    /// There can be many more `MovePathIndex` than there are locals in a MIR body.
-    /// We use a mixed bitset to avoid paying too high a memory footprint.
-    type Domain = MixedBitSet<MovePathIndex>;
+    type Domain = MaybeUninitializedPlacesDomain;
 
     const NAME: &'static str = "maybe_uninit";
 
     fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
-        // bottom = initialized (start_block_effect counters this at outset)
+        // bottom = initialized (`initialize_start_block` overwrites this on first entry)
         MixedBitSet::new_empty(self.move_data().move_paths.len())
     }
 
-    // sets on_entry bits for Arg places
+    // sets state bits for Arg places
     fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) {
         // set all bits to 1 (uninit) before gathering counter-evidence
         state.insert_all();
@@ -392,28 +394,28 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
         });
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _statement: &mir::Statement<'tcx>,
         location: Location,
     ) {
         drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
-            Self::update_bits(trans, path, s)
+            Self::update_bits(state, path, s)
         });
 
         // Unlike in `MaybeInitializedPlaces` above, we don't need to change the state when a
         // mutable borrow occurs. Places cannot become uninitialized through a mutable reference.
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
         drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
-            Self::update_bits(trans, path, s)
+            Self::update_bits(state, path, s)
         });
         if self.skip_unreachable_unwind.contains(location.block) {
             let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { bug!() };
@@ -426,7 +428,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
 
     fn apply_call_return_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _block: mir::BasicBlock,
         return_places: CallReturnPlaces<'_, 'tcx>,
     ) {
@@ -437,7 +439,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
                 self.move_data(),
                 self.move_data().rev_lookup.find(place.as_ref()),
                 |mpi| {
-                    trans.kill(mpi);
+                    state.kill(mpi);
                 },
             );
         });
@@ -466,7 +468,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
         };
 
         let mut discriminants = enum_def.discriminants(self.tcx);
-        edge_effects.apply(|trans, edge| {
+        edge_effects.apply(|state, edge| {
             let Some(value) = edge.value else {
                 return;
             };
@@ -484,16 +486,18 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
                 self.move_data(),
                 enum_place,
                 variant,
-                |mpi| trans.gen_(mpi),
+                |mpi| state.gen_(mpi),
             );
         });
     }
 }
 
+/// There can be many more `InitIndex` than there are locals in a MIR body.
+/// We use a mixed bitset to avoid paying too high a memory footprint.
+pub type EverInitializedPlacesDomain = MixedBitSet<InitIndex>;
+
 impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
-    /// There can be many more `InitIndex` than there are locals in a MIR body.
-    /// We use a mixed bitset to avoid paying too high a memory footprint.
-    type Domain = MixedBitSet<InitIndex>;
+    type Domain = EverInitializedPlacesDomain;
 
     const NAME: &'static str = "ever_init";
 
@@ -508,10 +512,10 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
         }
     }
 
-    #[instrument(skip(self, trans), level = "debug")]
-    fn apply_statement_effect(
+    #[instrument(skip(self, state), level = "debug")]
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         location: Location,
     ) {
@@ -521,7 +525,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
         let rev_lookup = &move_data.rev_lookup;
 
         debug!("initializes move_indexes {:?}", init_loc_map[location]);
-        trans.gen_all(init_loc_map[location].iter().copied());
+        state.gen_all(init_loc_map[location].iter().copied());
 
         if let mir::StatementKind::StorageDead(local) = stmt.kind {
             // End inits for StorageDead, so that an immutable variable can
@@ -531,15 +535,15 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
                     "clears the ever initialized status of {:?}",
                     init_path_map[move_path_index]
                 );
-                trans.kill_all(init_path_map[move_path_index].iter().copied());
+                state.kill_all(init_path_map[move_path_index].iter().copied());
             }
         }
     }
 
-    #[instrument(skip(self, trans, terminator), level = "debug")]
-    fn apply_terminator_effect<'mir>(
+    #[instrument(skip(self, state, terminator), level = "debug")]
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
@@ -548,7 +552,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
         let init_loc_map = &move_data.init_loc_map;
         debug!(?term);
         debug!("initializes move_indexes {:?}", init_loc_map[location]);
-        trans.gen_all(
+        state.gen_all(
             init_loc_map[location]
                 .iter()
                 .filter(|init_index| {
@@ -561,7 +565,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
 
     fn apply_call_return_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         block: mir::BasicBlock,
         _return_places: CallReturnPlaces<'_, 'tcx>,
     ) {
@@ -570,7 +574,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
 
         let call_loc = self.body.terminator_loc(block);
         for init_index in &init_loc_map[call_loc] {
-            trans.gen_(*init_index);
+            state.gen_(*init_index);
         }
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index fd7254a0210..b2050a6adf9 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -40,33 +40,33 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
         // No variables are live until we observe a use
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         statement: &mir::Statement<'tcx>,
         location: Location,
     ) {
-        TransferFunction(trans).visit_statement(statement, location);
+        TransferFunction(state).visit_statement(statement, location);
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
-        TransferFunction(trans).visit_terminator(terminator, location);
+        TransferFunction(state).visit_terminator(terminator, location);
         terminator.edges()
     }
 
     fn apply_call_return_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _block: mir::BasicBlock,
         return_places: CallReturnPlaces<'_, 'tcx>,
     ) {
         if let CallReturnPlaces::Yield(resume_place) = return_places {
-            YieldResumeEffect(trans).visit_place(
+            YieldResumeEffect(state).visit_place(
                 &resume_place,
                 PlaceContext::MutatingUse(MutatingUseContext::Yield),
                 Location::START,
@@ -74,7 +74,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
         } else {
             return_places.for_each(|place| {
                 if let Some(local) = place.as_local() {
-                    trans.kill(local);
+                    state.kill(local);
                 }
             });
         }
@@ -137,10 +137,10 @@ enum DefUse {
 }
 
 impl DefUse {
-    fn apply(trans: &mut BitSet<Local>, place: Place<'_>, context: PlaceContext) {
+    fn apply(state: &mut BitSet<Local>, place: Place<'_>, context: PlaceContext) {
         match DefUse::for_place(place, context) {
-            Some(DefUse::Def) => trans.kill(place.local),
-            Some(DefUse::Use) => trans.gen_(place.local),
+            Some(DefUse::Def) => state.kill(place.local),
+            Some(DefUse::Use) => state.gen_(place.local),
             None => {}
         }
     }
@@ -232,9 +232,9 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
         // No variables are live until we observe a use
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         statement: &mir::Statement<'tcx>,
         location: Location,
     ) {
@@ -258,34 +258,34 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
         };
         if let Some(destination) = destination {
             if !destination.is_indirect()
-                && !trans.contains(destination.local)
+                && !state.contains(destination.local)
                 && !self.always_live.contains(destination.local)
             {
                 // This store is dead
                 return;
             }
         }
-        TransferFunction(trans).visit_statement(statement, location);
+        TransferFunction(state).visit_statement(statement, location);
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
-        TransferFunction(trans).visit_terminator(terminator, location);
+        TransferFunction(state).visit_terminator(terminator, location);
         terminator.edges()
     }
 
     fn apply_call_return_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _block: mir::BasicBlock,
         return_places: CallReturnPlaces<'_, 'tcx>,
     ) {
         if let CallReturnPlaces::Yield(resume_place) = return_places {
-            YieldResumeEffect(trans).visit_place(
+            YieldResumeEffect(state).visit_place(
                 &resume_place,
                 PlaceContext::MutatingUse(MutatingUseContext::Yield),
                 Location::START,
@@ -293,7 +293,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
         } else {
             return_places.for_each(|place| {
                 if let Some(local) = place.as_local() {
-                    trans.remove(local);
+                    state.remove(local);
                 }
             });
         }
diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs
index d69a8019c8d..3f29b819a6d 100644
--- a/compiler/rustc_mir_dataflow/src/impls/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs
@@ -5,7 +5,8 @@ mod storage_liveness;
 
 pub use self::borrowed_locals::{MaybeBorrowedLocals, borrowed_locals};
 pub use self::initialized::{
-    EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
+    EverInitializedPlaces, EverInitializedPlacesDomain, MaybeInitializedPlaces,
+    MaybeUninitializedPlaces, MaybeUninitializedPlacesDomain,
 };
 pub use self::liveness::{
     MaybeLiveLocals, MaybeTransitiveLiveLocals, TransferFunction as LivenessTransferFunction,
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 1aae06d79d3..65b480d3a5e 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -44,23 +44,23 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> {
         BitSet::new_empty(body.local_decls.len())
     }
 
-    fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) {
-        on_entry.union(&*self.always_live_locals);
+    fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
+        state.union(&*self.always_live_locals);
 
         for arg in body.args_iter() {
-            on_entry.insert(arg);
+            state.insert(arg);
         }
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         stmt: &Statement<'tcx>,
         _: Location,
     ) {
         match stmt.kind {
-            StatementKind::StorageLive(l) => trans.gen_(l),
-            StatementKind::StorageDead(l) => trans.kill(l),
+            StatementKind::StorageLive(l) => state.gen_(l),
+            StatementKind::StorageDead(l) => state.kill(l),
             _ => (),
         }
     }
@@ -86,25 +86,25 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageDead<'a> {
         BitSet::new_empty(body.local_decls.len())
     }
 
-    fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) {
+    fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
         assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size());
         // Do not iterate on return place and args, as they are trivially always live.
         for local in body.vars_and_temps_iter() {
             if !self.always_live_locals.contains(local) {
-                on_entry.insert(local);
+                state.insert(local);
             }
         }
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         stmt: &Statement<'tcx>,
         _: Location,
     ) {
         match stmt.kind {
-            StatementKind::StorageLive(l) => trans.kill(l),
-            StatementKind::StorageDead(l) => trans.gen_(l),
+            StatementKind::StorageLive(l) => state.kill(l),
+            StatementKind::StorageDead(l) => state.gen_(l),
             _ => (),
         }
     }
@@ -134,31 +134,31 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
         BitSet::new_empty(body.local_decls.len())
     }
 
-    fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) {
+    fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
         // The resume argument is live on function entry (we don't care about
         // the `self` argument)
         for arg in body.args_iter().skip(1) {
-            on_entry.insert(arg);
+            state.insert(arg);
         }
     }
 
-    fn apply_before_statement_effect(
+    fn apply_early_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         stmt: &Statement<'tcx>,
         loc: Location,
     ) {
         // If a place is borrowed in a statement, it needs storage for that statement.
-        MaybeBorrowedLocals::transfer_function(trans).visit_statement(stmt, loc);
+        MaybeBorrowedLocals::transfer_function(state).visit_statement(stmt, loc);
 
         match &stmt.kind {
-            StatementKind::StorageDead(l) => trans.kill(*l),
+            StatementKind::StorageDead(l) => state.kill(*l),
 
             // If a place is assigned to in a statement, it needs storage for that statement.
             StatementKind::Assign(box (place, _))
             | StatementKind::SetDiscriminant { box place, .. }
             | StatementKind::Deinit(box place) => {
-                trans.gen_(place.local);
+                state.gen_(place.local);
             }
 
             // Nothing to do for these. Match exhaustively so this fails to compile when new
@@ -176,29 +176,29 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
         }
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _: &Statement<'tcx>,
         loc: Location,
     ) {
         // If we move from a place then it only stops needing storage *after*
         // that statement.
-        self.check_for_move(trans, loc);
+        self.check_for_move(state, loc);
     }
 
-    fn apply_before_terminator_effect(
+    fn apply_early_terminator_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &Terminator<'tcx>,
         loc: Location,
     ) {
         // If a place is borrowed in a terminator, it needs storage for that terminator.
-        MaybeBorrowedLocals::transfer_function(trans).visit_terminator(terminator, loc);
+        MaybeBorrowedLocals::transfer_function(state).visit_terminator(terminator, loc);
 
         match &terminator.kind {
             TerminatorKind::Call { destination, .. } => {
-                trans.gen_(destination.local);
+                state.gen_(destination.local);
             }
 
             // Note that we do *not* gen the `resume_arg` of `Yield` terminators. The reason for
@@ -213,7 +213,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
                         InlineAsmOperand::Out { place, .. }
                         | InlineAsmOperand::InOut { out_place: place, .. } => {
                             if let Some(place) = place {
-                                trans.gen_(place.local);
+                                state.gen_(place.local);
                             }
                         }
                         InlineAsmOperand::In { .. }
@@ -242,9 +242,9 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
         }
     }
 
-    fn apply_terminator_effect<'t>(
+    fn apply_primary_terminator_effect<'t>(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         terminator: &'t Terminator<'tcx>,
         loc: Location,
     ) -> TerminatorEdges<'t, 'tcx> {
@@ -254,12 +254,12 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
             // Since `propagate_call_unwind` doesn't exist, we have to kill the
             // destination here, and then gen it again in `call_return_effect`.
             TerminatorKind::Call { destination, .. } => {
-                trans.kill(destination.local);
+                state.kill(destination.local);
             }
 
             // The same applies to InlineAsm outputs.
             TerminatorKind::InlineAsm { ref operands, .. } => {
-                CallReturnPlaces::InlineAsm(operands).for_each(|place| trans.kill(place.local));
+                CallReturnPlaces::InlineAsm(operands).for_each(|place| state.kill(place.local));
             }
 
             // Nothing to do for these. Match exhaustively so this fails to compile when new
@@ -279,32 +279,32 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
             | TerminatorKind::Unreachable => {}
         }
 
-        self.check_for_move(trans, loc);
+        self.check_for_move(state, loc);
         terminator.edges()
     }
 
     fn apply_call_return_effect(
         &mut self,
-        trans: &mut Self::Domain,
+        state: &mut Self::Domain,
         _block: BasicBlock,
         return_places: CallReturnPlaces<'_, 'tcx>,
     ) {
-        return_places.for_each(|place| trans.gen_(place.local));
+        return_places.for_each(|place| state.gen_(place.local));
     }
 }
 
 impl<'tcx> MaybeRequiresStorage<'_, 'tcx> {
     /// Kill locals that are fully moved and have not been borrowed.
-    fn check_for_move(&mut self, trans: &mut <Self as Analysis<'tcx>>::Domain, loc: Location) {
+    fn check_for_move(&mut self, state: &mut <Self as Analysis<'tcx>>::Domain, loc: Location) {
         let body = self.borrowed_locals.body();
-        let mut visitor = MoveVisitor { trans, borrowed_locals: &mut self.borrowed_locals };
+        let mut visitor = MoveVisitor { state, borrowed_locals: &mut self.borrowed_locals };
         visitor.visit_location(body, loc);
     }
 }
 
 struct MoveVisitor<'a, 'mir, 'tcx> {
     borrowed_locals: &'a mut BorrowedLocalsResults<'mir, 'tcx>,
-    trans: &'a mut BitSet<Local>,
+    state: &'a mut BitSet<Local>,
 }
 
 impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> {
@@ -312,7 +312,7 @@ impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> {
         if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context {
             self.borrowed_locals.seek_before_primary_effect(loc);
             if !self.borrowed_locals.get().contains(local) {
-                self.trans.kill(local);
+                self.state.kill(local);
             }
         }
     }
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index 2248972cecc..85255db5d9a 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -18,7 +18,7 @@ pub use self::drop_flag_effects::{
     move_path_children_matching, on_all_children_bits, on_lookup_result_bits,
 };
 pub use self::framework::{
-    Analysis, Backward, Direction, EntrySets, Forward, GenKill, JoinSemiLattice, MaybeReachable,
+    Analysis, Backward, Direction, EntryStates, Forward, GenKill, JoinSemiLattice, MaybeReachable,
     Results, ResultsCursor, ResultsVisitor, SwitchIntEdgeEffects, fmt, graphviz, lattice,
     visit_results,
 };
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_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs
index 10f1e009855..74209da876a 100644
--- a/compiler/rustc_mir_dataflow/src/points.rs
+++ b/compiler/rustc_mir_dataflow/src/points.rs
@@ -125,7 +125,7 @@ where
     A: Analysis<'tcx, Domain = BitSet<N>>,
     N: Idx,
 {
-    fn visit_statement_after_primary_effect(
+    fn visit_after_primary_statement_effect(
         &mut self,
         _results: &mut Results<'tcx, A>,
         state: &A::Domain,
@@ -139,7 +139,7 @@ where
         });
     }
 
-    fn visit_terminator_after_primary_effect(
+    fn visit_after_primary_terminator_effect(
         &mut self,
         _results: &mut Results<'tcx, A>,
         state: &A::Domain,
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 34ef8afdde3..85cf8ca2104 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -1,6 +1,5 @@
 use rustc_ast::MetaItem;
 use rustc_hir::def_id::DefId;
-use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::{self, Body, Local, Location};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
@@ -254,7 +253,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
         &self,
         tcx: TyCtxt<'tcx>,
         place: mir::Place<'tcx>,
-        state: &BitSet<Local>,
+        state: &Self::Domain,
         call: PeekCall,
     ) {
         info!(?place, "peek_at");
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index ed8678de1eb..9328870c7ae 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -67,7 +67,7 @@ impl<V: Clone> Clone for StateData<V> {
     }
 }
 
-impl<V: JoinSemiLattice + Clone + HasBottom> JoinSemiLattice for StateData<V> {
+impl<V: JoinSemiLattice + Clone> JoinSemiLattice for StateData<V> {
     fn join(&mut self, other: &Self) -> bool {
         let mut changed = false;
         #[allow(rustc::potential_query_instability)]
@@ -342,7 +342,7 @@ impl<V: Clone + HasBottom> State<V> {
     }
 }
 
-impl<V: JoinSemiLattice + Clone + HasBottom> JoinSemiLattice for State<V> {
+impl<V: JoinSemiLattice + Clone> JoinSemiLattice for State<V> {
     fn join(&mut self, other: &Self) -> bool {
         match (&mut *self, other) {
             (_, State::Unreachable) => false,
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 858752a3f01..31d5245fb5c 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -878,7 +878,7 @@ struct StorageConflictVisitor<'a, 'tcx> {
 impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, MaybeRequiresStorage<'a, 'tcx>>
     for StorageConflictVisitor<'a, 'tcx>
 {
-    fn visit_statement_before_primary_effect(
+    fn visit_after_early_statement_effect(
         &mut self,
         _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
         state: &BitSet<Local>,
@@ -888,7 +888,7 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, MaybeRequiresStorage<'a, 'tcx>>
         self.apply_state(state, loc);
     }
 
-    fn visit_terminator_before_primary_effect(
+    fn visit_after_early_terminator_effect(
         &mut self,
         _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
         state: &BitSet<Local>,
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/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index b94c925b1db..711cf2edc46 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -106,7 +106,7 @@ impl<'tcx> Analysis<'tcx> for ConstAnalysis<'_, 'tcx> {
         }
     }
 
-    fn apply_statement_effect(
+    fn apply_primary_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         statement: &Statement<'tcx>,
@@ -117,7 +117,7 @@ impl<'tcx> Analysis<'tcx> for ConstAnalysis<'_, 'tcx> {
         }
     }
 
-    fn apply_terminator_effect<'mir>(
+    fn apply_primary_terminator_effect<'mir>(
         &mut self,
         state: &mut Self::Domain,
         terminator: &'mir Terminator<'tcx>,
@@ -224,7 +224,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
     }
 
     /// The effect of a successful function call return should not be
-    /// applied here, see [`Analysis::apply_terminator_effect`].
+    /// applied here, see [`Analysis::apply_primary_terminator_effect`].
     fn handle_terminator<'mir>(
         &self,
         terminator: &'mir Terminator<'tcx>,
@@ -954,7 +954,7 @@ fn try_write_constant<'tcx>(
 
 impl<'mir, 'tcx> ResultsVisitor<'mir, 'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> {
     #[instrument(level = "trace", skip(self, results, statement))]
-    fn visit_statement_before_primary_effect(
+    fn visit_after_early_statement_effect(
         &mut self,
         results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
         state: &State<FlatSet<Scalar>>,
@@ -976,7 +976,7 @@ impl<'mir, 'tcx> ResultsVisitor<'mir, 'tcx, ConstAnalysis<'_, 'tcx>> for Collect
     }
 
     #[instrument(level = "trace", skip(self, results, statement))]
-    fn visit_statement_after_primary_effect(
+    fn visit_after_primary_statement_effect(
         &mut self,
         results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
         state: &State<FlatSet<Scalar>>,
@@ -1001,7 +1001,7 @@ impl<'mir, 'tcx> ResultsVisitor<'mir, 'tcx, ConstAnalysis<'_, 'tcx>> for Collect
         }
     }
 
-    fn visit_terminator_before_primary_effect(
+    fn visit_after_early_terminator_effect(
         &mut self,
         results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
         state: &State<FlatSet<Scalar>>,
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 0c0f3b61977..3ebc9113725 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -127,7 +127,7 @@ impl InitializationData<'_, '_> {
         self.uninits.seek_before_primary_effect(loc);
     }
 
-    fn maybe_live_dead(&self, path: MovePathIndex) -> (bool, bool) {
+    fn maybe_init_uninit(&self, path: MovePathIndex) -> (bool, bool) {
         (self.inits.get().contains(path), self.uninits.get().contains(path))
     }
 }
@@ -153,23 +153,23 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> {
 
     #[instrument(level = "debug", skip(self), ret)]
     fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
-        let ((maybe_live, maybe_dead), multipart) = match mode {
-            DropFlagMode::Shallow => (self.init_data.maybe_live_dead(path), false),
+        let ((maybe_init, maybe_uninit), multipart) = match mode {
+            DropFlagMode::Shallow => (self.init_data.maybe_init_uninit(path), false),
             DropFlagMode::Deep => {
-                let mut some_live = false;
-                let mut some_dead = false;
+                let mut some_maybe_init = false;
+                let mut some_maybe_uninit = false;
                 let mut children_count = 0;
                 on_all_children_bits(self.move_data(), path, |child| {
-                    let (live, dead) = self.init_data.maybe_live_dead(child);
-                    debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead));
-                    some_live |= live;
-                    some_dead |= dead;
+                    let (maybe_init, maybe_uninit) = self.init_data.maybe_init_uninit(child);
+                    debug!("elaborate_drop: state({:?}) = {:?}", child, (maybe_init, maybe_uninit));
+                    some_maybe_init |= maybe_init;
+                    some_maybe_uninit |= maybe_uninit;
                     children_count += 1;
                 });
-                ((some_live, some_dead), children_count != 1)
+                ((some_maybe_init, some_maybe_uninit), children_count != 1)
             }
         };
-        match (maybe_live, maybe_dead, multipart) {
+        match (maybe_init, maybe_uninit, multipart) {
             (false, _, _) => DropStyle::Dead,
             (true, false, _) => DropStyle::Static,
             (true, true, false) => DropStyle::Conditional,
@@ -283,15 +283,15 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> {
                 LookupResult::Exact(path) => {
                     self.init_data.seek_before(self.body.terminator_loc(bb));
                     on_all_children_bits(self.move_data(), path, |child| {
-                        let (maybe_live, maybe_dead) = self.init_data.maybe_live_dead(child);
+                        let (maybe_init, maybe_uninit) = self.init_data.maybe_init_uninit(child);
                         debug!(
                             "collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}",
                             child,
                             place,
                             path,
-                            (maybe_live, maybe_dead)
+                            (maybe_init, maybe_uninit)
                         );
-                        if maybe_live && maybe_dead {
+                        if maybe_init && maybe_uninit {
                             self.create_drop_flag(child, terminator.source_info.span)
                         }
                     });
@@ -303,8 +303,8 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> {
                     }
 
                     self.init_data.seek_before(self.body.terminator_loc(bb));
-                    let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent);
-                    if maybe_dead {
+                    let (_maybe_init, maybe_uninit) = self.init_data.maybe_init_uninit(parent);
+                    if maybe_uninit {
                         self.tcx.dcx().span_delayed_bug(
                             terminator.source_info.span,
                             format!(
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index a6ba2f32d32..adc3374df2e 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -47,7 +47,6 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
                         }
                         ctx.simplify_bool_cmp(rvalue);
                         ctx.simplify_ref_deref(rvalue);
-                        ctx.simplify_len(rvalue);
                         ctx.simplify_ptr_aggregate(rvalue);
                         ctx.simplify_cast(rvalue);
                     }
@@ -132,18 +131,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
         }
     }
 
-    /// Transform `Len([_; N])` ==> `N`.
-    fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) {
-        if let Rvalue::Len(ref place) = *rvalue {
-            let place_ty = place.ty(self.local_decls, self.tcx).ty;
-            if let ty::Array(_, len) = *place_ty.kind() {
-                let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
-                let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
-                *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
-            }
-        }
-    }
-
     /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
     fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index f0fcb44603b..5c090bf7cad 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -189,6 +189,7 @@ declare_passes! {
     mod simplify_comparison_integral : SimplifyComparisonIntegral;
     mod single_use_consts : SingleUseConsts;
     mod sroa : ScalarReplacementOfAggregates;
+    mod strip_debuginfo : StripDebugInfo;
     mod unreachable_enum_branching : UnreachableEnumBranching;
     mod unreachable_prop : UnreachablePropagation;
     mod validate : Validator;
@@ -699,6 +700,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             &o1(simplify_branches::SimplifyConstCondition::Final),
             &o1(remove_noop_landing_pads::RemoveNoopLandingPads),
             &o1(simplify::SimplifyCfg::Final),
+            // After the last SimplifyCfg, because this wants one-block functions.
+            &strip_debuginfo::StripDebugInfo,
             &copy_prop::CopyProp,
             &dead_store_elimination::DeadStoreElimination::Final,
             &nrvo::RenameReturnPlace,
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_mir_transform/src/strip_debuginfo.rs b/compiler/rustc_mir_transform/src/strip_debuginfo.rs
new file mode 100644
index 00000000000..438c75726bb
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/strip_debuginfo.rs
@@ -0,0 +1,34 @@
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
+use rustc_session::config::MirStripDebugInfo;
+
+/// Conditionally remove some of the VarDebugInfo in MIR.
+///
+/// In particular, stripping non-parameter debug info for tiny, primitive-like
+/// methods in core saves work later, and nobody ever wanted to use it anyway.
+pub(super) struct StripDebugInfo;
+
+impl<'tcx> crate::MirPass<'tcx> for StripDebugInfo {
+    fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
+        sess.opts.unstable_opts.mir_strip_debuginfo != MirStripDebugInfo::None
+    }
+
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        match tcx.sess.opts.unstable_opts.mir_strip_debuginfo {
+            MirStripDebugInfo::None => return,
+            MirStripDebugInfo::AllLocals => {}
+            MirStripDebugInfo::LocalsInTinyFunctions
+                if let TerminatorKind::Return { .. } =
+                    body.basic_blocks[START_BLOCK].terminator().kind => {}
+            MirStripDebugInfo::LocalsInTinyFunctions => return,
+        }
+
+        body.var_debug_info.retain(|vdi| {
+            matches!(
+                vdi.value,
+                VarDebugInfoContents::Place(place)
+                    if place.local.as_usize() <= body.arg_count && place.local != RETURN_PLACE,
+            )
+        });
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 404fbb6b839..bce015046e1 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1115,14 +1115,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         );
                     }
                     UnOp::PtrMetadata => {
-                        if !matches!(self.body.phase, MirPhase::Runtime(_)) {
-                            // It would probably be fine to support this in earlier phases, but at
-                            // the time of writing it's only ever introduced from intrinsic
-                            // lowering or other runtime-phase optimization passes, so earlier
-                            // things can just `bug!` on it.
-                            self.fail(location, "PtrMetadata should be in runtime MIR only");
-                        }
-
                         check_kinds!(
                             a,
                             "Cannot PtrMetadata non-pointer non-reference type {:?}",
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/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 2426eb81678..443ddfc94ec 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -69,24 +69,30 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
         token: Token::dummy(),
         diag_info: TokenTreeDiagInfo::default(),
     };
-    let (_open_spacing, stream, res) = lexer.lex_token_trees(/* is_delimited */ false);
-    let unmatched_delims = lexer.diag_info.unmatched_delims;
-
-    if res.is_ok() && unmatched_delims.is_empty() {
-        Ok(stream)
-    } else {
-        // Return error if there are unmatched delimiters or unclosed delimiters.
-        // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
-        // because the delimiter mismatch is more likely to be the root cause of error
-        let mut buffer: Vec<_> = unmatched_delims
-            .into_iter()
-            .filter_map(|unmatched_delim| make_unclosed_delims_error(unmatched_delim, psess))
-            .collect();
-        if let Err(errs) = res {
-            // Add unclosing delimiter or diff marker errors
-            buffer.extend(errs);
+    let res = lexer.lex_token_trees(/* is_delimited */ false);
+
+    let mut unmatched_delims: Vec<_> = lexer
+        .diag_info
+        .unmatched_delims
+        .into_iter()
+        .filter_map(|unmatched_delim| make_unclosed_delims_error(unmatched_delim, psess))
+        .collect();
+
+    match res {
+        Ok((_open_spacing, stream)) => {
+            if unmatched_delims.is_empty() {
+                Ok(stream)
+            } else {
+                // Return error if there are unmatched delimiters or unclosed delimiters.
+                Err(unmatched_delims)
+            }
+        }
+        Err(errs) => {
+            // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
+            // because the delimiter mismatch is more likely to be the root cause of error
+            unmatched_delims.extend(errs);
+            Err(unmatched_delims)
         }
-        Err(buffer)
     }
 }
 
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index c6c9eb3b0b2..b3f83a32024 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -1,12 +1,10 @@
 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_span::symbol::kw;
+use rustc_errors::Diag;
 
 use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level};
 use super::{Lexer, UnmatchedDelim};
-use crate::Parser;
 
 impl<'psess, 'src> Lexer<'psess, 'src> {
     // Lex into a token stream. The `Spacing` in the result is that of the
@@ -14,7 +12,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
     pub(super) fn lex_token_trees(
         &mut self,
         is_delimited: bool,
-    ) -> (Spacing, TokenStream, Result<(), Vec<PErr<'psess>>>) {
+    ) -> Result<(Spacing, TokenStream), Vec<Diag<'psess>>> {
         // Move past the opening delimiter.
         let open_spacing = self.bump_minimal();
 
@@ -27,25 +25,25 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
                     debug_assert!(!matches!(delim, Delimiter::Invisible(_)));
                     buf.push(match self.lex_token_tree_open_delim(delim) {
                         Ok(val) => val,
-                        Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
+                        Err(errs) => return Err(errs),
                     })
                 }
                 token::CloseDelim(delim) => {
                     // Invisible delimiters cannot occur here because `TokenTreesReader` parses
                     // code directly from strings, with no macro expansion involved.
                     debug_assert!(!matches!(delim, Delimiter::Invisible(_)));
-                    return (
-                        open_spacing,
-                        TokenStream::new(buf),
-                        if is_delimited { Ok(()) } else { Err(vec![self.close_delim_err(delim)]) },
-                    );
+                    return if is_delimited {
+                        Ok((open_spacing, TokenStream::new(buf)))
+                    } else {
+                        Err(vec![self.close_delim_err(delim)])
+                    };
                 }
                 token::Eof => {
-                    return (
-                        open_spacing,
-                        TokenStream::new(buf),
-                        if is_delimited { Err(vec![self.eof_err()]) } else { Ok(()) },
-                    );
+                    return if is_delimited {
+                        Err(vec![self.eof_err()])
+                    } else {
+                        Ok((open_spacing, TokenStream::new(buf)))
+                    };
                 }
                 _ => {
                     // Get the next normal token.
@@ -56,7 +54,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 +96,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;
 
@@ -107,10 +105,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
         // Lex the token trees within the delimiters.
         // We stop at any delimiter so we can try to recover if the user
         // uses an incorrect delimiter.
-        let (open_spacing, tts, res) = self.lex_token_trees(/* is_delimited */ true);
-        if let Err(errs) = res {
-            return Err(self.unclosed_delim_err(tts, errs));
-        }
+        let (open_spacing, tts) = self.lex_token_trees(/* is_delimited */ true)?;
 
         // Expand to cover the entire delimited token tree.
         let delim_span = DelimSpan::from_pair(pre_span, self.token.span);
@@ -247,68 +242,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
         this_spacing
     }
 
-    fn unclosed_delim_err(
-        &mut self,
-        tts: TokenStream,
-        mut errs: Vec<PErr<'psess>>,
-    ) -> Vec<PErr<'psess>> {
-        // If there are unclosed delims, see if there are diff markers and if so, point them
-        // out instead of complaining about the unclosed delims.
-        let mut parser = Parser::new(self.psess, tts, None);
-        let mut diff_errs = vec![];
-        // Suggest removing a `{` we think appears in an `if`/`while` condition.
-        // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition,
-        // but we have no way of tracking this in the lexer itself, so we piggyback on the parser.
-        let mut in_cond = false;
-        while parser.token != token::Eof {
-            if let Err(diff_err) = parser.err_vcs_conflict_marker() {
-                diff_errs.push(diff_err);
-            } else if parser.is_keyword_ahead(0, &[kw::If, kw::While]) {
-                in_cond = true;
-            } else if matches!(
-                parser.token.kind,
-                token::CloseDelim(Delimiter::Brace) | token::FatArrow
-            ) {
-                // End of the `if`/`while` body, or the end of a `match` guard.
-                in_cond = false;
-            } else if in_cond && parser.token == token::OpenDelim(Delimiter::Brace) {
-                // Store the `&&` and `let` to use their spans later when creating the diagnostic
-                let maybe_andand = parser.look_ahead(1, |t| t.clone());
-                let maybe_let = parser.look_ahead(2, |t| t.clone());
-                if maybe_andand == token::OpenDelim(Delimiter::Brace) {
-                    // This might be the beginning of the `if`/`while` body (i.e., the end of the
-                    // condition).
-                    in_cond = false;
-                } else if maybe_andand == token::AndAnd && maybe_let.is_keyword(kw::Let) {
-                    let mut err = parser.dcx().struct_span_err(
-                        parser.token.span,
-                        "found a `{` in the middle of a let-chain",
-                    );
-                    err.span_suggestion(
-                        parser.token.span,
-                        "consider removing this brace to parse the `let` as part of the same chain",
-                        "",
-                        Applicability::MachineApplicable,
-                    );
-                    err.span_label(
-                        maybe_andand.span.to(maybe_let.span),
-                        "you might have meant to continue the let-chain here",
-                    );
-                    errs.push(err);
-                }
-            }
-            parser.bump();
-        }
-        if !diff_errs.is_empty() {
-            for err in errs {
-                err.cancel();
-            }
-            return diff_errs;
-        }
-        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/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index b6fa2099588..8cf37671185 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -1,6 +1,5 @@
-use rustc_ast as ast;
-use rustc_ast::attr;
 use rustc_ast::token::{self, Delimiter};
+use rustc_ast::{self as ast, Attribute, attr};
 use rustc_errors::codes::*;
 use rustc_errors::{Diag, PResult};
 use rustc_span::symbol::kw;
@@ -48,7 +47,7 @@ impl<'a> Parser<'a> {
         let start_pos = self.num_bump_calls;
         loop {
             let attr = if self.check(&token::Pound) {
-                let prev_outer_attr_sp = outer_attrs.last().map(|attr| attr.span);
+                let prev_outer_attr_sp = outer_attrs.last().map(|attr: &Attribute| attr.span);
 
                 let inner_error_reason = if just_parsed_doc_comment {
                     Some(InnerAttrForbiddenReason::AfterOuterDocComment {
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..a2136399b0c 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -15,7 +15,7 @@ use rustc_ast::visit::{Visitor, walk_expr};
 use rustc_ast::{
     self as ast, AnonConst, Arm, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy,
     ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl, FnRetTy, Label, MacCall,
-    MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, TyKind, UnOp,
+    MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind,
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -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)))
         }
     }
@@ -1928,6 +1931,12 @@ impl<'a> Parser<'a> {
             Ok(match ident.name {
                 sym::offset_of => Some(this.parse_expr_offset_of(lo)?),
                 sym::type_ascribe => Some(this.parse_expr_type_ascribe(lo)?),
+                sym::wrap_binder => {
+                    Some(this.parse_expr_unsafe_binder_cast(lo, UnsafeBinderCastKind::Wrap)?)
+                }
+                sym::unwrap_binder => {
+                    Some(this.parse_expr_unsafe_binder_cast(lo, UnsafeBinderCastKind::Unwrap)?)
+                }
                 _ => None,
             })
         })
@@ -2003,6 +2012,17 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(span, ExprKind::Type(expr, ty)))
     }
 
+    pub(crate) fn parse_expr_unsafe_binder_cast(
+        &mut self,
+        lo: Span,
+        kind: UnsafeBinderCastKind,
+    ) -> PResult<'a, P<Expr>> {
+        let expr = self.parse_expr()?;
+        let ty = if self.eat(&TokenKind::Comma) { Some(self.parse_ty()?) } else { None };
+        let span = lo.to(self.token.span);
+        Ok(self.mk_expr(span, ExprKind::UnsafeBinderCast(kind, expr, ty)))
+    }
+
     /// Returns a string literal if the next token is a string literal.
     /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
     /// and returns `None` if the next token is not literal at all.
@@ -2363,10 +2383,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.
@@ -4016,7 +4033,9 @@ impl MutVisitor for CondChecker<'_> {
                 mut_visit::walk_expr(self, e);
                 self.forbid_let_reason = forbid_let_reason;
             }
-            ExprKind::Cast(ref mut op, _) | ExprKind::Type(ref mut op, _) => {
+            ExprKind::Cast(ref mut op, _)
+            | ExprKind::Type(ref mut op, _)
+            | ExprKind::UnsafeBinderCast(_, ref mut op, _) => {
                 let forbid_let_reason = self.forbid_let_reason;
                 self.forbid_let_reason = Some(OtherForbidden);
                 self.visit_expr(op);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 58b4bf8980b..e27fc963eb9 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -45,7 +45,7 @@ impl<'a> Parser<'a> {
             let (inner_attrs, items, inner_span) =
                 self.parse_mod(&token::CloseDelim(Delimiter::Brace))?;
             attrs.extend(inner_attrs);
-            ModKind::Loaded(items, Inline::Yes, inner_span)
+            ModKind::Loaded(items, Inline::Yes, inner_span, Ok(()))
         };
         Ok((id, ItemKind::Mod(safety, mod_kind)))
     }
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 37556c064d8..976ffe608a2 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -29,9 +29,9 @@ use rustc_ast::tokenstream::{
 };
 use rustc_ast::util::case::Case;
 use rustc_ast::{
-    self as ast, AnonConst, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind,
-    DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered,
-    Safety, StrLit, Visibility, VisibilityKind,
+    self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID,
+    DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit,
+    Visibility, VisibilityKind,
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
@@ -1376,7 +1376,7 @@ impl<'a> Parser<'a> {
             AttrArgs::Delimited(args)
         } else if self.eat(&token::Eq) {
             let eq_span = self.prev_token.span;
-            AttrArgs::Eq { eq_span, value: AttrArgsEq::Ast(self.parse_expr_force_collect()?) }
+            AttrArgs::Eq { eq_span, expr: self.parse_expr_force_collect()? }
         } else {
             AttrArgs::Empty
         })
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_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 8cff23c2e32..f696074e66a 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -5,7 +5,7 @@ use rustc_ast::{
     self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
     GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
     Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
-    TyKind,
+    TyKind, UnsafeBinderTy,
 };
 use rustc_errors::{Applicability, PResult};
 use rustc_span::symbol::{Ident, kw, sym};
@@ -348,6 +348,10 @@ impl<'a> Parser<'a> {
                     TyKind::Err(guar)
                 }
             }
+        } else if self.check_keyword(kw::Unsafe)
+            && self.look_ahead(1, |tok| matches!(tok.kind, token::Lt))
+        {
+            self.parse_unsafe_binder_ty()?
         } else {
             let msg = format!("expected type, found {}", super::token_descr(&self.token));
             let mut err = self.dcx().struct_span_err(lo, msg);
@@ -369,6 +373,19 @@ impl<'a> Parser<'a> {
         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
     }
 
+    fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
+        let lo = self.token.span;
+        assert!(self.eat_keyword(kw::Unsafe));
+        self.expect_lt()?;
+        let generic_params = self.parse_generic_params()?;
+        self.expect_gt()?;
+        let inner_ty = self.parse_ty()?;
+        let span = lo.to(self.prev_token.span);
+        self.psess.gated_spans.gate(sym::unsafe_binders, span);
+
+        Ok(TyKind::UnsafeBinder(P(UnsafeBinderTy { generic_params, inner_ty })))
+    }
+
     /// Parses either:
     /// - `(TYPE)`, a parenthesized type.
     /// - `(TYPE,)`, a tuple with a single field of type TYPE.
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index aab3f10bc66..8b6b37c0f8f 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -3,8 +3,7 @@
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::DelimSpan;
 use rustc_ast::{
-    self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind,
-    Safety,
+    self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety,
 };
 use rustc_errors::{Applicability, FatalError, PResult};
 use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
@@ -70,7 +69,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
                     parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?;
                 MetaItemKind::List(nmis)
             }
-            AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => {
+            AttrArgs::Eq { expr, .. } => {
                 if let ast::ExprKind::Lit(token_lit) = expr.kind {
                     let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span);
                     let res = match res {
@@ -116,9 +115,6 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
                     return Err(err);
                 }
             }
-            AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => {
-                MetaItemKind::NameValue(lit.clone())
-            }
         },
     })
 }
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs
index 4db8584b884..ff3ae65fbea 100644
--- a/compiler/rustc_passes/src/abi_test.rs
+++ b/compiler/rustc_passes/src/abi_test.rs
@@ -1,4 +1,4 @@
-use rustc_ast::Attribute;
+use rustc_hir::Attribute;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::span_bug;
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 074fe77324f..ee197ce07ca 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -7,17 +7,15 @@
 use std::cell::Cell;
 use std::collections::hash_map::Entry;
 
-use rustc_ast::{
-    AttrKind, AttrStyle, Attribute, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast,
-};
+use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
 use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
 use rustc_hir::def_id::LocalModDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{
-    self as hir, self, AssocItemKind, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId,
-    Item, ItemKind, MethodKind, Safety, Target, TraitItem,
+    self as hir, self, AssocItemKind, AttrKind, Attribute, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig,
+    ForeignItem, HirId, Item, ItemKind, MethodKind, Safety, Target, TraitItem,
 };
 use rustc_macros::LintDiagnostic;
 use rustc_middle::hir::nested_filter;
@@ -715,7 +713,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         attrs: &[Attribute],
     ) {
         match target {
-            Target::Fn => {
+            Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
+            | Target::Fn => {
                 // `#[target_feature]` is not allowed in lang items.
                 if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
                     // Calling functions with `#[target_feature]` is
@@ -732,7 +731,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     });
                 }
             }
-            Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {}
             // FIXME: #[target_feature] was previously erroneously allowed on statements and some
             // crates used this, so only emit a warning.
             Target::Statement => {
@@ -1176,10 +1174,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         specified_inline: &mut Option<(bool, Span)>,
         aliases: &mut FxHashMap<String, Span>,
     ) {
-        if let Some(mi) = attr.meta()
-            && let Some(list) = mi.meta_item_list()
-        {
-            for meta in list {
+        if let Some(list) = attr.meta_item_list() {
+            for meta in &list {
                 if let Some(i_meta) = meta.meta_item() {
                     match i_meta.name_or_empty() {
                         sym::alias => {
@@ -1279,7 +1275,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                             AttrStyle::Inner => "!",
                                             AttrStyle::Outer => "",
                                         },
-                                        sugg: (attr.meta().unwrap().span, applicability),
+                                        sugg: (attr.span, applicability),
                                     },
                                 );
                             } else if i_meta.has_name(sym::passes)
@@ -2141,10 +2137,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     fn check_confusables(&self, attr: &Attribute, target: Target) {
         match target {
             Target::Method(MethodKind::Inherent) => {
-                let Some(meta) = attr.meta() else {
-                    return;
-                };
-                let ast::MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else {
+                let Some(metas) = attr.meta_item_list() else {
                     return;
                 };
 
@@ -2602,7 +2595,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
 
                     if let AttrKind::Normal(ref p) = attr.kind {
                         tcx.dcx().try_steal_replace_and_emit_err(
-                            p.item.path.span,
+                            p.path.span,
                             StashKey::UndeterminedMacroResolution,
                             err,
                         );
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index 1c3d3bf3dea..071e537233b 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -9,9 +9,8 @@
 //!
 //! * Compiler internal types like `Ty` and `TyCtxt`
 
-use rustc_ast as ast;
-use rustc_hir::OwnerId;
 use rustc_hir::diagnostic_items::DiagnosticItems;
+use rustc_hir::{Attribute, OwnerId};
 use rustc_middle::query::{LocalCrate, Providers};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
@@ -55,7 +54,7 @@ fn report_duplicate_item(
 }
 
 /// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
-fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
+fn extract(attrs: &[Attribute]) -> Option<Symbol> {
     attrs.iter().find_map(|attr| {
         if attr.has_name(sym::rustc_diagnostic_item) { attr.value_str() } else { None }
     })
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index 76edb51c0bc..a65e91d629f 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -315,9 +315,40 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
 
     fn visit_expr(&mut self, e: &'v hir::Expr<'v>) {
         record_variants!((self, e, e.kind, Some(e.hir_id), hir, Expr, ExprKind), [
-            ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, DropTemps,
-            Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index, Path, AddrOf,
-            Break, Continue, Ret, Become, InlineAsm, OffsetOf, Struct, Repeat, Yield, Err
+            ConstBlock,
+            Array,
+            Call,
+            MethodCall,
+            Tup,
+            Binary,
+            Unary,
+            Lit,
+            Cast,
+            Type,
+            DropTemps,
+            Let,
+            If,
+            Loop,
+            Match,
+            Closure,
+            Block,
+            Assign,
+            AssignOp,
+            Field,
+            Index,
+            Path,
+            AddrOf,
+            Break,
+            Continue,
+            Ret,
+            Become,
+            InlineAsm,
+            OffsetOf,
+            Struct,
+            Repeat,
+            Yield,
+            UnsafeBinderCast,
+            Err
         ]);
         hir_visit::walk_expr(self, e)
     }
@@ -335,10 +366,12 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
             Ptr,
             Ref,
             BareFn,
+            UnsafeBinder,
             Never,
             Tup,
             Path,
             OpaqueDef,
+            TraitAscription,
             TraitObject,
             Typeof,
             Infer,
@@ -467,7 +500,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
         hir_visit::walk_assoc_item_constraint(self, constraint)
     }
 
-    fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
+    fn visit_attribute(&mut self, attr: &'v hir::Attribute) {
         self.record("Attribute", None, attr);
     }
 
@@ -571,7 +604,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
                 If, While, ForLoop, Loop, Match, Closure, Block, Await, TryBlock, Assign,
                 AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret,
                 InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet,
-                Become, IncludedBytes, Gen, Err, Dummy
+                Become, IncludedBytes, Gen, UnsafeBinderCast, Err, Dummy
             ]
         );
         ast_visit::walk_expr(self, e)
@@ -585,6 +618,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
             Ref,
             PinnedRef,
             BareFn,
+            UnsafeBinder,
             Never,
             Tup,
             Path,
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index bb90b5a1e31..dbdc383504c 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -1,5 +1,5 @@
 use rustc_abi::{HasDataLayout, TargetDataLayout};
-use rustc_ast::Attribute;
+use rustc_hir::Attribute;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::span_bug;
diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs
index 8a360c017ad..ec9075bbdee 100644
--- a/compiler/rustc_passes/src/lib_features.rs
+++ b/compiler/rustc_passes/src/lib_features.rs
@@ -4,8 +4,8 @@
 //! but are not declared in one single location (unlike lang features), which means we need to
 //! collect them instead.
 
-use rustc_ast::Attribute;
 use rustc_attr::VERSION_PLACEHOLDER;
+use rustc_hir::Attribute;
 use rustc_hir::intravisit::Visitor;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 09cbb648f9b..034f7308c4a 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -447,6 +447,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
             | hir::ExprKind::InlineAsm(..)
             | hir::ExprKind::OffsetOf(..)
             | hir::ExprKind::Type(..)
+            | hir::ExprKind::UnsafeBinderCast(..)
             | hir::ExprKind::Err(_)
             | hir::ExprKind::Path(hir::QPath::TypeRelative(..))
             | hir::ExprKind::Path(hir::QPath::LangItem(..)) => {}
@@ -1051,6 +1052,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             hir::ExprKind::AddrOf(_, _, ref e)
             | hir::ExprKind::Cast(ref e, _)
             | hir::ExprKind::Type(ref e, _)
+            | hir::ExprKind::UnsafeBinderCast(_, ref e, _)
             | hir::ExprKind::DropTemps(ref e)
             | hir::ExprKind::Unary(_, ref e)
             | hir::ExprKind::Repeat(ref e, _) => self.propagate_through_expr(e, succ),
@@ -1443,6 +1445,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
         | hir::ExprKind::Path(_)
         | hir::ExprKind::Yield(..)
         | hir::ExprKind::Type(..)
+        | hir::ExprKind::UnsafeBinderCast(..)
         | hir::ExprKind::Err(_) => {}
     }
 }
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index b2f8d7dadff..766a9e1bdad 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -186,6 +186,7 @@ impl CheckInlineAssembly {
             | ExprKind::Lit(..)
             | ExprKind::Cast(..)
             | ExprKind::Type(..)
+            | ExprKind::UnsafeBinderCast(..)
             | ExprKind::Loop(..)
             | ExprKind::Match(..)
             | ExprKind::If(..)
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index f72f656b2f8..1b12af62ea5 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -349,9 +349,9 @@ pub(crate) fn create_query_frame<
             hasher.finish::<Hash64>()
         })
     };
-    let ty_def_id = key.ty_def_id();
+    let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle();
 
-    QueryStackFrame::new(description, span, def_id, def_kind, kind, ty_def_id, hash)
+    QueryStackFrame::new(description, span, def_id, def_kind, kind, def_id_for_ty_in_cycle, hash)
 }
 
 pub(crate) fn encode_query_results<'a, 'tcx, Q>(
diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs
index 5a72e80a0a5..480fd497728 100644
--- a/compiler/rustc_query_system/src/ich/impls_syntax.rs
+++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs
@@ -1,18 +1,17 @@
 //! This module contains `HashStable` implementations for various data types
-//! from `rustc_ast` in no particular order.
+//! from various crates in no particular order.
 
-use std::assert_matches::assert_matches;
-
-use rustc_ast as ast;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_hir as hir;
 use rustc_span::SourceFile;
 use smallvec::SmallVec;
 
 use crate::ich::StableHashingContext;
 
 impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
+impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {}
 
-impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
+impl<'a> HashStable<StableHashingContext<'a>> for [hir::Attribute] {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         if self.is_empty() {
             self.len().hash_stable(hcx, hasher);
@@ -20,7 +19,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
         }
 
         // Some attributes are always ignored during hashing.
-        let filtered: SmallVec<[&ast::Attribute; 8]> = self
+        let filtered: SmallVec<[&hir::Attribute; 8]> = self
             .iter()
             .filter(|attr| {
                 !attr.is_doc_comment()
@@ -35,30 +34,23 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
     }
 }
 
-impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
-    fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
+impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
+    fn hash_attr(&mut self, attr: &hir::Attribute, hasher: &mut StableHasher) {
         // Make sure that these have been filtered out.
         debug_assert!(!attr.ident().is_some_and(|ident| self.is_ignored_attr(ident.name)));
         debug_assert!(!attr.is_doc_comment());
 
-        let ast::Attribute { kind, id: _, style, span } = attr;
-        if let ast::AttrKind::Normal(normal) = kind {
-            normal.item.hash_stable(self, hasher);
+        let hir::Attribute { kind, id: _, style, span } = attr;
+        if let hir::AttrKind::Normal(item) = kind {
+            item.hash_stable(self, hasher);
             style.hash_stable(self, hasher);
             span.hash_stable(self, hasher);
-            assert_matches!(
-                normal.tokens.as_ref(),
-                None,
-                "Tokens should have been removed during lowering!"
-            );
         } else {
             unreachable!();
         }
     }
 }
 
-impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {}
-
 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         let SourceFile {
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index b81386f06ec..82c51193a19 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -33,7 +33,7 @@ pub struct QueryStackFrame {
     pub def_id: Option<DefId>,
     pub def_kind: Option<DefKind>,
     /// A def-id that is extracted from a `Ty` in a query key
-    pub ty_def_id: Option<DefId>,
+    pub def_id_for_ty_in_cycle: Option<DefId>,
     pub dep_kind: DepKind,
     /// This hash is used to deterministically pick
     /// a query to remove cycles in the parallel compiler.
@@ -48,10 +48,10 @@ impl QueryStackFrame {
         def_id: Option<DefId>,
         def_kind: Option<DefKind>,
         dep_kind: DepKind,
-        ty_def_id: Option<DefId>,
+        def_id_for_ty_in_cycle: Option<DefId>,
         hash: impl FnOnce() -> Hash64,
     ) -> Self {
-        Self { description, span, def_id, def_kind, ty_def_id, dep_kind, hash: hash() }
+        Self { description, span, def_id, def_kind, def_id_for_ty_in_cycle, dep_kind, hash: hash() }
     }
 
     // FIXME(eddyb) Get more valid `Span`s on queries.
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 293cee500bb..924b8afa329 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -770,7 +770,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 );
             }
 
-            ItemKind::Mod(..) => {
+            ItemKind::Mod(.., ref mod_kind) => {
                 let module = self.r.new_module(
                     Some(parent),
                     ModuleKind::Def(def_kind, def_id, ident.name),
@@ -781,6 +781,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 );
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
 
+                if let ast::ModKind::Loaded(_, _, _, Err(_)) = mod_kind {
+                    self.r.mods_with_parse_errors.insert(def_id);
+                }
+
                 // Descend into the module.
                 self.parent_scope.module = module;
             }
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 66492842581..ec442e22204 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -356,6 +356,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
                 let kind = match self.impl_trait_context {
                     ImplTraitContext::Universal => DefKind::TyParam,
                     ImplTraitContext::Existential => DefKind::OpaqueTy,
+                    ImplTraitContext::InBinding => return visit::walk_ty(self, ty),
                 };
                 let id = self.create_def(*id, name, kind, ty.span);
                 match self.impl_trait_context {
@@ -365,6 +366,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
                     ImplTraitContext::Existential => {
                         self.with_parent(id, |this| visit::walk_ty(this, ty))
                     }
+                    ImplTraitContext::InBinding => unreachable!(),
                 };
             }
             _ => visit::walk_ty(self, ty),
@@ -374,6 +376,13 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
     fn visit_stmt(&mut self, stmt: &'a Stmt) {
         match stmt.kind {
             StmtKind::MacCall(..) => self.visit_macro_invoc(stmt.id),
+            // FIXME(impl_trait_in_bindings): We don't really have a good way of
+            // introducing the right `ImplTraitContext` here for all the cases we
+            // care about, in case we want to introduce ITIB to other positions
+            // such as turbofishes (e.g. `foo::<impl Fn()>(|| {})`).
+            StmtKind::Let(ref local) => self.with_impl_trait(ImplTraitContext::InBinding, |this| {
+                visit::walk_local(this, local)
+            }),
             _ => visit::walk_stmt(self, stmt),
         }
     }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 4c76617a391..368eb3c26c7 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -3056,7 +3056,7 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
 
     fn visit_item(&mut self, item: &'tcx ast::Item) {
         if self.target_module == item.id {
-            if let ItemKind::Mod(_, ModKind::Loaded(items, _inline, mod_spans)) = &item.kind {
+            if let ItemKind::Mod(_, ModKind::Loaded(items, _inline, mod_spans, _)) = &item.kind {
                 let inject = mod_spans.inject_use_span;
                 if is_span_suitable_for_use_injection(inject) {
                     self.first_legal_span = Some(inject);
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 466e190028a..5906a682f3e 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1428,6 +1428,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         ignore_import: Option<Import<'ra>>,
     ) -> PathResult<'ra> {
         let mut module = None;
+        let mut module_had_parse_errors = false;
         let mut allow_super = true;
         let mut second_binding = None;
 
@@ -1471,9 +1472,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                             continue;
                         }
                     }
-                    return PathResult::failed(ident, false, finalize.is_some(), module, || {
-                        ("there are too many leading `super` keywords".to_string(), None)
-                    });
+                    return PathResult::failed(
+                        ident,
+                        false,
+                        finalize.is_some(),
+                        module_had_parse_errors,
+                        module,
+                        || ("there are too many leading `super` keywords".to_string(), None),
+                    );
                 }
                 if segment_idx == 0 {
                     if name == kw::SelfLower {
@@ -1511,19 +1517,26 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
             // Report special messages for path segment keywords in wrong positions.
             if ident.is_path_segment_keyword() && segment_idx != 0 {
-                return PathResult::failed(ident, false, finalize.is_some(), module, || {
-                    let name_str = if name == kw::PathRoot {
-                        "crate root".to_string()
-                    } else {
-                        format!("`{name}`")
-                    };
-                    let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
-                        format!("global paths cannot start with {name_str}")
-                    } else {
-                        format!("{name_str} in paths can only be used in start position")
-                    };
-                    (label, None)
-                });
+                return PathResult::failed(
+                    ident,
+                    false,
+                    finalize.is_some(),
+                    module_had_parse_errors,
+                    module,
+                    || {
+                        let name_str = if name == kw::PathRoot {
+                            "crate root".to_string()
+                        } else {
+                            format!("`{name}`")
+                        };
+                        let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
+                            format!("global paths cannot start with {name_str}")
+                        } else {
+                            format!("{name_str} in paths can only be used in start position")
+                        };
+                        (label, None)
+                    },
+                );
             }
 
             let binding = if let Some(module) = module {
@@ -1589,6 +1602,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
                     let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
                     if let Some(next_module) = binding.module() {
+                        if self.mods_with_parse_errors.contains(&next_module.def_id()) {
+                            module_had_parse_errors = true;
+                        }
                         module = Some(ModuleOrUniformRoot::Module(next_module));
                         record_segment_res(self, res);
                     } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
@@ -1614,6 +1630,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                             ident,
                             is_last,
                             finalize.is_some(),
+                            module_had_parse_errors,
                             module,
                             || {
                                 let label = format!(
@@ -1637,19 +1654,26 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         }
                     }
 
-                    return PathResult::failed(ident, is_last, finalize.is_some(), module, || {
-                        self.report_path_resolution_error(
-                            path,
-                            opt_ns,
-                            parent_scope,
-                            ribs,
-                            ignore_binding,
-                            ignore_import,
-                            module,
-                            segment_idx,
-                            ident,
-                        )
-                    });
+                    return PathResult::failed(
+                        ident,
+                        is_last,
+                        finalize.is_some(),
+                        module_had_parse_errors,
+                        module,
+                        || {
+                            self.report_path_resolution_error(
+                                path,
+                                opt_ns,
+                                parent_scope,
+                                ribs,
+                                ignore_binding,
+                                ignore_import,
+                                module,
+                                segment_idx,
+                                ident,
+                            )
+                        },
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 51fbcb8ebb8..2ed3f4d2c4f 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -670,9 +670,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
     fn throw_unresolved_import_error(
         &mut self,
-        errors: Vec<(Import<'_>, UnresolvedImportError)>,
+        mut errors: Vec<(Import<'_>, UnresolvedImportError)>,
         glob_error: bool,
     ) {
+        errors.retain(|(_import, err)| match err.module {
+            // Skip `use` errors for `use foo::Bar;` if `foo.rs` has unrecovered parse errors.
+            Some(def_id) if self.mods_with_parse_errors.contains(&def_id) => false,
+            _ => true,
+        });
         if errors.is_empty() {
             return;
         }
@@ -898,6 +903,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 label,
                 suggestion,
                 module,
+                error_implied_by_parse_error: _,
             } => {
                 if no_ambiguity {
                     assert!(import.imported_module.get().is_none());
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 4e57154ff2b..61be85d2dff 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -894,6 +894,28 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
                     },
                 )
             }
+            TyKind::UnsafeBinder(unsafe_binder) => {
+                // FIXME(unsafe_binder): Better span
+                let span = ty.span;
+                self.with_generic_param_rib(
+                    &unsafe_binder.generic_params,
+                    RibKind::Normal,
+                    LifetimeRibKind::Generics {
+                        binder: ty.id,
+                        kind: LifetimeBinderKind::BareFnType,
+                        span,
+                    },
+                    |this| {
+                        this.visit_generic_params(&unsafe_binder.generic_params, false);
+                        this.with_lifetime_rib(
+                            // We don't allow anonymous `unsafe &'_ ()` binders,
+                            // although I guess we could.
+                            LifetimeRibKind::AnonymousReportError,
+                            |this| this.visit_ty(&unsafe_binder.inner_ty),
+                        );
+                    },
+                )
+            }
             TyKind::Array(element_ty, length) => {
                 self.visit_ty(element_ty);
                 self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
@@ -4427,6 +4449,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => {
                 PartialRes::new(module.res().unwrap())
             }
+            // A part of this path references a `mod` that had a parse error. To avoid resolution
+            // errors for each reference to that module, we don't emit an error for them until the
+            // `mod` is fixed. this can have a significant cascade effect.
+            PathResult::Failed { error_implied_by_parse_error: true, .. } => {
+                PartialRes::new(Res::Err)
+            }
             // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
             // don't report an error right away, but try to fallback to a primitive type.
             // So, we are still able to successfully resolve something like
@@ -4475,6 +4503,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 suggestion,
                 module,
                 segment_name,
+                error_implied_by_parse_error: _,
             } => {
                 return Err(respan(span, ResolutionError::FailedToResolve {
                     segment: Some(segment_name),
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index ca4adce37ce..5c4c401af31 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -190,6 +190,7 @@ impl InvocationParent {
 enum ImplTraitContext {
     Existential,
     Universal,
+    InBinding,
 }
 
 /// Used for tracking import use types which will be used for redundant import checking.
@@ -450,6 +451,7 @@ enum PathResult<'ra> {
         module: Option<ModuleOrUniformRoot<'ra>>,
         /// The segment name of target
         segment_name: Symbol,
+        error_implied_by_parse_error: bool,
     },
 }
 
@@ -458,6 +460,7 @@ impl<'ra> PathResult<'ra> {
         ident: Ident,
         is_error_from_last_segment: bool,
         finalize: bool,
+        error_implied_by_parse_error: bool,
         module: Option<ModuleOrUniformRoot<'ra>>,
         label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>),
     ) -> PathResult<'ra> {
@@ -470,6 +473,7 @@ impl<'ra> PathResult<'ra> {
             suggestion,
             is_error_from_last_segment,
             module,
+            error_implied_by_parse_error,
         }
     }
 }
@@ -1198,6 +1202,8 @@ pub struct Resolver<'ra, 'tcx> {
     /// This is the `Span` where an `extern crate foo;` suggestion would be inserted, if `foo`
     /// could be a crate that wasn't imported. For diagnostics use only.
     current_crate_outer_attr_insert_span: Span,
+
+    mods_with_parse_errors: FxHashSet<DefId>,
 }
 
 /// This provides memory for the rest of the crate. The `'ra` lifetime that is
@@ -1543,6 +1549,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             impl_unexpanded_invocations: Default::default(),
             impl_binding_keys: Default::default(),
             current_crate_outer_attr_insert_span,
+            mods_with_parse_errors: Default::default(),
         };
 
         let root_parent_scope = ParentScope::module(graph_root, &resolver);
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 0b4d0e04c29..6e2af9aae23 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -7,7 +7,7 @@ use std::mem;
 use rustc_ast::expand::StrippedCfgItem;
 use rustc_ast::{self as ast, Crate, Inline, ItemKind, ModKind, NodeId, attr};
 use rustc_ast_pretty::pprust;
-use rustc_attr::StabilityLevel;
+use rustc_attr::{AttributeExt, StabilityLevel};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, StashKey};
@@ -166,7 +166,7 @@ fn soft_custom_inner_attributes_gate(path: &ast::Path, invoc: &Invocation) -> bo
         [seg1, seg2] if seg1.ident.name == sym::rustfmt && seg2.ident.name == sym::skip => {
             if let InvocationKind::Attr { item, .. } = &invoc.kind {
                 if let Annotatable::Item(item) = item {
-                    if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, _)) = item.kind {
+                    if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, _, _)) = item.kind {
                         return true;
                     }
                 }
@@ -1126,7 +1126,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         &mut self,
         macro_def: &ast::MacroDef,
         ident: Ident,
-        attrs: &[ast::Attribute],
+        attrs: &[impl AttributeExt],
         span: Span,
         node_id: NodeId,
         edition: Edition,
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 65128ceb866..8b14fe31d8c 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -6,6 +6,7 @@ use pulldown_cmark::{
 };
 use rustc_ast as ast;
 use rustc_ast::util::comments::beautify_doc_string;
+use rustc_attr::AttributeExt;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::DefId;
@@ -192,19 +193,24 @@ pub fn add_doc_fragment(out: &mut String, frag: &DocFragment) {
     }
 }
 
-pub fn attrs_to_doc_fragments<'a>(
-    attrs: impl Iterator<Item = (&'a ast::Attribute, Option<DefId>)>,
+pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>(
+    attrs: impl Iterator<Item = (&'a A, Option<DefId>)>,
     doc_only: bool,
-) -> (Vec<DocFragment>, ast::AttrVec) {
+) -> (Vec<DocFragment>, Vec<A>) {
     let mut doc_fragments = Vec::new();
-    let mut other_attrs = ast::AttrVec::new();
+    let mut other_attrs = Vec::<A>::new();
     for (attr, item_id) in attrs {
         if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
             let doc = beautify_doc_string(doc_str, comment_kind);
             let (span, kind) = if attr.is_doc_comment() {
-                (attr.span, DocFragmentKind::SugaredDoc)
+                (attr.span(), DocFragmentKind::SugaredDoc)
             } else {
-                (span_for_value(attr), DocFragmentKind::RawDoc)
+                (
+                    attr.value_span()
+                        .map(|i| i.with_ctxt(attr.span().ctxt()))
+                        .unwrap_or(attr.span()),
+                    DocFragmentKind::RawDoc,
+                )
             };
             let fragment = DocFragment { span, doc, kind, item_id, indent: 0 };
             doc_fragments.push(fragment);
@@ -218,16 +224,6 @@ pub fn attrs_to_doc_fragments<'a>(
     (doc_fragments, other_attrs)
 }
 
-fn span_for_value(attr: &ast::Attribute) -> Span {
-    if let ast::AttrKind::Normal(normal) = &attr.kind
-        && let ast::AttrArgs::Eq { value, .. } = &normal.item.args
-    {
-        value.span().with_ctxt(attr.span.ctxt())
-    } else {
-        attr.span
-    }
-}
-
 /// Return the doc-comments on this item, grouped by the module they came from.
 /// The module can be different if this is a re-export with added documentation.
 ///
@@ -353,12 +349,15 @@ pub fn strip_generics_from_path(path_str: &str) -> Result<Box<str>, MalformedGen
 ///
 //// If there are no doc-comments, return true.
 /// FIXME(#78591): Support both inner and outer attributes on the same item.
-pub fn inner_docs(attrs: &[ast::Attribute]) -> bool {
-    attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner)
+pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool {
+    attrs
+        .iter()
+        .find(|a| a.doc_str().is_some())
+        .map_or(true, |a| a.style() == ast::AttrStyle::Inner)
 }
 
 /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`.
-pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool {
+pub fn has_primitive_or_keyword_docs(attrs: &[impl AttributeExt]) -> bool {
     for attr in attrs {
         if attr.has_name(sym::rustc_doc_primitive) {
             return true;
@@ -408,7 +407,7 @@ pub fn may_be_doc_link(link_type: LinkType) -> bool {
 
 /// Simplified version of `preprocessed_markdown_links` from rustdoc.
 /// Must return at least the same links as it, but may add some more links on top of that.
-pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<Box<str>> {
+pub(crate) fn attrs_to_preprocessed_links<A: AttributeExt + Clone>(attrs: &[A]) -> Vec<Box<str>> {
     let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
     let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
 
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index cb6d539cdf9..936c2ca87d6 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -472,6 +472,13 @@ impl ToString for DebugInfoCompression {
     }
 }
 
+#[derive(Clone, Copy, Debug, PartialEq, Hash)]
+pub enum MirStripDebugInfo {
+    None,
+    LocalsInTinyFunctions,
+    AllLocals,
+}
+
 /// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split
 /// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform
 /// uses DWARF for debug-information.
@@ -2900,10 +2907,10 @@ pub(crate) mod dep_tracking {
         BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
         CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
         InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
-        LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
-        PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks,
-        SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
-        WasiExecModel,
+        LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel, OutFileName,
+        OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents,
+        ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
+        SymbolManglingVersion, WasiExecModel,
     };
     use crate::lint;
     use crate::utils::NativeLib;
@@ -2971,6 +2978,7 @@ pub(crate) mod dep_tracking {
         LtoCli,
         DebugInfo,
         DebugInfoCompression,
+        MirStripDebugInfo,
         CollapseMacroDebuginfo,
         UnstableFeatures,
         NativeLib,
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs
index 99d9d5b7665..43cf1324edd 100644
--- a/compiler/rustc_session/src/config/cfg.rs
+++ b/compiler/rustc_session/src/config/cfg.rs
@@ -371,7 +371,7 @@ impl CheckCfg {
 
         ins!(sym::target_feature, empty_values).extend(
             rustc_target::target_features::all_rust_features()
-                .filter(|(_, s)| s.is_supported())
+                .filter(|(_, s)| s.in_cfg())
                 .map(|(f, _s)| f)
                 .chain(rustc_target::target_features::RUSTC_SPECIFIC_FEATURES.iter().cloned())
                 .map(Symbol::intern),
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index b01d9e5e8e3..3873a203bd3 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -391,6 +391,8 @@ mod desc {
     pub(crate) const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
     pub(crate) const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
     pub(crate) const parse_debuginfo_compression: &str = "one of `none`, `zlib`, or `zstd`";
+    pub(crate) const parse_mir_strip_debuginfo: &str =
+        "one of `none`, `locals-in-tiny-functions`, or `all-locals`";
     pub(crate) const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`";
     pub(crate) const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
     pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
@@ -925,6 +927,16 @@ pub mod parse {
         true
     }
 
+    pub(crate) fn parse_mir_strip_debuginfo(slot: &mut MirStripDebugInfo, v: Option<&str>) -> bool {
+        match v {
+            Some("none") => *slot = MirStripDebugInfo::None,
+            Some("locals-in-tiny-functions") => *slot = MirStripDebugInfo::LocalsInTinyFunctions,
+            Some("all-locals") => *slot = MirStripDebugInfo::AllLocals,
+            _ => return false,
+        };
+        true
+    }
+
     pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
         match v.and_then(LinkerFlavorCli::from_str) {
             Some(lf) => *slot = Some(lf),
@@ -1893,6 +1905,8 @@ options! {
     #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")]
     mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
         "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
+    mir_strip_debuginfo: MirStripDebugInfo = (MirStripDebugInfo::None, parse_mir_strip_debuginfo, [TRACKED],
+        "Whether to remove some of the MIR debug info from methods.  Default: None"),
     move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
         "the size at which the `large_assignments` lint starts to be emitted"),
     mutable_noalias: bool = (true, parse_bool, [TRACKED],
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 993d111466b..9f6106f9cfb 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -8,7 +8,6 @@ use std::{env, fmt, io};
 
 use rustc_data_structures::flock;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
-use rustc_data_structures::jobserver::{self, Client};
 use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
 use rustc_data_structures::sync::{
     DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock,
@@ -154,16 +153,9 @@ pub struct Session {
     /// Data about code being compiled, gathered during compilation.
     pub code_stats: CodeStats,
 
-    /// Loaded up early on in the initialization of this `Session` to avoid
-    /// false positives about a job server in our environment.
-    pub jobserver: Client,
-
     /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
     pub lint_store: Option<Lrc<dyn LintStoreMarker>>,
 
-    /// Should be set if any lints are registered in `lint_store`.
-    pub registered_lints: bool,
-
     /// Cap lint level specified by a driver specifically.
     pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
 
@@ -1072,9 +1064,7 @@ pub fn build_session(
         incr_comp_session: RwLock::new(IncrCompSession::NotInitialized),
         prof,
         code_stats: Default::default(),
-        jobserver: jobserver::client(),
         lint_store: None,
-        registered_lints: false,
         driver_lint_caps,
         ctfe_backtrace,
         miri_unleashed_features: Lock::new(Default::default()),
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index 1230667ee91..29ce24e8b78 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -7,9 +7,9 @@ edition = "2021"
 # tidy-alphabetical-start
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
-rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_hir = { path = "../rustc_hir" }
+rustc_hir_pretty = { path = "../rustc_hir_pretty" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index dec2a77619b..c465367b6b9 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -141,6 +141,10 @@ impl RustcInternal for RigidTy {
             RigidTy::Coroutine(def, args, _mov) => {
                 rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx))
             }
+            RigidTy::CoroutineClosure(def, args) => rustc_ty::TyKind::CoroutineClosure(
+                def.0.internal(tables, tcx),
+                args.internal(tables, tcx),
+            ),
             RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness(
                 def.0.internal(tables, tcx),
                 args.internal(tables, tcx),
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 614c9169d66..64d241067a8 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -107,6 +107,10 @@ impl<'tcx> Tables<'tcx> {
         stable_mir::ty::CoroutineDef(self.create_def_id(did))
     }
 
+    pub fn coroutine_closure_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineClosureDef {
+        stable_mir::ty::CoroutineClosureDef(self.create_def_id(did))
+    }
+
     pub fn alias_def(&mut self, did: DefId) -> stable_mir::ty::AliasDef {
         stable_mir::ty::AliasDef(self.create_def_id(did))
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index 9025b47c422..4b172517fd5 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -255,7 +255,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
             attr.iter().map(|seg| rustc_span::symbol::Symbol::intern(&seg)).collect();
         tcx.get_attrs_by_path(did, &attr_name)
             .map(|attribute| {
-                let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute);
+                let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
                 let span = attribute.span;
                 stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
             })
@@ -266,17 +266,16 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         let mut tables = self.0.borrow_mut();
         let tcx = tables.tcx;
         let did = tables[def_id];
-        let filter_fn = move |a: &&rustc_ast::ast::Attribute| {
-            matches!(a.kind, rustc_ast::ast::AttrKind::Normal(_))
-        };
+        let filter_fn =
+            move |a: &&rustc_hir::Attribute| matches!(a.kind, rustc_hir::AttrKind::Normal(_));
         let attrs_iter = if let Some(did) = did.as_local() {
             tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
         } else {
-            tcx.item_attrs(did).iter().filter(filter_fn)
+            tcx.attrs_for_def(did).iter().filter(filter_fn)
         };
         attrs_iter
             .map(|attribute| {
-                let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute);
+                let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
                 let span = attribute.span;
                 stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
             })
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index fcdf8703b14..a5a17b4b573 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -565,8 +565,11 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
                     tables.tcx.coroutine_movability(*def_id).stable(tables),
                 )
             }
-            mir::AggregateKind::CoroutineClosure(..) => {
-                todo!("FIXME(async_closures): Lower these to SMIR")
+            mir::AggregateKind::CoroutineClosure(def_id, generic_args) => {
+                stable_mir::mir::AggregateKind::CoroutineClosure(
+                    tables.coroutine_closure_def(*def_id),
+                    generic_args.stable(tables),
+                )
             }
             mir::AggregateKind::RawPtr(ty, mutability) => {
                 stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))
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/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index a5826137181..3cdae437b7d 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1163,6 +1163,9 @@ pub enum DesugaringKind {
     WhileLoop,
     /// `async Fn()` bound modifier
     BoundModifier,
+    /// Marks a `&raw const *_1` needed as part of getting the length of a mutable
+    /// slice for the bounds check, so that MIRI's retag handling can recognize it.
+    IndexBoundsCheckReborrow,
 }
 
 impl DesugaringKind {
@@ -1179,6 +1182,7 @@ impl DesugaringKind {
             DesugaringKind::ForLoop => "`for` loop",
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
+            DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
         }
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 958d4f0c251..6e25de847fc 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -25,7 +25,6 @@
 #![feature(hash_set_entry)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(read_buf)]
 #![feature(round_char_boundary)]
@@ -523,6 +522,12 @@ impl SpanData {
     }
 }
 
+impl Default for SpanData {
+    fn default() -> Self {
+        Self { lo: BytePos(0), hi: BytePos(0), ctxt: SyntaxContext::root(), parent: None }
+    }
+}
+
 impl PartialOrd for Span {
     fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
         PartialOrd::partial_cmp(&self.data(), &rhs.data())
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d30b17c9cd8..c62e609c8a9 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,
@@ -1189,6 +1190,7 @@ symbols! {
         loongarch_target_feature,
         loop_break_value,
         lt,
+        m68k_target_feature,
         macro_at_most_once_rep,
         macro_attributes_in_derive_output,
         macro_escape,
@@ -2104,6 +2106,7 @@ symbols! {
         unreachable_macro,
         unrestricted_attribute_tokens,
         unsafe_attributes,
+        unsafe_binders,
         unsafe_block_in_unsafe_fn,
         unsafe_cell,
         unsafe_cell_raw_get,
@@ -2127,6 +2130,7 @@ symbols! {
         unwind_attributes,
         unwind_safe_trait,
         unwrap,
+        unwrap_binder,
         unwrap_or,
         use_extern_macros,
         use_nested_groups,
@@ -2185,6 +2189,7 @@ symbols! {
         windows,
         windows_subsystem,
         with_negative_coherence,
+        wrap_binder,
         wrapping_add,
         wrapping_div,
         wrapping_mul,
@@ -2200,6 +2205,7 @@ symbols! {
         writeln_macro,
         x86_amx_intrinsics,
         x87_reg,
+        x87_target_feature,
         xer,
         xmm_reg,
         xop_target_feature,
@@ -2471,13 +2477,6 @@ impl fmt::Display for Symbol {
     }
 }
 
-// takes advantage of `str::to_string` specialization
-impl ToString for Symbol {
-    fn to_string(&self) -> String {
-        self.as_str().to_string()
-    }
-}
-
 impl<CTX> HashStable<CTX> for Symbol {
     #[inline]
     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 59ccd6dff85..0d6d8488a23 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -2,7 +2,7 @@ use std::fmt::{self, Write};
 use std::mem::{self, discriminant};
 
 use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
-use rustc_hir::def_id::CrateNum;
+use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_middle::bug;
 use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
@@ -378,6 +378,33 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
             Ok(())
         }
     }
+
+    fn print_impl_path(
+        &mut self,
+        impl_def_id: DefId,
+        args: &'tcx [GenericArg<'tcx>],
+        mut self_ty: Ty<'tcx>,
+        mut impl_trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<(), PrintError> {
+        let mut typing_env = ty::TypingEnv::post_analysis(self.tcx, impl_def_id);
+        if !args.is_empty() {
+            typing_env.param_env =
+                ty::EarlyBinder::bind(typing_env.param_env).instantiate(self.tcx, args);
+        }
+
+        match &mut impl_trait_ref {
+            Some(impl_trait_ref) => {
+                assert_eq!(impl_trait_ref.self_ty(), self_ty);
+                *impl_trait_ref = self.tcx.normalize_erasing_regions(typing_env, *impl_trait_ref);
+                self_ty = impl_trait_ref.self_ty();
+            }
+            None => {
+                self_ty = self.tcx.normalize_erasing_regions(typing_env, self_ty);
+            }
+        }
+
+        self.default_print_impl_path(impl_def_id, args, self_ty, impl_trait_ref)
+    }
 }
 
 impl<'tcx> PrettyPrinter<'tcx> for SymbolPrinter<'tcx> {
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index def741e3546..4f568a20332 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -439,7 +439,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 let sig = sig_tys.with(hdr);
                 self.push("F");
                 self.in_binder(&sig, |cx, sig| {
-                    if sig.safety == hir::Safety::Unsafe {
+                    if sig.safety.is_unsafe() {
                         cx.push("U");
                     }
                     match sig.abi {
diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs
index 71e533b8cc5..3a71592cbe0 100644
--- a/compiler/rustc_target/src/callconv/powerpc64.rs
+++ b/compiler/rustc_target/src/callconv/powerpc64.rs
@@ -99,7 +99,7 @@ where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
 {
-    let abi = if cx.target_spec().env == "musl" {
+    let abi = if cx.target_spec().env == "musl" || cx.target_spec().os == "freebsd" {
         ELFv2
     } else if cx.target_spec().os == "aix" {
         AIX
diff --git a/compiler/rustc_target/src/spec/base/linux_musl.rs b/compiler/rustc_target/src/spec/base/linux_musl.rs
index e020bb85238..1a854fe362d 100644
--- a/compiler/rustc_target/src/spec/base/linux_musl.rs
+++ b/compiler/rustc_target/src/spec/base/linux_musl.rs
@@ -8,8 +8,5 @@ pub(crate) fn opts() -> TargetOptions {
     base.post_link_objects_self_contained = crt_objects::post_musl_self_contained();
     base.link_self_contained = LinkSelfContainedDefault::InferredForMusl;
 
-    // These targets statically link libc by default
-    base.crt_static_default = true;
-
     base
 }
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/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 210d67fa1aa..a44d2af6b90 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2213,6 +2213,10 @@ pub struct TargetOptions {
     /// `-Ctarget-cpu` but can be overwritten with `-Ctarget-features`.
     /// Corresponds to `llc -mattr=$features`.
     /// Note that these are LLVM feature names, not Rust feature names!
+    ///
+    /// Generally it is a bad idea to use negative target features because they often interact very
+    /// poorly with how `-Ctarget-cpu` works. Instead, try to use a lower "base CPU" and enable the
+    /// features you want to use.
     pub features: StaticCow<str>,
     /// Direct or use GOT indirect to reference external data symbols
     pub direct_access_external_data: Option<bool>,
@@ -2603,6 +2607,14 @@ impl TargetOptions {
                 .collect();
         }
     }
+
+    pub(crate) fn has_feature(&self, search_feature: &str) -> bool {
+        self.features.split(',').any(|f| f.strip_prefix('+').is_some_and(|f| f == search_feature))
+    }
+
+    pub(crate) fn has_neg_feature(&self, search_feature: &str) -> bool {
+        self.features.split(',').any(|f| f.strip_prefix('-').is_some_and(|f| f == search_feature))
+    }
 }
 
 impl Default for TargetOptions {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs
index bb65048a56d..4fefdfa5c5e 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs
@@ -12,6 +12,9 @@ pub(crate) fn target() -> Target {
         | SanitizerSet::MEMORY
         | SanitizerSet::THREAD;
 
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
+
     Target {
         llvm_target: "aarch64-unknown-linux-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs
index b96d8455a5b..416bb5432fd 100644
--- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs
@@ -22,6 +22,8 @@ pub(crate) fn target() -> Target {
             features: "+strict-align,+v6".into(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".into(),
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs
index 3418a7090d3..909eb78f698 100644
--- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs
@@ -22,6 +22,8 @@ pub(crate) fn target() -> Target {
             features: "+strict-align,+v6,+vfp2,-d32".into(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".into(),
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs
index 1bcd090b9f2..5e3ad42e5a4 100644
--- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs
@@ -23,6 +23,8 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(32),
             mcount: "\u{1}mcount".into(),
             has_thumb_interworking: true,
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs
index 16923497325..843adcfc711 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs
@@ -26,6 +26,8 @@ pub(crate) fn target() -> Target {
             features: "+v7,+thumb2,+soft-float,-neon".into(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".into(),
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs
index 5adfa0bc2f8..e0630817bc3 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs
@@ -25,6 +25,8 @@ pub(crate) fn target() -> Target {
             features: "+v7,+vfp3,-d32,+thumb2,-neon".into(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".into(),
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs
index 623422a89ea..8ad93496f3a 100644
--- a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs
@@ -4,5 +4,7 @@ pub(crate) fn target() -> Target {
     let mut base = super::i686_unknown_linux_musl::target();
     base.cpu = "pentium".into();
     base.llvm_target = "i586-unknown-linux-musl".into();
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
     base
 }
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs
index b805b80b85b..6ba87c732b7 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs
@@ -6,6 +6,8 @@ pub(crate) fn target() -> Target {
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]);
     base.stack_probes = StackProbeType::Inline;
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
 
     // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind
     // implementation, apparently relies on frame pointers existing... somehow.
diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
index cc288e042d9..bddcc457498 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
@@ -8,7 +8,6 @@ pub(crate) fn target() -> Target {
     base.cpu = "mips64r2".into();
     base.features = "+mips64r2,+soft-float".into();
     base.max_atomic_width = Some(64);
-    base.crt_static_default = false;
 
     Target {
         // LLVM doesn't recognize "muslabi64" yet.
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
index 69af2da1100..32f5c79d653 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
@@ -22,6 +22,8 @@ pub(crate) fn target() -> Target {
             abi: "abi64".into(),
             endian: Endian::Big,
             mcount: "_mcount".into(),
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
index 4f50e8b7033..5e7c37fd46c 100644
--- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
@@ -5,6 +5,8 @@ pub(crate) fn target() -> Target {
     base.cpu = "mips64r2".into();
     base.features = "+mips64r2".into();
     base.max_atomic_width = Some(64);
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
     Target {
         // LLVM doesn't recognize "muslabi64" yet.
         llvm_target: "mips64el-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
index b283b3b1ef7..5076ae345a9 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
@@ -6,7 +6,6 @@ pub(crate) fn target() -> Target {
     base.cpu = "mips32r2".into();
     base.features = "+mips32r2,+soft-float".into();
     base.max_atomic_width = Some(32);
-    base.crt_static_default = false;
     Target {
         llvm_target: "mips-unknown-linux-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs
index 744396aa1ba..339b32b6339 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs
@@ -5,7 +5,6 @@ pub(crate) fn target() -> Target {
     base.cpu = "mips32r2".into();
     base.features = "+mips32r2,+soft-float".into();
     base.max_atomic_width = Some(32);
-    base.crt_static_default = false;
     Target {
         llvm_target: "mipsel-unknown-linux-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
index 68a3718035c..4ccb3ee4664 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
@@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
     Target {
         llvm_target: "powerpc64-unknown-freebsd".into(),
         metadata: crate::spec::TargetMetadata {
-            description: Some("PPC64 FreeBSD (ELFv1 and ELFv2)".into()),
+            description: Some("PPC64 FreeBSD (ELFv2)".into()),
             tier: Some(3),
             host_tools: Some(true),
             std: Some(true),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
index a964f417799..a54b17c87a7 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
@@ -7,6 +7,8 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
     base.max_atomic_width = Some(64);
     base.stack_probes = StackProbeType::Inline;
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc64-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs
index 04fe5f9af33..952a00c52a2 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs
@@ -6,6 +6,8 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
     base.max_atomic_width = Some(64);
     base.stack_probes = StackProbeType::Inline;
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc64le-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
index 5372a83e29a..0cd0ea96ad3 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
@@ -6,6 +6,8 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
     base.max_atomic_width = Some(32);
     base.stack_probes = StackProbeType::Inline;
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
index 2305db81c5e..b86c3c2e8e0 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
@@ -6,6 +6,8 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe"]);
     base.max_atomic_width = Some(32);
     base.stack_probes = StackProbeType::Inline;
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc-unknown-linux-muslspe".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
index 08871d9d72b..a07429bb0c5 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
@@ -23,6 +23,8 @@ pub(crate) fn target() -> Target {
             llvm_abiname: "ilp32d".into(),
             max_atomic_width: Some(32),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
index 397c202ec1a..0a4cc3b8be6 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
@@ -21,7 +21,6 @@ pub(crate) fn target() -> Target {
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
-            crt_static_default: false,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index 7a78004927b..fbe8c48eca7 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -12,6 +12,8 @@ pub(crate) fn target() -> Target {
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
 
     Target {
         llvm_target: "s390x-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
index fdc9628f78e..770da60da9e 100644
--- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
     Target {
         llvm_target: "sparcv9-sun-solaris".into(),
         metadata: crate::spec::TargetMetadata {
-            description: Some("SPARC Solaris 11, illumos".into()),
+            description: Some("SPARC Solaris 11.4".into()),
             tier: Some(2),
             host_tools: Some(false),
             std: Some(true),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
index 2f539f4f600..a0852b4611e 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
@@ -29,6 +29,8 @@ pub(crate) fn target() -> Target {
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".into(),
+            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs
index 28dd3c426c7..843568a4792 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
     Target {
         llvm_target: "x86_64-pc-solaris".into(),
         metadata: crate::spec::TargetMetadata {
-            description: Some("64-bit Solaris 11, illumos".into()),
+            description: Some("64-bit Solaris 11.4".into()),
             tier: Some(2),
             host_tools: Some(false),
             std: Some(true),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs
index 8be0f335db9..8dcdc5be8a9 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs
@@ -14,6 +14,8 @@ pub(crate) fn target() -> Target {
         | SanitizerSet::MEMORY
         | SanitizerSet::THREAD;
     base.supports_xray = true;
+    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
+    base.crt_static_default = true;
 
     Target {
         llvm_target: "x86_64-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 3a130607265..69f7a217cbf 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -5,6 +5,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_span::symbol::{Symbol, sym};
 
+use crate::spec::Target;
+
 /// Features that control behaviour of rustc, rather than the codegen.
 /// These exist globally and are not in the target-specific lists below.
 pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
@@ -15,45 +17,148 @@ pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
 pub const RUSTC_SPECIAL_FEATURES: &[&str] = &["backchain"];
 
 /// Stability information for target features.
-#[derive(Debug, Clone, Copy)]
-pub enum Stability {
+/// `Toggleability` is the type storing whether (un)stable features can be toggled:
+/// this is initially a function since it can depend on `Target`, but for stable hashing
+/// it needs to be something hashable to we have to make the type generic.
+#[derive(Debug, Clone)]
+pub enum Stability<Toggleability> {
     /// This target feature is stable, it can be used in `#[target_feature]` and
     /// `#[cfg(target_feature)]`.
-    Stable,
-    /// This target feature is unstable; using it in `#[target_feature]` or `#[cfg(target_feature)]`
-    /// requires enabling the given nightly feature.
-    Unstable(Symbol),
-    /// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be set in the basic
-    /// target definition. Used in particular for features that change the floating-point ABI.
+    Stable {
+        /// When enabling/disabling the feature via `-Ctarget-feature` or `#[target_feature]`,
+        /// determine if that is allowed.
+        allow_toggle: Toggleability,
+    },
+    /// This target feature is unstable. It is only present in `#[cfg(target_feature)]` on
+    /// nightly and using it in `#[target_feature]` requires enabling the given nightly feature.
+    Unstable {
+        /// This must be a *language* feature, or else rustc will ICE when reporting a missing
+        /// feature gate!
+        nightly_feature: Symbol,
+        /// See `Stable::allow_toggle` comment above.
+        allow_toggle: Toggleability,
+    },
+    /// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be
+    /// set in the basic target definition. It is never set in `cfg(target_feature)`. Used in
+    /// particular for features that change the floating-point ABI.
     Forbidden { reason: &'static str },
 }
-use Stability::*;
 
-impl<CTX> HashStable<CTX> for Stability {
+/// Returns `Ok` if the toggle is allowed, `Err` with an explanation of not.
+/// The `bool` indicates whether the feature is being enabled (`true`) or disabled.
+pub type AllowToggleUncomputed = fn(&Target, bool) -> Result<(), &'static str>;
+
+/// The computed result of whether a feature can be enabled/disabled on the current target.
+#[derive(Debug, Clone)]
+pub struct AllowToggleComputed {
+    enable: Result<(), &'static str>,
+    disable: Result<(), &'static str>,
+}
+
+/// `Stability` where `allow_toggle` has not been computed yet.
+pub type StabilityUncomputed = Stability<AllowToggleUncomputed>;
+/// `Stability` where `allow_toggle` has already been computed.
+pub type StabilityComputed = Stability<AllowToggleComputed>;
+
+impl<CTX, Toggleability: HashStable<CTX>> HashStable<CTX> for Stability<Toggleability> {
     #[inline]
     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
         std::mem::discriminant(self).hash_stable(hcx, hasher);
         match self {
-            Stable => {}
-            Unstable(sym) => {
-                sym.hash_stable(hcx, hasher);
+            Stability::Stable { allow_toggle } => {
+                allow_toggle.hash_stable(hcx, hasher);
             }
-            Forbidden { .. } => {}
+            Stability::Unstable { nightly_feature, allow_toggle } => {
+                nightly_feature.hash_stable(hcx, hasher);
+                allow_toggle.hash_stable(hcx, hasher);
+            }
+            Stability::Forbidden { reason } => {
+                reason.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl<CTX> HashStable<CTX> for AllowToggleComputed {
+    #[inline]
+    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
+        let AllowToggleComputed { enable, disable } = self;
+        enable.hash_stable(hcx, hasher);
+        disable.hash_stable(hcx, hasher);
+    }
+}
+
+impl<Toggleability> Stability<Toggleability> {
+    /// Returns whether the feature can be used in `cfg(target_feature)` ever.
+    /// (It might still be nightly-only even if this returns `true`, so make sure to also check
+    /// `requires_nightly`.)
+    pub fn in_cfg(&self) -> bool {
+        !matches!(self, Stability::Forbidden { .. })
+    }
+
+    /// Returns the nightly feature that is required to toggle this target feature via
+    /// `#[target_feature]`/`-Ctarget-feature` or to test it via `cfg(target_feature)`.
+    /// (For `cfg` we only care whether the feature is nightly or not, we don't require
+    /// the feature gate to actually be enabled when using a nightly compiler.)
+    ///
+    /// Before calling this, ensure the feature is even permitted for this use:
+    /// - for `#[target_feature]`/`-Ctarget-feature`, check `allow_toggle()`
+    /// - for `cfg(target_feature)`, check `in_cfg`
+    pub fn requires_nightly(&self) -> Option<Symbol> {
+        match *self {
+            Stability::Unstable { nightly_feature, .. } => Some(nightly_feature),
+            Stability::Stable { .. } => None,
+            Stability::Forbidden { .. } => panic!("forbidden features should not reach this far"),
         }
     }
 }
 
-impl Stability {
-    pub fn is_stable(self) -> bool {
-        matches!(self, Stable)
+impl StabilityUncomputed {
+    pub fn compute_toggleability(&self, target: &Target) -> StabilityComputed {
+        use Stability::*;
+        let compute = |f: AllowToggleUncomputed| AllowToggleComputed {
+            enable: f(target, true),
+            disable: f(target, false),
+        };
+        match *self {
+            Stable { allow_toggle } => Stable { allow_toggle: compute(allow_toggle) },
+            Unstable { nightly_feature, allow_toggle } => {
+                Unstable { nightly_feature, allow_toggle: compute(allow_toggle) }
+            }
+            Forbidden { reason } => Forbidden { reason },
+        }
     }
 
-    /// Forbidden features are not supported.
-    pub fn is_supported(self) -> bool {
-        !matches!(self, Forbidden { .. })
+    pub fn toggle_allowed(&self, target: &Target, enable: bool) -> Result<(), &'static str> {
+        use Stability::*;
+        match *self {
+            Stable { allow_toggle } => allow_toggle(target, enable),
+            Unstable { allow_toggle, .. } => allow_toggle(target, enable),
+            Forbidden { reason } => Err(reason),
+        }
     }
 }
 
+impl StabilityComputed {
+    /// Returns whether the feature may be toggled via `#[target_feature]` or `-Ctarget-feature`.
+    /// (It might still be nightly-only even if this returns `true`, so make sure to also check
+    /// `requires_nightly`.)
+    pub fn toggle_allowed(&self, enable: bool) -> Result<(), &'static str> {
+        let allow_toggle = match self {
+            Stability::Stable { allow_toggle } => allow_toggle,
+            Stability::Unstable { allow_toggle, .. } => allow_toggle,
+            Stability::Forbidden { reason } => return Err(reason),
+        };
+        if enable { allow_toggle.enable } else { allow_toggle.disable }
+    }
+}
+
+// Constructors for the list below, defaulting to "always allow toggle".
+const STABLE: StabilityUncomputed = Stability::Stable { allow_toggle: |_target, _enable| Ok(()) };
+const fn unstable(nightly_feature: Symbol) -> StabilityUncomputed {
+    Stability::Unstable { nightly_feature, allow_toggle: |_target, _enable| Ok(()) }
+}
+
 // Here we list target features that rustc "understands": they can be used in `#[target_feature]`
 // and `#[cfg(target_feature)]`. They also do not trigger any warnings when used with
 // `-Ctarget-feature`.
@@ -99,181 +204,218 @@ impl Stability {
 // Both of these are also applied transitively.
 type ImpliedFeatures = &'static [&'static str];
 
-const ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const ARM_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("aclass", Unstable(sym::arm_target_feature), &[]),
-    ("aes", Unstable(sym::arm_target_feature), &["neon"]),
-    ("crc", Unstable(sym::arm_target_feature), &[]),
-    ("d32", Unstable(sym::arm_target_feature), &[]),
-    ("dotprod", Unstable(sym::arm_target_feature), &["neon"]),
-    ("dsp", Unstable(sym::arm_target_feature), &[]),
-    ("fp-armv8", Unstable(sym::arm_target_feature), &["vfp4"]),
-    ("i8mm", Unstable(sym::arm_target_feature), &["neon"]),
-    ("mclass", Unstable(sym::arm_target_feature), &[]),
-    ("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
-    ("rclass", Unstable(sym::arm_target_feature), &[]),
-    ("sha2", Unstable(sym::arm_target_feature), &["neon"]),
-    ("soft-float", Forbidden { reason: "unsound because it changes float ABI" }, &[]),
+    ("aclass", unstable(sym::arm_target_feature), &[]),
+    ("aes", unstable(sym::arm_target_feature), &["neon"]),
+    ("crc", unstable(sym::arm_target_feature), &[]),
+    ("d32", unstable(sym::arm_target_feature), &[]),
+    ("dotprod", unstable(sym::arm_target_feature), &["neon"]),
+    ("dsp", unstable(sym::arm_target_feature), &[]),
+    ("fp-armv8", unstable(sym::arm_target_feature), &["vfp4"]),
+    (
+        "fpregs",
+        Stability::Unstable {
+            nightly_feature: sym::arm_target_feature,
+            allow_toggle: |target: &Target, _enable| {
+                // Only allow toggling this if the target has `soft-float` set. With `soft-float`,
+                // `fpregs` isn't needed so changing it cannot affect the ABI.
+                if target.has_feature("soft-float") {
+                    Ok(())
+                } else {
+                    Err("unsound on hard-float targets because it changes float ABI")
+                }
+            },
+        },
+        &[],
+    ),
+    ("i8mm", unstable(sym::arm_target_feature), &["neon"]),
+    ("mclass", unstable(sym::arm_target_feature), &[]),
+    ("neon", unstable(sym::arm_target_feature), &["vfp3"]),
+    ("rclass", unstable(sym::arm_target_feature), &[]),
+    ("sha2", unstable(sym::arm_target_feature), &["neon"]),
+    ("soft-float", Stability::Forbidden { reason: "unsound because it changes float ABI" }, &[]),
     // This is needed for inline assembly, but shouldn't be stabilized as-is
     // since it should be enabled per-function using #[instruction_set], not
     // #[target_feature].
-    ("thumb-mode", Unstable(sym::arm_target_feature), &[]),
-    ("thumb2", Unstable(sym::arm_target_feature), &[]),
-    ("trustzone", Unstable(sym::arm_target_feature), &[]),
-    ("v5te", Unstable(sym::arm_target_feature), &[]),
-    ("v6", Unstable(sym::arm_target_feature), &["v5te"]),
-    ("v6k", Unstable(sym::arm_target_feature), &["v6"]),
-    ("v6t2", Unstable(sym::arm_target_feature), &["v6k", "thumb2"]),
-    ("v7", Unstable(sym::arm_target_feature), &["v6t2"]),
-    ("v8", Unstable(sym::arm_target_feature), &["v7"]),
-    ("vfp2", Unstable(sym::arm_target_feature), &[]),
-    ("vfp3", Unstable(sym::arm_target_feature), &["vfp2", "d32"]),
-    ("vfp4", Unstable(sym::arm_target_feature), &["vfp3"]),
-    ("virtualization", Unstable(sym::arm_target_feature), &[]),
+    ("thumb-mode", unstable(sym::arm_target_feature), &[]),
+    ("thumb2", unstable(sym::arm_target_feature), &[]),
+    ("trustzone", unstable(sym::arm_target_feature), &[]),
+    ("v5te", unstable(sym::arm_target_feature), &[]),
+    ("v6", unstable(sym::arm_target_feature), &["v5te"]),
+    ("v6k", unstable(sym::arm_target_feature), &["v6"]),
+    ("v6t2", unstable(sym::arm_target_feature), &["v6k", "thumb2"]),
+    ("v7", unstable(sym::arm_target_feature), &["v6t2"]),
+    ("v8", unstable(sym::arm_target_feature), &["v7"]),
+    ("vfp2", unstable(sym::arm_target_feature), &[]),
+    ("vfp3", unstable(sym::arm_target_feature), &["vfp2", "d32"]),
+    ("vfp4", unstable(sym::arm_target_feature), &["vfp3"]),
+    ("virtualization", unstable(sym::arm_target_feature), &[]),
     // tidy-alphabetical-end
-    // FIXME: need to also forbid turning off `fpregs` on hardfloat targets
 ];
 
-const AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const AARCH64_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
     // FEAT_AES & FEAT_PMULL
-    ("aes", Stable, &["neon"]),
+    ("aes", STABLE, &["neon"]),
     // FEAT_BF16
-    ("bf16", Stable, &[]),
+    ("bf16", STABLE, &[]),
     // FEAT_BTI
-    ("bti", Stable, &[]),
+    ("bti", STABLE, &[]),
     // FEAT_CRC
-    ("crc", Stable, &[]),
+    ("crc", STABLE, &[]),
     // FEAT_CSSC
-    ("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("cssc", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_DIT
-    ("dit", Stable, &[]),
+    ("dit", STABLE, &[]),
     // FEAT_DotProd
-    ("dotprod", Stable, &["neon"]),
+    ("dotprod", STABLE, &["neon"]),
     // FEAT_DPB
-    ("dpb", Stable, &[]),
+    ("dpb", STABLE, &[]),
     // FEAT_DPB2
-    ("dpb2", Stable, &["dpb"]),
+    ("dpb2", STABLE, &["dpb"]),
     // FEAT_ECV
-    ("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("ecv", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_F32MM
-    ("f32mm", Stable, &["sve"]),
+    ("f32mm", STABLE, &["sve"]),
     // FEAT_F64MM
-    ("f64mm", Stable, &["sve"]),
+    ("f64mm", STABLE, &["sve"]),
     // FEAT_FAMINMAX
-    ("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("faminmax", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_FCMA
-    ("fcma", Stable, &["neon"]),
+    ("fcma", STABLE, &["neon"]),
     // FEAT_FHM
-    ("fhm", Stable, &["fp16"]),
+    ("fhm", STABLE, &["fp16"]),
     // FEAT_FLAGM
-    ("flagm", Stable, &[]),
+    ("flagm", STABLE, &[]),
     // FEAT_FLAGM2
-    ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("flagm2", unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
     // FEAT_FP16
     // Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
-    ("fp16", Stable, &["neon"]),
+    ("fp16", STABLE, &["neon"]),
     // FEAT_FP8
-    ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
+    ("fp8", unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
     // FEAT_FP8DOT2
-    ("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
+    ("fp8dot2", unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
     // FEAT_FP8DOT4
-    ("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
+    ("fp8dot4", unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
     // FEAT_FP8FMA
-    ("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
+    ("fp8fma", unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
     // FEAT_FRINTTS
-    ("frintts", Stable, &[]),
+    ("frintts", STABLE, &[]),
     // FEAT_HBC
-    ("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("hbc", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_I8MM
-    ("i8mm", Stable, &[]),
+    ("i8mm", STABLE, &[]),
     // FEAT_JSCVT
     // Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
-    ("jsconv", Stable, &["neon"]),
+    ("jsconv", STABLE, &["neon"]),
     // FEAT_LOR
-    ("lor", Stable, &[]),
+    ("lor", STABLE, &[]),
     // FEAT_LSE
-    ("lse", Stable, &[]),
+    ("lse", STABLE, &[]),
     // FEAT_LSE128
-    ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
+    ("lse128", unstable(sym::aarch64_unstable_target_feature), &["lse"]),
     // FEAT_LSE2
-    ("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("lse2", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_LUT
-    ("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("lut", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_MOPS
-    ("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("mops", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_MTE & FEAT_MTE2
-    ("mte", Stable, &[]),
+    ("mte", STABLE, &[]),
     // FEAT_AdvSimd & FEAT_FP
-    ("neon", Stable, &[]),
+    (
+        "neon",
+        Stability::Stable {
+            allow_toggle: |target, enable| {
+                if target.abi == "softfloat" {
+                    // `neon` has no ABI implications for softfloat targets, we can allow this.
+                    Ok(())
+                } else if enable
+                    && !target.has_neg_feature("fp-armv8")
+                    && !target.has_neg_feature("neon")
+                {
+                    // neon is enabled by default, and has not been disabled, so enabling it again
+                    // is redundant and we can permit it. Forbidding this would be a breaking change
+                    // since this feature is stable.
+                    Ok(())
+                } else {
+                    Err("unsound on hard-float targets because it changes float ABI")
+                }
+            },
+        },
+        &[],
+    ),
     // FEAT_PAUTH (address authentication)
-    ("paca", Stable, &[]),
+    ("paca", STABLE, &[]),
     // FEAT_PAUTH (generic authentication)
-    ("pacg", Stable, &[]),
+    ("pacg", STABLE, &[]),
     // FEAT_PAN
-    ("pan", Stable, &[]),
+    ("pan", STABLE, &[]),
     // FEAT_PAuth_LR
-    ("pauth-lr", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("pauth-lr", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_PMUv3
-    ("pmuv3", Stable, &[]),
+    ("pmuv3", STABLE, &[]),
     // FEAT_RNG
-    ("rand", Stable, &[]),
+    ("rand", STABLE, &[]),
     // FEAT_RAS & FEAT_RASv1p1
-    ("ras", Stable, &[]),
+    ("ras", STABLE, &[]),
     // FEAT_LRCPC
-    ("rcpc", Stable, &[]),
+    ("rcpc", STABLE, &[]),
     // FEAT_LRCPC2
-    ("rcpc2", Stable, &["rcpc"]),
+    ("rcpc2", STABLE, &["rcpc"]),
     // FEAT_LRCPC3
-    ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
+    ("rcpc3", unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
     // FEAT_RDM
-    ("rdm", Stable, &["neon"]),
+    ("rdm", STABLE, &["neon"]),
     // This is needed for inline assembly, but shouldn't be stabilized as-is
     // since it should be enabled globally using -Zfixed-x18, not
     // #[target_feature].
     // Note that cfg(target_feature = "reserve-x18") is currently not set for
     // targets that reserve x18 by default.
-    ("reserve-x18", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("reserve-x18", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_SB
-    ("sb", Stable, &[]),
+    ("sb", STABLE, &[]),
     // FEAT_SHA1 & FEAT_SHA256
-    ("sha2", Stable, &["neon"]),
+    ("sha2", STABLE, &["neon"]),
     // FEAT_SHA512 & FEAT_SHA3
-    ("sha3", Stable, &["sha2"]),
+    ("sha3", STABLE, &["sha2"]),
     // FEAT_SM3 & FEAT_SM4
-    ("sm4", Stable, &["neon"]),
+    ("sm4", STABLE, &["neon"]),
     // FEAT_SME
-    ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
+    ("sme", unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
     // FEAT_SME_B16B16
-    ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
+    ("sme-b16b16", unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
     // FEAT_SME_F16F16
-    ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
+    ("sme-f16f16", unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
     // FEAT_SME_F64F64
-    ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
+    ("sme-f64f64", unstable(sym::aarch64_unstable_target_feature), &["sme"]),
     // FEAT_SME_F8F16
-    ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
+    ("sme-f8f16", unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
     // FEAT_SME_F8F32
-    ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
+    ("sme-f8f32", unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
     // FEAT_SME_FA64
-    ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
+    ("sme-fa64", unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
     // FEAT_SME_I16I64
-    ("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
+    ("sme-i16i64", unstable(sym::aarch64_unstable_target_feature), &["sme"]),
     // FEAT_SME_LUTv2
-    ("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("sme-lutv2", unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_SME2
-    ("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
+    ("sme2", unstable(sym::aarch64_unstable_target_feature), &["sme"]),
     // FEAT_SME2p1
-    ("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
+    ("sme2p1", unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
     // FEAT_SPE
-    ("spe", Stable, &[]),
+    ("spe", STABLE, &[]),
     // FEAT_SSBS & FEAT_SSBS2
-    ("ssbs", Stable, &[]),
+    ("ssbs", STABLE, &[]),
     // FEAT_SSVE_FP8FDOT2
-    ("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
+    ("ssve-fp8dot2", unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
     // FEAT_SSVE_FP8FDOT4
-    ("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
+    ("ssve-fp8dot4", unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
     // FEAT_SSVE_FP8FMA
-    ("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
+    ("ssve-fp8fma", unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
     // FEAT_SVE
     // It was decided that SVE requires Neon: https://github.com/rust-lang/rust/pull/91608
     //
@@ -281,46 +423,46 @@ const AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     // exist together: https://developer.arm.com/documentation/102340/0100/New-features-in-SVE2
     //
     // "For backwards compatibility, Neon and VFP are required in the latest architectures."
-    ("sve", Stable, &["neon"]),
+    ("sve", STABLE, &["neon"]),
     // FEAT_SVE_B16B16 (SVE or SME Z-targeting instructions)
-    ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
+    ("sve-b16b16", unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
     // FEAT_SVE2
-    ("sve2", Stable, &["sve"]),
+    ("sve2", STABLE, &["sve"]),
     // FEAT_SVE_AES & FEAT_SVE_PMULL128
-    ("sve2-aes", Stable, &["sve2", "aes"]),
+    ("sve2-aes", STABLE, &["sve2", "aes"]),
     // FEAT_SVE2_BitPerm
-    ("sve2-bitperm", Stable, &["sve2"]),
+    ("sve2-bitperm", STABLE, &["sve2"]),
     // FEAT_SVE2_SHA3
-    ("sve2-sha3", Stable, &["sve2", "sha3"]),
+    ("sve2-sha3", STABLE, &["sve2", "sha3"]),
     // FEAT_SVE2_SM4
-    ("sve2-sm4", Stable, &["sve2", "sm4"]),
+    ("sve2-sm4", STABLE, &["sve2", "sm4"]),
     // FEAT_SVE2p1
-    ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
+    ("sve2p1", unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
     // FEAT_TME
-    ("tme", Stable, &[]),
-    ("v8.1a", Unstable(sym::aarch64_ver_target_feature), &[
+    ("tme", STABLE, &[]),
+    ("v8.1a", unstable(sym::aarch64_ver_target_feature), &[
         "crc", "lse", "rdm", "pan", "lor", "vh",
     ]),
-    ("v8.2a", Unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
-    ("v8.3a", Unstable(sym::aarch64_ver_target_feature), &[
+    ("v8.2a", unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
+    ("v8.3a", unstable(sym::aarch64_ver_target_feature), &[
         "v8.2a", "rcpc", "paca", "pacg", "jsconv",
     ]),
-    ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
-    ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
-    ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
-    ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
-    ("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
-    ("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
-    ("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
-    ("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
-    ("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
-    ("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
-    ("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
-    ("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
+    ("v8.4a", unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
+    ("v8.5a", unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
+    ("v8.6a", unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
+    ("v8.7a", unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
+    ("v8.8a", unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
+    ("v8.9a", unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
+    ("v9.1a", unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
+    ("v9.2a", unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
+    ("v9.3a", unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
+    ("v9.4a", unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
+    ("v9.5a", unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
+    ("v9a", unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
     // FEAT_VHE
-    ("vh", Stable, &[]),
+    ("vh", STABLE, &[]),
     // FEAT_WFxT
-    ("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    ("wfxt", unstable(sym::aarch64_unstable_target_feature), &[]),
     // tidy-alphabetical-end
 ];
 
@@ -328,241 +470,270 @@ const AARCH64_TIED_FEATURES: &[&[&str]] = &[
     &["paca", "pacg"], // Together these represent `pauth` in LLVM
 ];
 
-const X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const X86_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("adx", Stable, &[]),
-    ("aes", Stable, &["sse2"]),
-    ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
-    ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
-    ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
-    ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
-    ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
-    ("avx", Stable, &["sse4.2"]),
-    ("avx2", Stable, &["avx"]),
-    ("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]),
-    ("avx512bitalg", Unstable(sym::avx512_target_feature), &["avx512bw"]),
-    ("avx512bw", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avx512cd", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avx512dq", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avx512f", Unstable(sym::avx512_target_feature), &["avx2", "fma", "f16c"]),
-    ("avx512fp16", Unstable(sym::avx512_target_feature), &["avx512bw", "avx512vl", "avx512dq"]),
-    ("avx512ifma", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avx512vbmi", Unstable(sym::avx512_target_feature), &["avx512bw"]),
-    ("avx512vbmi2", Unstable(sym::avx512_target_feature), &["avx512bw"]),
-    ("avx512vl", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avx512vnni", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avx512vp2intersect", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avx512vpopcntdq", Unstable(sym::avx512_target_feature), &["avx512f"]),
-    ("avxifma", Unstable(sym::avx512_target_feature), &["avx2"]),
-    ("avxneconvert", Unstable(sym::avx512_target_feature), &["avx2"]),
-    ("avxvnni", Unstable(sym::avx512_target_feature), &["avx2"]),
-    ("avxvnniint16", Unstable(sym::avx512_target_feature), &["avx2"]),
-    ("avxvnniint8", Unstable(sym::avx512_target_feature), &["avx2"]),
-    ("bmi1", Stable, &[]),
-    ("bmi2", Stable, &[]),
-    ("cmpxchg16b", Stable, &[]),
-    ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
-    ("f16c", Stable, &["avx"]),
-    ("fma", Stable, &["avx"]),
-    ("fxsr", Stable, &[]),
-    ("gfni", Unstable(sym::avx512_target_feature), &["sse2"]),
-    ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
-    ("lzcnt", Stable, &[]),
-    ("movbe", Stable, &[]),
-    ("pclmulqdq", Stable, &["sse2"]),
-    ("popcnt", Stable, &[]),
-    ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
-    ("rdrand", Stable, &[]),
-    ("rdseed", Stable, &[]),
-    ("rtm", Unstable(sym::rtm_target_feature), &[]),
-    ("sha", Stable, &["sse2"]),
-    ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
-    ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
-    ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
-    ("soft-float", Forbidden { reason: "unsound because it changes float ABI" }, &[]),
-    ("sse", Stable, &[]),
-    ("sse2", Stable, &["sse"]),
-    ("sse3", Stable, &["sse2"]),
-    ("sse4.1", Stable, &["ssse3"]),
-    ("sse4.2", Stable, &["sse4.1"]),
-    ("sse4a", Unstable(sym::sse4a_target_feature), &["sse3"]),
-    ("ssse3", Stable, &["sse3"]),
-    ("tbm", Unstable(sym::tbm_target_feature), &[]),
-    ("vaes", Unstable(sym::avx512_target_feature), &["avx2", "aes"]),
-    ("vpclmulqdq", Unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
-    ("xop", Unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]),
-    ("xsave", Stable, &[]),
-    ("xsavec", Stable, &["xsave"]),
-    ("xsaveopt", Stable, &["xsave"]),
-    ("xsaves", Stable, &["xsave"]),
+    ("adx", STABLE, &[]),
+    ("aes", STABLE, &["sse2"]),
+    ("amx-bf16", unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("amx-complex", unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("amx-fp16", unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("amx-int8", unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("amx-tile", unstable(sym::x86_amx_intrinsics), &[]),
+    ("avx", STABLE, &["sse4.2"]),
+    ("avx2", STABLE, &["avx"]),
+    ("avx512bf16", unstable(sym::avx512_target_feature), &["avx512bw"]),
+    ("avx512bitalg", unstable(sym::avx512_target_feature), &["avx512bw"]),
+    ("avx512bw", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avx512cd", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avx512dq", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avx512f", unstable(sym::avx512_target_feature), &["avx2", "fma", "f16c"]),
+    ("avx512fp16", unstable(sym::avx512_target_feature), &["avx512bw", "avx512vl", "avx512dq"]),
+    ("avx512ifma", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avx512vbmi", unstable(sym::avx512_target_feature), &["avx512bw"]),
+    ("avx512vbmi2", unstable(sym::avx512_target_feature), &["avx512bw"]),
+    ("avx512vl", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avx512vnni", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avx512vp2intersect", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avx512vpopcntdq", unstable(sym::avx512_target_feature), &["avx512f"]),
+    ("avxifma", unstable(sym::avx512_target_feature), &["avx2"]),
+    ("avxneconvert", unstable(sym::avx512_target_feature), &["avx2"]),
+    ("avxvnni", unstable(sym::avx512_target_feature), &["avx2"]),
+    ("avxvnniint16", unstable(sym::avx512_target_feature), &["avx2"]),
+    ("avxvnniint8", unstable(sym::avx512_target_feature), &["avx2"]),
+    ("bmi1", STABLE, &[]),
+    ("bmi2", STABLE, &[]),
+    ("cmpxchg16b", STABLE, &[]),
+    ("ermsb", unstable(sym::ermsb_target_feature), &[]),
+    ("f16c", STABLE, &["avx"]),
+    ("fma", STABLE, &["avx"]),
+    ("fxsr", STABLE, &[]),
+    ("gfni", unstable(sym::avx512_target_feature), &["sse2"]),
+    ("lahfsahf", unstable(sym::lahfsahf_target_feature), &[]),
+    ("lzcnt", STABLE, &[]),
+    ("movbe", STABLE, &[]),
+    ("pclmulqdq", STABLE, &["sse2"]),
+    ("popcnt", STABLE, &[]),
+    ("prfchw", unstable(sym::prfchw_target_feature), &[]),
+    ("rdrand", STABLE, &[]),
+    ("rdseed", STABLE, &[]),
+    ("rtm", unstable(sym::rtm_target_feature), &[]),
+    ("sha", STABLE, &["sse2"]),
+    ("sha512", unstable(sym::sha512_sm_x86), &["avx2"]),
+    ("sm3", unstable(sym::sha512_sm_x86), &["avx"]),
+    ("sm4", unstable(sym::sha512_sm_x86), &["avx2"]),
+    ("soft-float", Stability::Forbidden { reason: "unsound because it changes float ABI" }, &[]),
+    ("sse", STABLE, &[]),
+    ("sse2", STABLE, &["sse"]),
+    ("sse3", STABLE, &["sse2"]),
+    ("sse4.1", STABLE, &["ssse3"]),
+    ("sse4.2", STABLE, &["sse4.1"]),
+    ("sse4a", unstable(sym::sse4a_target_feature), &["sse3"]),
+    ("ssse3", STABLE, &["sse3"]),
+    ("tbm", unstable(sym::tbm_target_feature), &[]),
+    ("vaes", unstable(sym::avx512_target_feature), &["avx2", "aes"]),
+    ("vpclmulqdq", unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
+    (
+        "x87",
+        Stability::Unstable {
+            nightly_feature: sym::x87_target_feature,
+            allow_toggle: |target: &Target, _enable| {
+                // Only allow toggling this if the target has `soft-float` set. With `soft-float`,
+                // `fpregs` isn't needed so changing it cannot affect the ABI.
+                if target.has_feature("soft-float") {
+                    Ok(())
+                } else {
+                    Err("unsound on hard-float targets because it changes float ABI")
+                }
+            },
+        },
+        &[],
+    ),
+    ("xop", unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]),
+    ("xsave", STABLE, &[]),
+    ("xsavec", STABLE, &["xsave"]),
+    ("xsaveopt", STABLE, &["xsave"]),
+    ("xsaves", STABLE, &["xsave"]),
     // tidy-alphabetical-end
-    // FIXME: need to also forbid turning off `x87` on hardfloat targets
 ];
 
-const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const HEXAGON_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("hvx", Unstable(sym::hexagon_target_feature), &[]),
-    ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
+    ("hvx", unstable(sym::hexagon_target_feature), &[]),
+    ("hvx-length128b", unstable(sym::hexagon_target_feature), &["hvx"]),
     // tidy-alphabetical-end
 ];
 
-const POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const POWERPC_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("altivec", Unstable(sym::powerpc_target_feature), &[]),
-    ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
-    ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
-    ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
-    ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
-    ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
-    ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
-    ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
-    ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
-    ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
+    ("altivec", unstable(sym::powerpc_target_feature), &[]),
+    ("partword-atomics", unstable(sym::powerpc_target_feature), &[]),
+    ("power10-vector", unstable(sym::powerpc_target_feature), &["power9-vector"]),
+    ("power8-altivec", unstable(sym::powerpc_target_feature), &["altivec"]),
+    ("power8-crypto", unstable(sym::powerpc_target_feature), &["power8-altivec"]),
+    ("power8-vector", unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
+    ("power9-altivec", unstable(sym::powerpc_target_feature), &["power8-altivec"]),
+    ("power9-vector", unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
+    ("quadword-atomics", unstable(sym::powerpc_target_feature), &[]),
+    ("vsx", unstable(sym::powerpc_target_feature), &["altivec"]),
     // tidy-alphabetical-end
 ];
 
-const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const MIPS_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("fp64", Unstable(sym::mips_target_feature), &[]),
-    ("msa", Unstable(sym::mips_target_feature), &[]),
-    ("virt", Unstable(sym::mips_target_feature), &[]),
+    ("fp64", unstable(sym::mips_target_feature), &[]),
+    ("msa", unstable(sym::mips_target_feature), &[]),
+    ("virt", unstable(sym::mips_target_feature), &[]),
     // tidy-alphabetical-end
 ];
 
-const RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const RISCV_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("a", Stable, &["zaamo", "zalrsc"]),
-    ("c", Stable, &[]),
-    ("d", Unstable(sym::riscv_target_feature), &["f"]),
-    ("e", Unstable(sym::riscv_target_feature), &[]),
-    ("f", Unstable(sym::riscv_target_feature), &[]),
-    ("m", Stable, &[]),
-    ("relax", Unstable(sym::riscv_target_feature), &[]),
-    ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
-    ("v", Unstable(sym::riscv_target_feature), &[]),
-    ("zaamo", Unstable(sym::riscv_target_feature), &[]),
-    ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
-    ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
-    ("zba", Stable, &[]),
-    ("zbb", Stable, &[]),
-    ("zbc", Stable, &[]),
-    ("zbkb", Stable, &[]),
-    ("zbkc", Stable, &[]),
-    ("zbkx", Stable, &[]),
-    ("zbs", Stable, &[]),
-    ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
-    ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
-    ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
-    ("zfinx", Unstable(sym::riscv_target_feature), &[]),
-    ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
-    ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
-    ("zk", Stable, &["zkn", "zkr", "zkt"]),
-    ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
-    ("zknd", Stable, &[]),
-    ("zkne", Stable, &[]),
-    ("zknh", Stable, &[]),
-    ("zkr", Stable, &[]),
-    ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
-    ("zksed", Stable, &[]),
-    ("zksh", Stable, &[]),
-    ("zkt", Stable, &[]),
+    ("a", STABLE, &["zaamo", "zalrsc"]),
+    ("c", STABLE, &[]),
+    ("d", unstable(sym::riscv_target_feature), &["f"]),
+    ("e", unstable(sym::riscv_target_feature), &[]),
+    ("f", unstable(sym::riscv_target_feature), &[]),
+    ("m", STABLE, &[]),
+    ("relax", unstable(sym::riscv_target_feature), &[]),
+    ("unaligned-scalar-mem", unstable(sym::riscv_target_feature), &[]),
+    ("v", unstable(sym::riscv_target_feature), &[]),
+    ("zaamo", unstable(sym::riscv_target_feature), &[]),
+    ("zabha", unstable(sym::riscv_target_feature), &["zaamo"]),
+    ("zalrsc", unstable(sym::riscv_target_feature), &[]),
+    ("zba", STABLE, &[]),
+    ("zbb", STABLE, &[]),
+    ("zbc", STABLE, &[]),
+    ("zbkb", STABLE, &[]),
+    ("zbkc", STABLE, &[]),
+    ("zbkx", STABLE, &[]),
+    ("zbs", STABLE, &[]),
+    ("zdinx", unstable(sym::riscv_target_feature), &["zfinx"]),
+    ("zfh", unstable(sym::riscv_target_feature), &["zfhmin"]),
+    ("zfhmin", unstable(sym::riscv_target_feature), &["f"]),
+    ("zfinx", unstable(sym::riscv_target_feature), &[]),
+    ("zhinx", unstable(sym::riscv_target_feature), &["zhinxmin"]),
+    ("zhinxmin", unstable(sym::riscv_target_feature), &["zfinx"]),
+    ("zk", STABLE, &["zkn", "zkr", "zkt"]),
+    ("zkn", STABLE, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
+    ("zknd", STABLE, &[]),
+    ("zkne", STABLE, &[]),
+    ("zknh", STABLE, &[]),
+    ("zkr", STABLE, &[]),
+    ("zks", STABLE, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
+    ("zksed", STABLE, &[]),
+    ("zksh", STABLE, &[]),
+    ("zkt", STABLE, &[]),
     // tidy-alphabetical-end
 ];
 
-const WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const WASM_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("atomics", Unstable(sym::wasm_target_feature), &[]),
-    ("bulk-memory", Stable, &[]),
-    ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
-    ("extended-const", Stable, &[]),
-    ("multivalue", Stable, &[]),
-    ("mutable-globals", Stable, &[]),
-    ("nontrapping-fptoint", Stable, &[]),
-    ("reference-types", Stable, &[]),
-    ("relaxed-simd", Stable, &["simd128"]),
-    ("sign-ext", Stable, &[]),
-    ("simd128", Stable, &[]),
-    ("tail-call", Stable, &[]),
-    ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
+    ("atomics", unstable(sym::wasm_target_feature), &[]),
+    ("bulk-memory", STABLE, &[]),
+    ("exception-handling", unstable(sym::wasm_target_feature), &[]),
+    ("extended-const", STABLE, &[]),
+    ("multivalue", STABLE, &[]),
+    ("mutable-globals", STABLE, &[]),
+    ("nontrapping-fptoint", STABLE, &[]),
+    ("reference-types", STABLE, &[]),
+    ("relaxed-simd", STABLE, &["simd128"]),
+    ("sign-ext", STABLE, &[]),
+    ("simd128", STABLE, &[]),
+    ("tail-call", STABLE, &[]),
+    ("wide-arithmetic", unstable(sym::wasm_target_feature), &[]),
     // tidy-alphabetical-end
 ];
 
-const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
-    &[("alu32", Unstable(sym::bpf_target_feature), &[])];
+const BPF_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] =
+    &[("alu32", unstable(sym::bpf_target_feature), &[])];
 
-const CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const CSKY_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
-    ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
-    ("3e3r1", Unstable(sym::csky_target_feature), &[]),
-    ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
-    ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
-    ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
-    ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
-    ("cache", Unstable(sym::csky_target_feature), &[]),
-    ("doloop", Unstable(sym::csky_target_feature), &[]),
-    ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
-    ("dspe60", Unstable(sym::csky_target_feature), &[]),
-    ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
-    ("e2", Unstable(sym::csky_target_feature), &["e2"]),
-    ("edsp", Unstable(sym::csky_target_feature), &[]),
-    ("elrw", Unstable(sym::csky_target_feature), &[]),
-    ("float1e2", Unstable(sym::csky_target_feature), &[]),
-    ("float1e3", Unstable(sym::csky_target_feature), &[]),
-    ("float3e4", Unstable(sym::csky_target_feature), &[]),
-    ("float7e60", Unstable(sym::csky_target_feature), &[]),
-    ("floate1", Unstable(sym::csky_target_feature), &[]),
-    ("hard-tp", Unstable(sym::csky_target_feature), &[]),
-    ("high-registers", Unstable(sym::csky_target_feature), &[]),
-    ("hwdiv", Unstable(sym::csky_target_feature), &[]),
-    ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
-    ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
-    ("nvic", Unstable(sym::csky_target_feature), &[]),
-    ("trust", Unstable(sym::csky_target_feature), &[]),
-    ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
-    ("vdspv1", Unstable(sym::csky_target_feature), &[]),
-    ("vdspv2", Unstable(sym::csky_target_feature), &[]),
+    ("10e60", unstable(sym::csky_target_feature), &["7e10"]),
+    ("2e3", unstable(sym::csky_target_feature), &["e2"]),
+    ("3e3r1", unstable(sym::csky_target_feature), &[]),
+    ("3e3r2", unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
+    ("3e3r3", unstable(sym::csky_target_feature), &["doloop"]),
+    ("3e7", unstable(sym::csky_target_feature), &["2e3"]),
+    ("7e10", unstable(sym::csky_target_feature), &["3e7"]),
+    ("cache", unstable(sym::csky_target_feature), &[]),
+    ("doloop", unstable(sym::csky_target_feature), &[]),
+    ("dsp1e2", unstable(sym::csky_target_feature), &[]),
+    ("dspe60", unstable(sym::csky_target_feature), &[]),
+    ("e1", unstable(sym::csky_target_feature), &["elrw"]),
+    ("e2", unstable(sym::csky_target_feature), &["e2"]),
+    ("edsp", unstable(sym::csky_target_feature), &[]),
+    ("elrw", unstable(sym::csky_target_feature), &[]),
+    ("float1e2", unstable(sym::csky_target_feature), &[]),
+    ("float1e3", unstable(sym::csky_target_feature), &[]),
+    ("float3e4", unstable(sym::csky_target_feature), &[]),
+    ("float7e60", unstable(sym::csky_target_feature), &[]),
+    ("floate1", unstable(sym::csky_target_feature), &[]),
+    ("hard-tp", unstable(sym::csky_target_feature), &[]),
+    ("high-registers", unstable(sym::csky_target_feature), &[]),
+    ("hwdiv", unstable(sym::csky_target_feature), &[]),
+    ("mp", unstable(sym::csky_target_feature), &["2e3"]),
+    ("mp1e2", unstable(sym::csky_target_feature), &["3e7"]),
+    ("nvic", unstable(sym::csky_target_feature), &[]),
+    ("trust", unstable(sym::csky_target_feature), &[]),
+    ("vdsp2e60f", unstable(sym::csky_target_feature), &[]),
+    ("vdspv1", unstable(sym::csky_target_feature), &[]),
+    ("vdspv2", unstable(sym::csky_target_feature), &[]),
     // tidy-alphabetical-end
     //fpu
     // tidy-alphabetical-start
-    ("fdivdu", Unstable(sym::csky_target_feature), &[]),
-    ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
-    ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
-    ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
-    ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
-    ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
-    ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
-    ("hard-float", Unstable(sym::csky_target_feature), &[]),
-    ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
+    ("fdivdu", unstable(sym::csky_target_feature), &[]),
+    ("fpuv2_df", unstable(sym::csky_target_feature), &[]),
+    ("fpuv2_sf", unstable(sym::csky_target_feature), &[]),
+    ("fpuv3_df", unstable(sym::csky_target_feature), &[]),
+    ("fpuv3_hf", unstable(sym::csky_target_feature), &[]),
+    ("fpuv3_hi", unstable(sym::csky_target_feature), &[]),
+    ("fpuv3_sf", unstable(sym::csky_target_feature), &[]),
+    ("hard-float", unstable(sym::csky_target_feature), &[]),
+    ("hard-float-abi", unstable(sym::csky_target_feature), &[]),
+    // tidy-alphabetical-end
+];
+
+const LOONGARCH_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
+    // tidy-alphabetical-start
+    ("d", unstable(sym::loongarch_target_feature), &["f"]),
+    ("f", unstable(sym::loongarch_target_feature), &[]),
+    ("frecipe", unstable(sym::loongarch_target_feature), &[]),
+    ("lasx", unstable(sym::loongarch_target_feature), &["lsx"]),
+    ("lbt", unstable(sym::loongarch_target_feature), &[]),
+    ("lsx", unstable(sym::loongarch_target_feature), &["d"]),
+    ("lvz", unstable(sym::loongarch_target_feature), &[]),
+    ("relax", unstable(sym::loongarch_target_feature), &[]),
+    ("ual", unstable(sym::loongarch_target_feature), &[]),
     // tidy-alphabetical-end
 ];
 
-const LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const IBMZ_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("d", Unstable(sym::loongarch_target_feature), &["f"]),
-    ("f", Unstable(sym::loongarch_target_feature), &[]),
-    ("frecipe", Unstable(sym::loongarch_target_feature), &[]),
-    ("lasx", Unstable(sym::loongarch_target_feature), &["lsx"]),
-    ("lbt", Unstable(sym::loongarch_target_feature), &[]),
-    ("lsx", Unstable(sym::loongarch_target_feature), &["d"]),
-    ("lvz", Unstable(sym::loongarch_target_feature), &[]),
-    ("relax", Unstable(sym::loongarch_target_feature), &[]),
-    ("ual", Unstable(sym::loongarch_target_feature), &[]),
+    ("backchain", unstable(sym::s390x_target_feature), &[]),
+    ("vector", unstable(sym::s390x_target_feature), &[]),
     // tidy-alphabetical-end
 ];
 
-const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const SPARC_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("backchain", Unstable(sym::s390x_target_feature), &[]),
-    ("vector", Unstable(sym::s390x_target_feature), &[]),
+    ("leoncasa", unstable(sym::sparc_target_feature), &[]),
+    ("v8plus", unstable(sym::sparc_target_feature), &[]),
+    ("v9", unstable(sym::sparc_target_feature), &[]),
     // tidy-alphabetical-end
 ];
 
-const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
+const M68K_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
-    ("v8plus", Unstable(sym::sparc_target_feature), &[]),
-    ("v9", Unstable(sym::sparc_target_feature), &[]),
+    ("isa-68000", unstable(sym::m68k_target_feature), &[]),
+    ("isa-68010", unstable(sym::m68k_target_feature), &["isa-68000"]),
+    ("isa-68020", unstable(sym::m68k_target_feature), &["isa-68010"]),
+    ("isa-68030", unstable(sym::m68k_target_feature), &["isa-68020"]),
+    ("isa-68040", unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
+    ("isa-68060", unstable(sym::m68k_target_feature), &["isa-68040"]),
+    // FPU
+    ("isa-68881", unstable(sym::m68k_target_feature), &[]),
+    ("isa-68882", unstable(sym::m68k_target_feature), &["isa-68881"]),
     // tidy-alphabetical-end
 ];
 
@@ -570,7 +741,7 @@ const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
 /// primitives may be documented.
 ///
 /// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
-pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
+pub fn all_rust_features() -> impl Iterator<Item = (&'static str, StabilityUncomputed)> {
     std::iter::empty()
         .chain(ARM_FEATURES.iter())
         .chain(AARCH64_FEATURES.iter())
@@ -585,6 +756,7 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
         .chain(LOONGARCH_FEATURES)
         .chain(IBMZ_FEATURES)
         .chain(SPARC_FEATURES)
+        .chain(M68K_FEATURES)
         .cloned()
         .map(|(f, s, _)| (f, s))
 }
@@ -611,9 +783,13 @@ 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)] {
+impl Target {
+    pub fn rust_target_features(
+        &self,
+    ) -> &'static [(&'static str, StabilityUncomputed, ImpliedFeatures)] {
         match &*self.arch {
             "arm" => ARM_FEATURES,
             "aarch64" | "arm64ec" => AARCH64_FEATURES,
@@ -628,6 +804,7 @@ impl super::spec::Target {
             "loongarch64" => LOONGARCH_FEATURES,
             "s390x" => IBMZ_FEATURES,
             "sparc" | "sparc64" => SPARC_FEATURES,
+            "m68k" => M68K_FEATURES,
             _ => &[],
         }
     }
@@ -638,14 +815,14 @@ 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,
             "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
-            "bpf" => &[], // no vector ABI
+            "bpf" | "m68k" => &[], // no vector ABI
             "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
             // FIXME: for some tier3 targets, we are overly cautious and always give warnings
             // when passing args in vector registers.
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index f856a8d7abb..5a62a4c3bd5 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -63,10 +63,11 @@ use rustc_hir::{self as hir};
 use rustc_macros::extension;
 use rustc_middle::bug;
 use rustc_middle::dep_graph::DepContext;
+use rustc_middle::traits::PatternOriginExpr;
 use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt};
 use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, with_forced_trimmed_paths};
 use rustc_middle::ty::{
-    self, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
+    self, List, ParamEnv, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
     TypeVisitableExt,
 };
 use rustc_span::def_id::LOCAL_CRATE;
@@ -77,7 +78,7 @@ use crate::error_reporting::TypeErrCtxt;
 use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
 use crate::infer;
 use crate::infer::relate::{self, RelateResult, TypeRelation};
-use crate::infer::{InferCtxt, TypeTrace, ValuePairs};
+use crate::infer::{InferCtxt, InferCtxtExt as _, TypeTrace, ValuePairs};
 use crate::solve::deeply_normalize_for_diagnostics;
 use crate::traits::{
     IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
@@ -433,15 +434,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         cause: &ObligationCause<'tcx>,
         exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
         terr: TypeError<'tcx>,
+        param_env: Option<ParamEnv<'tcx>>,
     ) {
         match *cause.code() {
-            ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => {
-                let ty = self.resolve_vars_if_possible(root_ty);
-                if !matches!(ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)))
-                {
+            ObligationCauseCode::Pattern {
+                origin_expr: Some(origin_expr),
+                span: Some(span),
+                root_ty,
+            } => {
+                let expected_ty = self.resolve_vars_if_possible(root_ty);
+                if !matches!(
+                    expected_ty.kind(),
+                    ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_))
+                ) {
                     // don't show type `_`
                     if span.desugaring_kind() == Some(DesugaringKind::ForLoop)
-                        && let ty::Adt(def, args) = ty.kind()
+                        && let ty::Adt(def, args) = expected_ty.kind()
                         && Some(def.did()) == self.tcx.get_diagnostic_item(sym::Option)
                     {
                         err.span_label(
@@ -449,22 +457,48 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             format!("this is an iterator with items of type `{}`", args.type_at(0)),
                         );
                     } else {
-                        err.span_label(span, format!("this expression has type `{ty}`"));
+                        err.span_label(span, format!("this expression has type `{expected_ty}`"));
                     }
                 }
                 if let Some(ty::error::ExpectedFound { found, .. }) = exp_found
-                    && ty.boxed_ty() == Some(found)
-                    && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
+                    && let Ok(mut peeled_snippet) =
+                        self.tcx.sess.source_map().span_to_snippet(origin_expr.peeled_span)
                 {
-                    err.span_suggestion(
-                        span,
-                        "consider dereferencing the boxed value",
-                        format!("*{snippet}"),
-                        Applicability::MachineApplicable,
-                    );
+                    // Parentheses are needed for cases like as casts.
+                    // We use the peeled_span for deref suggestions.
+                    // It's also safe to use for box, since box only triggers if there
+                    // wasn't a reference to begin with.
+                    if origin_expr.peeled_prefix_suggestion_parentheses {
+                        peeled_snippet = format!("({peeled_snippet})");
+                    }
+
+                    // Try giving a box suggestion first, as it is a special case of the
+                    // deref suggestion.
+                    if expected_ty.boxed_ty() == Some(found) {
+                        err.span_suggestion_verbose(
+                            span,
+                            "consider dereferencing the boxed value",
+                            format!("*{peeled_snippet}"),
+                            Applicability::MachineApplicable,
+                        );
+                    } else if let Some(param_env) = param_env
+                        && let Some(prefix) = self.should_deref_suggestion_on_mismatch(
+                            param_env,
+                            found,
+                            expected_ty,
+                            origin_expr,
+                        )
+                    {
+                        err.span_suggestion_verbose(
+                            span,
+                            "consider dereferencing to access the inner value using the Deref trait",
+                            format!("{prefix}{peeled_snippet}"),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
                 }
             }
-            ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => {
+            ObligationCauseCode::Pattern { origin_expr: None, span: Some(span), .. } => {
                 err.span_label(span, "expected due to this");
             }
             ObligationCauseCode::BlockTailExpression(
@@ -618,6 +652,45 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         }
     }
 
+    /// Determines whether deref_to == <deref_from as Deref>::Target, and if so,
+    /// returns a prefix that should be added to deref_from as a suggestion.
+    fn should_deref_suggestion_on_mismatch(
+        &self,
+        param_env: ParamEnv<'tcx>,
+        deref_to: Ty<'tcx>,
+        deref_from: Ty<'tcx>,
+        origin_expr: PatternOriginExpr,
+    ) -> Option<String> {
+        // origin_expr contains stripped away versions of our expression.
+        // We'll want to use that to avoid suggesting things like *&x.
+        // However, the type that we have access to hasn't been stripped away,
+        // so we need to ignore the first n dereferences, where n is the number
+        // that's been stripped away in origin_expr.
+
+        // Find a way to autoderef from deref_from to deref_to.
+        let Some((num_derefs, (after_deref_ty, _))) = (self.autoderef_steps)(deref_from)
+            .into_iter()
+            .enumerate()
+            .find(|(_, (ty, _))| self.infcx.can_eq(param_env, *ty, deref_to))
+        else {
+            return None;
+        };
+
+        if num_derefs <= origin_expr.peeled_count {
+            return None;
+        }
+
+        let deref_part = "*".repeat(num_derefs - origin_expr.peeled_count);
+
+        // If the user used a reference in the original expression, they probably
+        // want the suggestion to still give a reference.
+        if deref_from.is_ref() && !after_deref_ty.is_ref() {
+            Some(format!("&{deref_part}"))
+        } else {
+            Some(deref_part)
+        }
+    }
+
     /// Given that `other_ty` is the same as a type argument for `name` in `sub`, populate `value`
     /// highlighting `name` and every type argument that isn't at `pos` (which is `other_ty`), and
     /// populate `other_value` with `other_ty`.
@@ -1406,8 +1479,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             Variable(ty::error::ExpectedFound<Ty<'a>>),
             Fixed(&'static str),
         }
-        let (expected_found, exp_found, is_simple_error, values) = match values {
-            None => (None, Mismatch::Fixed("type"), false, None),
+        let (expected_found, exp_found, is_simple_error, values, param_env) = match values {
+            None => (None, Mismatch::Fixed("type"), false, None, None),
             Some(ty::ParamEnvAnd { param_env, value: values }) => {
                 let mut values = self.resolve_vars_if_possible(values);
                 if self.next_trait_solver() {
@@ -1459,7 +1532,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     diag.downgrade_to_delayed_bug();
                     return;
                 };
-                (Some(vals), exp_found, is_simple_error, Some(values))
+                (Some(vals), exp_found, is_simple_error, Some(values), Some(param_env))
             }
         };
 
@@ -1791,7 +1864,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         // It reads better to have the error origin as the final
         // thing.
-        self.note_error_origin(diag, cause, exp_found, terr);
+        self.note_error_origin(diag, cause, exp_found, terr, param_env);
 
         debug!(?diag);
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index fc2d0ba36f0..08775df5ac9 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -210,7 +210,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code()
             {
                 ObligationCauseCode::Pattern { span: Some(then_span), origin_expr, .. } => {
-                    origin_expr.then_some(ConsiderAddingAwait::FutureSugg {
+                    origin_expr.is_some().then_some(ConsiderAddingAwait::FutureSugg {
                         span: then_span.shrink_to_hi(),
                     })
                 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index f10314c1c9e..dac4a03bf75 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -1,11 +1,12 @@
 use std::iter;
 use std::path::PathBuf;
 
-use rustc_ast::{AttrArgs, AttrKind, Attribute, MetaItemInner};
+use rustc_ast::MetaItemInner;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::codes::*;
 use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::{AttrArgs, AttrKind, Attribute};
 use rustc_macros::LintDiagnostic;
 use rustc_middle::bug;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
@@ -639,7 +640,7 @@ impl<'tcx> OnUnimplementedDirective {
                 let report_span = match &item.args {
                     AttrArgs::Empty => item.path.span,
                     AttrArgs::Delimited(args) => args.dspan.entire(),
-                    AttrArgs::Eq { eq_span, value } => eq_span.to(value.span()),
+                    AttrArgs::Eq { eq_span, expr } => eq_span.to(expr.span),
                 };
 
                 if let Some(item_def_id) = item_def_id.as_local() {
@@ -654,7 +655,7 @@ impl<'tcx> OnUnimplementedDirective {
             }
         } else if is_diagnostic_namespace_variant {
             match &attr.kind {
-                AttrKind::Normal(p) if !matches!(p.item.args, AttrArgs::Empty) => {
+                AttrKind::Normal(p) if !matches!(p.args, AttrArgs::Empty) => {
                     if let Some(item_def_id) = item_def_id.as_local() {
                         tcx.emit_node_span_lint(
                             UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 94682f501a8..cc8941b9224 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -20,7 +20,8 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{
-    CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node, is_range_literal,
+    CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node, expr_needs_parens,
+    is_range_literal,
 };
 use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk};
 use rustc_middle::hir::map;
@@ -1391,13 +1392,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         let Some(expr) = expr_finder.result else {
                             return false;
                         };
-                        let needs_parens = match expr.kind {
-                            // parenthesize if needed (Issue #46756)
-                            hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
-                            // parenthesize borrows of range literals (Issue #54505)
-                            _ if is_range_literal(expr) => true,
-                            _ => false,
-                        };
+                        let needs_parens = expr_needs_parens(expr);
 
                         let span = if needs_parens { span } else { span.shrink_to_lo() };
                         let suggestions = if !needs_parens {
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/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index 07fb2efb7fe..b17a489a857 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -128,7 +128,9 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>(
             Err(_) => Err(EvaluationFailure::NoSolution),
             Ok(Some(source)) => match source {
                 ImplSource::UserDefined(impl_) => {
-                    if tcx.constness(impl_.impl_def_id) != hir::Constness::Const {
+                    if tcx.impl_trait_header(impl_.impl_def_id).unwrap().constness
+                        != hir::Constness::Const
+                    {
                         return Err(EvaluationFailure::NoSolution);
                     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index d216ae72913..7a67b943e94 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -84,7 +84,7 @@ pub fn type_allowed_to_implement_copy<'tcx>(
         return Err(CopyImplementationError::HasDestructor);
     }
 
-    if impl_safety == hir::Safety::Safe && self_type.has_unsafe_fields() {
+    if impl_safety.is_safe() && self_type.has_unsafe_fields() {
         return Err(CopyImplementationError::HasUnsafeFields);
     }
 
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/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs
index dc3f5544613..254dee794f1 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs
@@ -3,7 +3,7 @@ use rustc_infer::traits::Obligation;
 use rustc_middle::traits::query::NoSolution;
 pub use rustc_middle::traits::query::type_op::AscribeUserType;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
-use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, UserType};
+use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, UserTypeKind};
 use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument};
 
@@ -46,12 +46,18 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>(
     let (param_env, AscribeUserType { mir_ty, user_ty }) = key.into_parts();
     debug!("type_op_ascribe_user_type: mir_ty={:?} user_ty={:?}", mir_ty, user_ty);
     let span = span.unwrap_or(DUMMY_SP);
-    match user_ty {
-        UserType::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
-        UserType::TypeOf(def_id, user_args) => {
+    match user_ty.kind {
+        UserTypeKind::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
+        UserTypeKind::TypeOf(def_id, user_args) => {
             relate_mir_and_user_args(ocx, param_env, span, mir_ty, def_id, user_args)?
         }
     };
+
+    // Enforce any bounds that come from impl trait in bindings.
+    ocx.register_obligations(user_ty.bounds.iter().map(|clause| {
+        Obligation::new(ocx.infcx.tcx, ObligationCause::dummy_with_span(span), param_env, clause)
+    }));
+
     Ok(())
 }
 
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/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index f96487cc53c..dfd090b3956 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -5,8 +5,8 @@ use serde::Serialize;
 use crate::compiler_interface::with;
 use crate::mir::pretty::function_body;
 use crate::ty::{
-    AdtDef, ClosureDef, CoroutineDef, GenericArgs, MirConst, Movability, Region, RigidTy, Ty,
-    TyConst, TyKind, VariantIdx,
+    AdtDef, ClosureDef, CoroutineClosureDef, CoroutineDef, GenericArgs, MirConst, Movability,
+    Region, RigidTy, Ty, TyConst, TyKind, VariantIdx,
 };
 use crate::{Error, Opaque, Span, Symbol};
 
@@ -617,6 +617,9 @@ impl Rvalue {
                 AggregateKind::Coroutine(def, ref args, mov) => {
                     Ok(Ty::new_coroutine(def, args.clone(), mov))
                 }
+                AggregateKind::CoroutineClosure(def, ref args) => {
+                    Ok(Ty::new_coroutine_closure(def, args.clone()))
+                }
                 AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
             },
             Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
@@ -633,6 +636,7 @@ pub enum AggregateKind {
     Closure(ClosureDef, GenericArgs),
     // FIXME(stable_mir): Movability here is redundant
     Coroutine(CoroutineDef, GenericArgs, Movability),
+    CoroutineClosure(CoroutineClosureDef, GenericArgs),
     RawPtr(Ty, Mutability),
 }
 
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index 01a50d46b2d..93ed32e258a 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -410,6 +410,10 @@ fn pretty_aggregate<W: Write>(
             write!(writer, "{{coroutine@{}}}(", def.span().diagnostic())?;
             ")"
         }
+        AggregateKind::CoroutineClosure(def, _) => {
+            write!(writer, "{{coroutine-closure@{}}}(", def.span().diagnostic())?;
+            ")"
+        }
         AggregateKind::RawPtr(ty, mutability) => {
             write!(
                 writer,
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 9ce72f155f9..d7eb435e13f 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -63,6 +63,11 @@ impl Ty {
         Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
     }
 
+    /// Create a new closure type.
+    pub fn new_coroutine_closure(def: CoroutineClosureDef, args: GenericArgs) -> Ty {
+        Ty::from_rigid_kind(RigidTy::CoroutineClosure(def, args))
+    }
+
     /// Create a new box type that represents `Box<T>`, for the given inner type `T`.
     pub fn new_box(inner_ty: Ty) -> Ty {
         with(|cx| cx.new_box_ty(inner_ty))
@@ -550,6 +555,7 @@ pub enum RigidTy {
     Closure(ClosureDef, GenericArgs),
     // FIXME(stable_mir): Movability here is redundant
     Coroutine(CoroutineDef, GenericArgs, Movability),
+    CoroutineClosure(CoroutineClosureDef, GenericArgs),
     Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
     Never,
     Tuple(Vec<Ty>),
@@ -742,6 +748,11 @@ crate_def! {
 
 crate_def! {
     #[derive(Serialize)]
+    pub CoroutineClosureDef;
+}
+
+crate_def! {
+    #[derive(Serialize)]
     pub ParamDef;
 }
 
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index 48260285408..3533ed2e851 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -168,6 +168,7 @@ impl Visitable for RigidTy {
             | RigidTy::Closure(_, args)
             | RigidTy::Coroutine(_, args, _)
             | RigidTy::CoroutineWitness(_, args)
+            | RigidTy::CoroutineClosure(_, args)
             | RigidTy::FnDef(_, args) => args.visit(visitor),
             RigidTy::FnPtr(sig) => sig.visit(visitor),
             RigidTy::Dynamic(pred, r, _) => {
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/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index cf51a84bb6f..0b6a55297e1 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1869,7 +1869,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
     ///
     /// # Panics
     ///
-    /// Panics if `index` is greater than deque's length
+    /// Panics if `index` is strictly greater than deque's length
     ///
     /// # Examples
     ///
@@ -1884,6 +1884,9 @@ impl<T, A: Allocator> VecDeque<T, A> {
     ///
     /// vec_deque.insert(1, 'd');
     /// assert_eq!(vec_deque, &['a', 'd', 'b', 'c']);
+    ///
+    /// vec_deque.insert(4, 'e');
+    /// assert_eq!(vec_deque, &['a', 'd', 'b', 'c', 'e']);
     /// ```
     #[stable(feature = "deque_extras_15", since = "1.5.0")]
     #[track_caller]
@@ -1928,13 +1931,13 @@ impl<T, A: Allocator> VecDeque<T, A> {
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
-    /// buf.push_back(1);
-    /// buf.push_back(2);
-    /// buf.push_back(3);
-    /// assert_eq!(buf, [1, 2, 3]);
+    /// buf.push_back('a');
+    /// buf.push_back('b');
+    /// buf.push_back('c');
+    /// assert_eq!(buf, ['a', 'b', 'c']);
     ///
-    /// assert_eq!(buf.remove(1), Some(2));
-    /// assert_eq!(buf, [1, 3]);
+    /// assert_eq!(buf.remove(1), Some('b'));
+    /// assert_eq!(buf, ['a', 'c']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_confusables("delete", "take")]
@@ -1982,10 +1985,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
     /// ```
     /// use std::collections::VecDeque;
     ///
-    /// let mut buf: VecDeque<_> = [1, 2, 3].into();
+    /// let mut buf: VecDeque<_> = ['a', 'b', 'c'].into();
     /// let buf2 = buf.split_off(1);
-    /// assert_eq!(buf, [1]);
-    /// assert_eq!(buf2, [2, 3]);
+    /// assert_eq!(buf, ['a']);
+    /// assert_eq!(buf2, ['b', 'c']);
     /// ```
     #[inline]
     #[must_use = "use `.truncate()` if you don't need the other half"]
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/rc.rs b/library/alloc/src/rc.rs
index 7aa1457b1df..bb27fe3c62d 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -2232,12 +2232,20 @@ impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {
 #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
 unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Rc<T, A> {}
 
+//#[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
+unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for UniqueRc<T, A> {}
+
 #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
 unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {}
 
 #[unstable(feature = "deref_pure_trait", issue = "87121")]
 unsafe impl<T: ?Sized, A: Allocator> DerefPure for Rc<T, A> {}
 
+//#[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<T: ?Sized, A: Allocator> DerefPure for UniqueRc<T, A> {}
+
 #[unstable(feature = "legacy_receiver_trait", issue = "none")]
 impl<T: ?Sized> LegacyReceiver for Rc<T> {}
 
@@ -3684,7 +3692,6 @@ fn data_offset_align(align: usize) -> usize {
 /// previous example, `UniqueRc` allows for more flexibility in the construction of cyclic data,
 /// including fallible or async constructors.
 #[unstable(feature = "unique_rc_arc", issue = "112566")]
-#[derive(Debug)]
 pub struct UniqueRc<
     T: ?Sized,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
@@ -3694,12 +3701,253 @@ pub struct UniqueRc<
     alloc: A,
 }
 
+// Not necessary for correctness since `UniqueRc` contains `NonNull`,
+// but having an explicit negative impl is nice for documentation purposes
+// and results in nicer error messages.
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> !Send for UniqueRc<T, A> {}
+
+// Not necessary for correctness since `UniqueRc` contains `NonNull`,
+// but having an explicit negative impl is nice for documentation purposes
+// and results in nicer error messages.
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> !Sync for UniqueRc<T, A> {}
+
 #[unstable(feature = "unique_rc_arc", issue = "112566")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<UniqueRc<U, A>>
     for UniqueRc<T, A>
 {
 }
 
+//#[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<UniqueRc<U>> for UniqueRc<T> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + fmt::Display, A: Allocator> fmt::Display for UniqueRc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for UniqueRc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> fmt::Pointer for UniqueRc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Pointer::fmt(&(&raw const **self), f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for UniqueRc<T, A> {
+    fn borrow(&self) -> &T {
+        &**self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for UniqueRc<T, A> {
+    fn borrow_mut(&mut self) -> &mut T {
+        &mut **self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> AsRef<T> for UniqueRc<T, A> {
+    fn as_ref(&self) -> &T {
+        &**self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> AsMut<T> for UniqueRc<T, A> {
+    fn as_mut(&mut self) -> &mut T {
+        &mut **self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> Unpin for UniqueRc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for UniqueRc<T, A> {
+    /// Equality for two `UniqueRc`s.
+    ///
+    /// Two `UniqueRc`s are equal if their inner values are equal.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five == UniqueRc::new(5));
+    /// ```
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
+
+    /// Inequality for two `UniqueRc`s.
+    ///
+    /// Two `UniqueRc`s are not equal if their inner values are not equal.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five != UniqueRc::new(6));
+    /// ```
+    #[inline]
+    fn ne(&self, other: &Self) -> bool {
+        PartialEq::ne(&**self, &**other)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for UniqueRc<T, A> {
+    /// Partial comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `partial_cmp()` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    /// use std::cmp::Ordering;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueRc::new(6)));
+    /// ```
+    #[inline(always)]
+    fn partial_cmp(&self, other: &UniqueRc<T, A>) -> Option<Ordering> {
+        (**self).partial_cmp(&**other)
+    }
+
+    /// Less-than comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `<` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five < UniqueRc::new(6));
+    /// ```
+    #[inline(always)]
+    fn lt(&self, other: &UniqueRc<T, A>) -> bool {
+        **self < **other
+    }
+
+    /// 'Less than or equal to' comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `<=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five <= UniqueRc::new(5));
+    /// ```
+    #[inline(always)]
+    fn le(&self, other: &UniqueRc<T, A>) -> bool {
+        **self <= **other
+    }
+
+    /// Greater-than comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `>` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five > UniqueRc::new(4));
+    /// ```
+    #[inline(always)]
+    fn gt(&self, other: &UniqueRc<T, A>) -> bool {
+        **self > **other
+    }
+
+    /// 'Greater than or equal to' comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `>=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five >= UniqueRc::new(5));
+    /// ```
+    #[inline(always)]
+    fn ge(&self, other: &UniqueRc<T, A>) -> bool {
+        **self >= **other
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Ord, A: Allocator> Ord for UniqueRc<T, A> {
+    /// Comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `cmp()` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    /// use std::cmp::Ordering;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert_eq!(Ordering::Less, five.cmp(&UniqueRc::new(6)));
+    /// ```
+    #[inline]
+    fn cmp(&self, other: &UniqueRc<T, A>) -> Ordering {
+        (**self).cmp(&**other)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Eq, A: Allocator> Eq for UniqueRc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Hash, A: Allocator> Hash for UniqueRc<T, A> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (**self).hash(state);
+    }
+}
+
 // Depends on A = Global
 impl<T> UniqueRc<T> {
     /// Creates a new `UniqueRc`.
@@ -3791,9 +4039,6 @@ impl<T: ?Sized, A: Allocator> Deref for UniqueRc<T, A> {
     }
 }
 
-#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
-unsafe impl<T: ?Sized> PinCoerceUnsized for UniqueRc<T> {}
-
 #[unstable(feature = "unique_rc_arc", issue = "112566")]
 impl<T: ?Sized, A: Allocator> DerefMut for UniqueRc<T, A> {
     fn deref_mut(&mut self) -> &mut T {
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index c5378d78d59..23d060d2158 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2675,12 +2675,25 @@ pub trait ToString {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Display + ?Sized> ToString for T {
+    #[inline]
+    fn to_string(&self) -> String {
+        <Self as SpecToString>::spec_to_string(self)
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
+trait SpecToString {
+    fn spec_to_string(&self) -> String;
+}
+
+#[cfg(not(no_global_oom_handling))]
+impl<T: fmt::Display + ?Sized> SpecToString for T {
     // A common guideline is to not inline generic functions. However,
     // removing `#[inline]` from this method causes non-negligible regressions.
     // See <https://github.com/rust-lang/rust/pull/74852>, the last attempt
     // to try to remove it.
     #[inline]
-    default fn to_string(&self) -> String {
+    default fn spec_to_string(&self) -> String {
         let mut buf = String::new();
         let mut formatter =
             core::fmt::Formatter::new(&mut buf, core::fmt::FormattingOptions::new());
@@ -2691,42 +2704,34 @@ impl<T: fmt::Display + ?Sized> ToString for T {
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[unstable(feature = "ascii_char", issue = "110998")]
-impl ToString for core::ascii::Char {
+impl SpecToString for core::ascii::Char {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         self.as_str().to_owned()
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "char_to_string_specialization", since = "1.46.0")]
-impl ToString for char {
+impl SpecToString for char {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         String::from(self.encode_utf8(&mut [0; 4]))
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "bool_to_string_specialization", since = "1.68.0")]
-impl ToString for bool {
+impl SpecToString for bool {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         String::from(if *self { "true" } else { "false" })
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "u8_to_string_specialization", since = "1.54.0")]
-impl ToString for u8 {
+impl SpecToString for u8 {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         let mut buf = String::with_capacity(3);
         let mut n = *self;
         if n >= 10 {
@@ -2742,12 +2747,10 @@ impl ToString for u8 {
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "i8_to_string_specialization", since = "1.54.0")]
-impl ToString for i8 {
+impl SpecToString for i8 {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         let mut buf = String::with_capacity(4);
         if self.is_negative() {
             buf.push('-');
@@ -2788,11 +2791,9 @@ macro_rules! to_string_expr_wrap_in_deref {
 macro_rules! to_string_str {
     {$($($x:ident)*),+} => {
         $(
-            #[doc(hidden)]
-            #[stable(feature = "str_to_string_specialization", since = "1.9.0")]
-            impl ToString for to_string_str_wrap_in_ref!($($x)*) {
+            impl SpecToString for to_string_str_wrap_in_ref!($($x)*) {
                 #[inline]
-                fn to_string(&self) -> String {
+                fn spec_to_string(&self) -> String {
                     String::from(to_string_expr_wrap_in_deref!(self ; $($x)*))
                 }
             }
@@ -2816,32 +2817,26 @@ to_string_str! {
     x,
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "cow_str_to_string_specialization", since = "1.17.0")]
-impl ToString for Cow<'_, str> {
+impl SpecToString for Cow<'_, str> {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         self[..].to_owned()
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "string_to_string_specialization", since = "1.17.0")]
-impl ToString for String {
+impl SpecToString for String {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         self.to_owned()
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "fmt_arguments_to_string_specialization", since = "1.71.0")]
-impl ToString for fmt::Arguments<'_> {
+impl SpecToString for fmt::Arguments<'_> {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         crate::fmt::format(*self)
     }
 }
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/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 457be3ae77f..7e7a8ff72c7 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1953,11 +1953,11 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// let mut vec = vec![1, 2, 3];
-    /// vec.insert(1, 4);
-    /// assert_eq!(vec, [1, 4, 2, 3]);
-    /// vec.insert(4, 5);
-    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
+    /// let mut vec = vec!['a', 'b', 'c'];
+    /// vec.insert(1, 'd');
+    /// assert_eq!(vec, ['a', 'd', 'b', 'c']);
+    /// vec.insert(4, 'e');
+    /// assert_eq!(vec, ['a', 'd', 'b', 'c', 'e']);
     /// ```
     ///
     /// # Time complexity
@@ -2024,9 +2024,9 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// let mut v = vec![1, 2, 3];
-    /// assert_eq!(v.remove(1), 2);
-    /// assert_eq!(v, [1, 3]);
+    /// let mut v = vec!['a', 'b', 'c'];
+    /// assert_eq!(v.remove(1), 'b');
+    /// assert_eq!(v, ['a', 'c']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[track_caller]
@@ -2715,10 +2715,10 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// let mut vec = vec![1, 2, 3];
+    /// let mut vec = vec!['a', 'b', 'c'];
     /// let vec2 = vec.split_off(1);
-    /// assert_eq!(vec, [1]);
-    /// assert_eq!(vec2, [2, 3]);
+    /// assert_eq!(vec, ['a']);
+    /// assert_eq!(vec2, ['b', 'c']);
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[inline]
@@ -2982,9 +2982,9 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
     /// vec.resize(3, "world");
     /// assert_eq!(vec, ["hello", "world", "world"]);
     ///
-    /// let mut vec = vec![1, 2, 3, 4];
-    /// vec.resize(2, 0);
-    /// assert_eq!(vec, [1, 2]);
+    /// let mut vec = vec!['a', 'b', 'c', 'd'];
+    /// vec.resize(2, '_');
+    /// assert_eq!(vec, ['a', 'b']);
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "vec_resize", since = "1.5.0")]
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/convert/mod.rs b/library/core/src/convert/mod.rs
index 432e55e8c9a..e468f4f0f7e 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -443,6 +443,7 @@ pub trait AsMut<T: ?Sized> {
 /// [`Vec`]: ../../std/vec/struct.Vec.html
 #[rustc_diagnostic_item = "Into"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[doc(search_unbox)]
 pub trait Into<T>: Sized {
     /// Converts this type into the (usually inferred) input type.
     #[must_use]
@@ -577,6 +578,7 @@ pub trait Into<T>: Sized {
     all(_Self = "&str", T = "alloc::string::String"),
     note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
 ))]
+#[doc(search_unbox)]
 pub trait From<T>: Sized {
     /// Converts to this type from the input type.
     #[rustc_diagnostic_item = "from_fn"]
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 91549f49f9f..9dbea57fa1f 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -2,7 +2,7 @@
 #![stable(feature = "error_in_core", since = "1.81.0")]
 
 use crate::any::TypeId;
-use crate::fmt::{Debug, Display, Formatter, Result};
+use crate::fmt::{self, Debug, Display, Formatter};
 
 /// `Error` is a trait representing the basic expectations for error values,
 /// i.e., values of type `E` in [`Result<T, E>`].
@@ -857,7 +857,7 @@ impl<'a> Request<'a> {
 
 #[unstable(feature = "error_generic_member_access", issue = "99301")]
 impl<'a> Debug for Request<'a> {
-    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.debug_struct("Request").finish_non_exhaustive()
     }
 }
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index af6f0da88de..94341a4da66 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -19,7 +19,7 @@ pub struct Placeholder {
 }
 
 impl Placeholder {
-    #[inline(always)]
+    #[inline]
     pub const fn new(
         position: usize,
         fill: char,
@@ -95,7 +95,7 @@ pub struct Argument<'a> {
 
 #[rustc_diagnostic_item = "ArgumentMethods"]
 impl Argument<'_> {
-    #[inline(always)]
+    #[inline]
     fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> {
         Argument {
             // INVARIANT: this creates an `ArgumentType<'a>` from a `&'a T` and
@@ -109,47 +109,47 @@ impl Argument<'_> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
         Self::new(x, Display::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
         Self::new(x, Debug::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
         Self::new(x, |_, _| Ok(()))
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
         Self::new(x, Octal::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
         Self::new(x, LowerHex::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
         Self::new(x, UpperHex::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
         Self::new(x, Pointer::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
         Self::new(x, Binary::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
         Self::new(x, LowerExp::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
         Self::new(x, UpperExp::fmt)
     }
-    #[inline(always)]
+    #[inline]
     pub fn from_usize(x: &usize) -> Argument<'_> {
         Argument { ty: ArgumentType::Count(*x) }
     }
@@ -164,7 +164,7 @@ impl Argument<'_> {
     // it here is an explicit CFI violation.
     #[allow(inline_no_sanitize)]
     #[no_sanitize(cfi, kcfi)]
-    #[inline(always)]
+    #[inline]
     pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         match self.ty {
             // SAFETY:
@@ -180,7 +180,7 @@ impl Argument<'_> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub(super) fn as_usize(&self) -> Option<usize> {
         match self.ty {
             ArgumentType::Count(count) => Some(count),
@@ -198,7 +198,7 @@ impl Argument<'_> {
     /// let f = format_args!("{}", "a");
     /// println!("{f}");
     /// ```
-    #[inline(always)]
+    #[inline]
     pub fn none() -> [Self; 0] {
         []
     }
@@ -215,7 +215,7 @@ pub struct UnsafeArg {
 impl UnsafeArg {
     /// See documentation where `UnsafeArg` is required to know when it is safe to
     /// create and use `UnsafeArg`.
-    #[inline(always)]
+    #[inline]
     pub unsafe fn new() -> Self {
         Self { _private: () }
     }
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index c59e4414d37..9c054b99a27 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -310,6 +310,8 @@ pub fn spin_loop() {
 /// behavior in the calling code. This property makes `black_box` useful for writing code in which
 /// certain optimizations are not desired, such as benchmarks.
 ///
+/// <div class="warning">
+///
 /// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
 /// extent to which it can block optimisations may vary depending upon the platform and code-gen
 /// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the
@@ -317,6 +319,8 @@ pub fn spin_loop() {
 /// This also means that this function does not offer any guarantees for cryptographic or security
 /// purposes.
 ///
+/// </div>
+///
 /// [`std::convert::identity`]: crate::convert::identity
 ///
 /// # When is this useful?
@@ -357,7 +361,7 @@ pub fn spin_loop() {
 /// ```
 /// use std::hint::black_box;
 ///
-/// // Same `contains` function
+/// // Same `contains` function.
 /// fn contains(haystack: &[&str], needle: &str) -> bool {
 ///     haystack.iter().any(|x| x == &needle)
 /// }
@@ -366,8 +370,13 @@ pub fn spin_loop() {
 ///     let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
 ///     let needle = "ghi";
 ///     for _ in 0..10 {
-///         // Adjust our benchmark loop contents
-///         black_box(contains(black_box(&haystack), black_box(needle)));
+///         // Force the compiler to run `contains`, even though it is a pure function whose
+///         // results are unused.
+///         black_box(contains(
+///             // Prevent the compiler from making assumptions about the input.
+///             black_box(&haystack),
+///             black_box(needle),
+///         ));
 ///     }
 /// }
 /// ```
@@ -382,6 +391,83 @@ pub fn spin_loop() {
 ///
 /// This makes our benchmark much more realistic to how the function would actually be used, where
 /// arguments are usually not known at compile time and the result is used in some way.
+///
+/// # How to use this
+///
+/// In practice, `black_box` serves two purposes:
+///
+/// 1. It prevents the compiler from making optimizations related to the value returned by `black_box`
+/// 2. It forces the value passed to `black_box` to be calculated, even if the return value of `black_box` is unused
+///
+/// ```
+/// use std::hint::black_box;
+///
+/// let zero = 0;
+/// let five = 5;
+///
+/// // The compiler will see this and remove the `* five` call, because it knows that multiplying
+/// // any integer by 0 will result in 0.
+/// let c = zero * five;
+///
+/// // Adding `black_box` here disables the compiler's ability to reason about the first operand in the multiplication.
+/// // It is forced to assume that it can be any possible number, so it cannot remove the `* five`
+/// // operation.
+/// let c = black_box(zero) * five;
+/// ```
+///
+/// While most cases will not be as clear-cut as the above example, it still illustrates how
+/// `black_box` can be used. When benchmarking a function, you usually want to wrap its inputs in
+/// `black_box` so the compiler cannot make optimizations that would be unrealistic in real-life
+/// use.
+///
+/// ```
+/// use std::hint::black_box;
+///
+/// // This is a simple function that increments its input by 1. Note that it is pure, meaning it
+/// // has no side-effects. This function has no effect if its result is unused. (An example of a
+/// // function *with* side-effects is `println!()`.)
+/// fn increment(x: u8) -> u8 {
+///     x + 1
+/// }
+///
+/// // Here, we call `increment` but discard its result. The compiler, seeing this and knowing that
+/// // `increment` is pure, will eliminate this function call entirely. This may not be desired,
+/// // though, especially if we're trying to track how much time `increment` takes to execute.
+/// let _ = increment(black_box(5));
+///
+/// // Here, we force `increment` to be executed. This is because the compiler treats `black_box`
+/// // as if it has side-effects, and thus must compute its input.
+/// let _ = black_box(increment(black_box(5)));
+/// ```
+///
+/// There may be additional situations where you want to wrap the result of a function in
+/// `black_box` to force its execution. This is situational though, and may not have any effect
+/// (such as when the function returns a zero-sized type such as [`()` unit][unit]).
+///
+/// Note that `black_box` has no effect on how its input is treated, only its output. As such,
+/// expressions passed to `black_box` may still be optimized:
+///
+/// ```
+/// use std::hint::black_box;
+///
+/// // The compiler sees this...
+/// let y = black_box(5 * 10);
+///
+/// // ...as this. As such, it will likely simplify `5 * 10` to just `50`.
+/// let _0 = 5 * 10;
+/// let y = black_box(_0);
+/// ```
+///
+/// In the above example, the `5 * 10` expression is considered distinct from the `black_box` call,
+/// and thus is still optimized by the compiler. You can prevent this by moving the multiplication
+/// operation outside of `black_box`:
+///
+/// ```
+/// use std::hint::black_box;
+///
+/// // No assumptions can be made about either operand, so the multiplication is not optimized out.
+/// let y = black_box(5) * black_box(10);
+/// ```
 #[inline]
 #[stable(feature = "bench_black_box", since = "1.66.0")]
 #[rustc_const_unstable(feature = "const_black_box", issue = "none")]
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index c3c7288e389..8ab1c26f95e 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -493,15 +493,64 @@ impl Extend<()> for () {
 }
 
 macro_rules! spec_tuple_impl {
-    ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), ) => {
-        spec_tuple_impl!($trait_name, $default_fn_name, #[doc(fake_variadic)] #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in RUSTC_CURRENT_VERSION."] => ($ty_name, $var_name, $extend_ty_name, $cnt),);
+    (
+        (
+            $ty_name:ident, $var_name:ident, $extend_ty_name: ident,
+            $trait_name:ident, $default_fn_name:ident, $cnt:tt
+        ),
+    ) => {
+        spec_tuple_impl!(
+            $trait_name,
+            $default_fn_name,
+            #[doc(fake_variadic)]
+            #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \
+                     1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \
+                     CURRENT_RUSTC_VERSION."]
+            => ($ty_name, $var_name, $extend_ty_name, $cnt),
+        );
     };
-    ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), $(($ty_names:ident, $var_names:ident,  $extend_ty_names:ident, $trait_names:ident, $default_fn_names:ident, $cnts:tt),)*) => {
-
-        spec_tuple_impl!($(($ty_names, $var_names, $extend_ty_names, $trait_names, $default_fn_names, $cnts),)*);
-        spec_tuple_impl!($trait_name, $default_fn_name, #[doc(hidden)] => ($ty_name, $var_name, $extend_ty_name, $cnt), $(($ty_names, $var_names, $extend_ty_names, $cnts),)*);
+    (
+        (
+            $ty_name:ident, $var_name:ident, $extend_ty_name: ident,
+            $trait_name:ident, $default_fn_name:ident, $cnt:tt
+        ),
+        $(
+            (
+                $ty_names:ident, $var_names:ident,  $extend_ty_names:ident,
+                $trait_names:ident, $default_fn_names:ident, $cnts:tt
+            ),
+        )*
+    ) => {
+        spec_tuple_impl!(
+            $(
+                (
+                    $ty_names, $var_names, $extend_ty_names,
+                    $trait_names, $default_fn_names, $cnts
+                ),
+            )*
+        );
+        spec_tuple_impl!(
+            $trait_name,
+            $default_fn_name,
+            #[doc(hidden)]
+            => (
+                $ty_name, $var_name, $extend_ty_name, $cnt
+            ),
+            $(
+                (
+                    $ty_names, $var_names, $extend_ty_names, $cnts
+                ),
+            )*
+        );
     };
-    ($trait_name:ident, $default_fn_name:ident, #[$meta:meta] $(#[$doctext:meta])? => $(($ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt),)*) => {
+    (
+        $trait_name:ident, $default_fn_name:ident, #[$meta:meta]
+        $(#[$doctext:meta])? => $(
+            (
+                $ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt
+            ),
+        )*
+    ) => {
         #[$meta]
         $(#[$doctext])?
         #[stable(feature = "extend_for_tuple", since = "1.56.0")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index fde6887c5ab..d45cb01910f 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -354,6 +354,8 @@ pub mod random;
 pub mod range;
 pub mod result;
 pub mod sync;
+#[unstable(feature = "unsafe_binders", issue = "130516")]
+pub mod unsafe_binder;
 
 pub mod fmt;
 pub mod hash;
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/mod.rs b/library/core/src/ptr/mod.rs
index bc4c4e168a3..51ab2054b3b 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -200,7 +200,7 @@
 //!
 //! But it *is* still sound to:
 //!
-//! * Create a pointer without provenance from just an address (see [`ptr::dangling`]). Such a
+//! * Create a pointer without provenance from just an address (see [`without_provenance`]). Such a
 //!   pointer cannot be used for memory accesses (except for zero-sized accesses). This can still be
 //!   useful for sentinel values like `null` *or* to represent a tagged pointer that will never be
 //!   dereferenceable. In general, it is always sound for an integer to pretend to be a pointer "for
@@ -314,8 +314,8 @@
 //! }
 //! ```
 //!
-//! (Yes, if you've been using AtomicUsize for pointers in concurrent datastructures, you should
-//! be using AtomicPtr instead. If that messes up the way you atomically manipulate pointers,
+//! (Yes, if you've been using [`AtomicUsize`] for pointers in concurrent datastructures, you should
+//! be using [`AtomicPtr`] instead. If that messes up the way you atomically manipulate pointers,
 //! we would like to know why, and what needs to be done to fix it.)
 //!
 //! Situations where a valid pointer *must* be created from just an address, such as baremetal code
@@ -381,7 +381,8 @@
 //! [`with_addr`]: pointer::with_addr
 //! [`map_addr`]: pointer::map_addr
 //! [`addr`]: pointer::addr
-//! [`ptr::dangling`]: core::ptr::dangling
+//! [`AtomicUsize`]: crate::sync::atomic::AtomicUsize
+//! [`AtomicPtr`]: crate::sync::atomic::AtomicPtr
 //! [`expose_provenance`]: pointer::expose_provenance
 //! [`with_exposed_provenance`]: with_exposed_provenance
 //! [Miri]: https://github.com/rust-lang/miri
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/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 97a7338b0bf..de00bdf8594 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1883,23 +1883,23 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// let v = [1, 2, 3, 4, 5, 6];
+    /// let v = ['a', 'b', 'c'];
     ///
     /// {
     ///    let (left, right) = v.split_at(0);
     ///    assert_eq!(left, []);
-    ///    assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+    ///    assert_eq!(right, ['a', 'b', 'c']);
     /// }
     ///
     /// {
     ///     let (left, right) = v.split_at(2);
-    ///     assert_eq!(left, [1, 2]);
-    ///     assert_eq!(right, [3, 4, 5, 6]);
+    ///     assert_eq!(left, ['a', 'b']);
+    ///     assert_eq!(right, ['c']);
     /// }
     ///
     /// {
-    ///     let (left, right) = v.split_at(6);
-    ///     assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    ///     let (left, right) = v.split_at(3);
+    ///     assert_eq!(left, ['a', 'b', 'c']);
     ///     assert_eq!(right, []);
     /// }
     /// ```
@@ -1969,23 +1969,23 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// let v = [1, 2, 3, 4, 5, 6];
+    /// let v = ['a', 'b', 'c'];
     ///
     /// unsafe {
     ///    let (left, right) = v.split_at_unchecked(0);
     ///    assert_eq!(left, []);
-    ///    assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+    ///    assert_eq!(right, ['a', 'b', 'c']);
     /// }
     ///
     /// unsafe {
     ///     let (left, right) = v.split_at_unchecked(2);
-    ///     assert_eq!(left, [1, 2]);
-    ///     assert_eq!(right, [3, 4, 5, 6]);
+    ///     assert_eq!(left, ['a', 'b']);
+    ///     assert_eq!(right, ['c']);
     /// }
     ///
     /// unsafe {
-    ///     let (left, right) = v.split_at_unchecked(6);
-    ///     assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    ///     let (left, right) = v.split_at_unchecked(3);
+    ///     assert_eq!(left, ['a', 'b', 'c']);
     ///     assert_eq!(right, []);
     /// }
     /// ```
diff --git a/library/core/src/unsafe_binder.rs b/library/core/src/unsafe_binder.rs
new file mode 100644
index 00000000000..98f53e07d9d
--- /dev/null
+++ b/library/core/src/unsafe_binder.rs
@@ -0,0 +1,25 @@
+//! Operators used to turn types into unsafe binders and back.
+
+/// Unwrap an unsafe binder into its underlying type.
+#[allow_internal_unstable(builtin_syntax)]
+#[unstable(feature = "unsafe_binders", issue = "130516")]
+pub macro unwrap_binder {
+    ($expr:expr) => {
+        builtin # unwrap_binder ( $expr )
+    },
+    ($expr:expr ; $ty:ty) => {
+        builtin # unwrap_binder ( $expr, $ty )
+    },
+}
+
+/// Wrap a type into an unsafe binder.
+#[allow_internal_unstable(builtin_syntax)]
+#[unstable(feature = "unsafe_binders", issue = "130516")]
+pub macro wrap_binder {
+    ($expr:expr) => {
+        builtin # wrap_binder ( $expr )
+    },
+    ($expr:expr ; $ty:ty) => {
+        builtin # wrap_binder ( $expr, $ty )
+    },
+}
diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs
index edad6e7ac39..6a1cecd69fb 100644
--- a/library/proc_macro/src/bridge/symbol.rs
+++ b/library/proc_macro/src/bridge/symbol.rs
@@ -91,12 +91,6 @@ impl fmt::Debug for Symbol {
     }
 }
 
-impl ToString for Symbol {
-    fn to_string(&self) -> String {
-        self.with(|s| s.to_owned())
-    }
-}
-
 impl fmt::Display for Symbol {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.with(|s| fmt::Display::fmt(s, f))
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 4aa47ce4e4f..26a09f0daca 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -19,9 +19,6 @@
 )]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-// This library is copied into rust-analyzer to allow loading rustc compiled proc macros.
-// Please avoid unstable features where possible to minimize the amount of changes necessary
-// to make it compile with rust-analyzer on stable.
 #![feature(staged_api)]
 #![feature(allow_internal_unstable)]
 #![feature(decl_macro)]
@@ -30,7 +27,6 @@
 #![feature(panic_can_unwind)]
 #![feature(restricted_std)]
 #![feature(rustc_attrs)]
-#![feature(min_specialization)]
 #![feature(extend_one)]
 #![recursion_limit = "256"]
 #![allow(internal_features)]
@@ -185,16 +181,6 @@ impl FromStr for TokenStream {
     }
 }
 
-// N.B., the bridge only provides `to_string`, implement `fmt::Display`
-// based on it (the reverse of the usual relationship between the two).
-#[doc(hidden)]
-#[stable(feature = "proc_macro_lib", since = "1.15.0")]
-impl ToString for TokenStream {
-    fn to_string(&self) -> String {
-        self.0.as_ref().map(|t| t.to_string()).unwrap_or_default()
-    }
-}
-
 /// Prints the token stream as a string that is supposed to be losslessly convertible back
 /// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s
 /// with `Delimiter::None` delimiters and negative numeric literals.
@@ -210,7 +196,10 @@ impl ToString for TokenStream {
 impl fmt::Display for TokenStream {
     #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
+        match &self.0 {
+            Some(ts) => write!(f, "{}", ts.to_string()),
+            None => Ok(()),
+        }
     }
 }
 
@@ -756,21 +745,6 @@ impl From<Literal> for TokenTree {
     }
 }
 
-// N.B., the bridge only provides `to_string`, implement `fmt::Display`
-// based on it (the reverse of the usual relationship between the two).
-#[doc(hidden)]
-#[stable(feature = "proc_macro_lib", since = "1.15.0")]
-impl ToString for TokenTree {
-    fn to_string(&self) -> String {
-        match *self {
-            TokenTree::Group(ref t) => t.to_string(),
-            TokenTree::Ident(ref t) => t.to_string(),
-            TokenTree::Punct(ref t) => t.to_string(),
-            TokenTree::Literal(ref t) => t.to_string(),
-        }
-    }
-}
-
 /// Prints the token tree as a string that is supposed to be losslessly convertible back
 /// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
 /// with `Delimiter::None` delimiters and negative numeric literals.
@@ -786,7 +760,12 @@ impl ToString for TokenTree {
 impl fmt::Display for TokenTree {
     #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
+        match self {
+            TokenTree::Group(t) => write!(f, "{t}"),
+            TokenTree::Ident(t) => write!(f, "{t}"),
+            TokenTree::Punct(t) => write!(f, "{t}"),
+            TokenTree::Literal(t) => write!(f, "{t}"),
+        }
     }
 }
 
@@ -912,16 +891,6 @@ impl Group {
     }
 }
 
-// N.B., the bridge only provides `to_string`, implement `fmt::Display`
-// based on it (the reverse of the usual relationship between the two).
-#[doc(hidden)]
-#[stable(feature = "proc_macro_lib", since = "1.15.0")]
-impl ToString for Group {
-    fn to_string(&self) -> String {
-        TokenStream::from(TokenTree::from(self.clone())).to_string()
-    }
-}
-
 /// Prints the group as a string that should be losslessly convertible back
 /// into the same group (modulo spans), except for possibly `TokenTree::Group`s
 /// with `Delimiter::None` delimiters.
@@ -929,7 +898,7 @@ impl ToString for Group {
 impl fmt::Display for Group {
     #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
+        write!(f, "{}", TokenStream::from(TokenTree::from(self.clone())))
     }
 }
 
@@ -1035,14 +1004,6 @@ impl Punct {
     }
 }
 
-#[doc(hidden)]
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl ToString for Punct {
-    fn to_string(&self) -> String {
-        self.as_char().to_string()
-    }
-}
-
 /// Prints the punctuation character as a string that should be losslessly convertible
 /// back into the same character.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
@@ -1138,14 +1099,6 @@ impl Ident {
     }
 }
 
-#[doc(hidden)]
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl ToString for Ident {
-    fn to_string(&self) -> String {
-        self.0.sym.with(|sym| if self.0.is_raw { ["r#", sym].concat() } else { sym.to_owned() })
-    }
-}
-
 /// Prints the identifier as a string that should be losslessly convertible back
 /// into the same identifier.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
@@ -1520,14 +1473,6 @@ impl FromStr for Literal {
     }
 }
 
-#[doc(hidden)]
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl ToString for Literal {
-    fn to_string(&self) -> String {
-        self.with_stringify_parts(|parts| parts.concat())
-    }
-}
-
 /// Prints the literal as a string that should be losslessly convertible
 /// back into the same literal (except for possible rounding for floating point literals).
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 49a03220039..2b97f73f79a 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)]
@@ -374,6 +373,7 @@
 #![feature(thin_box)]
 #![feature(try_reserve_kind)]
 #![feature(try_with_capacity)]
+#![feature(unique_rc_arc)]
 #![feature(vec_into_raw_parts)]
 // tidy-alphabetical-end
 //
@@ -545,6 +545,8 @@ pub use core::u64;
 #[stable(feature = "i128", since = "1.26.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::u128;
+#[unstable(feature = "unsafe_binders", issue = "130516")]
+pub use core::unsafe_binder;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::usize;
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 388b8a88a1a..abb13b75f50 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -428,6 +428,14 @@ impl<T: AsFd + ?Sized> AsFd for crate::rc::Rc<T> {
     }
 }
 
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: AsFd + ?Sized> AsFd for crate::rc::UniqueRc<T> {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        (**self).as_fd()
+    }
+}
+
 #[stable(feature = "asfd_ptrs", since = "1.64.0")]
 impl<T: AsFd + ?Sized> AsFd for Box<T> {
     #[inline]
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index 0d99d5492a2..22f5528248a 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -266,6 +266,14 @@ impl<T: AsRawFd> AsRawFd for crate::rc::Rc<T> {
     }
 }
 
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: AsRawFd + ?Sized> AsRawFd for crate::rc::UniqueRc<T> {
+    #[inline]
+    fn as_raw_fd(&self) -> RawFd {
+        (**self).as_raw_fd()
+    }
+}
+
 #[stable(feature = "asrawfd_ptrs", since = "1.63.0")]
 impl<T: AsRawFd> AsRawFd for Box<T> {
     #[inline]
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/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index a4fa94e2b96..76f5f549dd2 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -485,6 +485,14 @@ impl<T: AsHandle + ?Sized> AsHandle for crate::rc::Rc<T> {
     }
 }
 
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: AsHandle + ?Sized> AsHandle for crate::rc::UniqueRc<T> {
+    #[inline]
+    fn as_handle(&self) -> BorrowedHandle<'_> {
+        (**self).as_handle()
+    }
+}
+
 #[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 impl<T: AsHandle + ?Sized> AsHandle for Box<T> {
     #[inline]
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index 272641ea6c7..c6d7bad9440 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -279,6 +279,14 @@ impl<T: AsSocket> AsSocket for crate::rc::Rc<T> {
     }
 }
 
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: AsSocket + ?Sized> AsSocket for crate::rc::UniqueRc<T> {
+    #[inline]
+    fn as_socket(&self) -> BorrowedSocket<'_> {
+        (**self).as_socket()
+    }
+}
+
 #[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 impl<T: AsSocket> AsSocket for Box<T> {
     #[inline]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 5b277a982ee..35e920ab344 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2327,7 +2327,9 @@ impl Path {
             // FIXME: Allow Redox prefixes
             self.has_root() || has_redox_scheme(self.as_u8_slice())
         } else {
-            self.has_root() && (cfg!(any(unix, target_os = "wasi")) || self.prefix().is_some())
+            self.has_root()
+                && (cfg!(any(unix, target_os = "hermit", target_os = "wasi"))
+                    || self.prefix().is_some())
         }
     }
 
diff --git a/library/std/src/pipe.rs b/library/std/src/pipe.rs
index 891032e94a6..06f3fd9fdff 100644
--- a/library/std/src/pipe.rs
+++ b/library/std/src/pipe.rs
@@ -1,20 +1,66 @@
-//! Module for anonymous pipe
+//!  A cross-platform anonymous pipe.
 //!
-//! ```
-//! #![feature(anonymous_pipe)]
+//! This module provides support for anonymous OS pipes, like [pipe] on Linux or [CreatePipe] on
+//! Windows.
+//!
+//! # Behavior
+//!
+//! A pipe is a synchronous, unidirectional data channel between two or more processes, like an
+//! interprocess [`mpsc`](crate::sync::mpsc) provided by the OS. In particular:
+//!
+//! * A read on a [`PipeReader`] blocks until the pipe is non-empty.
+//! * A write on a [`PipeWriter`] blocks when the pipe is full.
+//! * When all copies of a [`PipeWriter`] are closed, a read on the corresponding [`PipeReader`]
+//!   returns EOF.
+//! * [`PipeReader`] can be shared, but only one process will consume the data in the pipe.
+//!
+//! # Capacity
+//!
+//! Pipe capacity is platform dependent. To quote the Linux [man page]:
+//!
+//! > Different implementations have different limits for the pipe capacity. Applications should
+//! > not rely on a particular capacity: an application should be designed so that a reading process
+//! > consumes data as soon as it is available, so that a writing process does not remain blocked.
 //!
+//! # Examples
+//!
+//! ```no_run
+//! #![feature(anonymous_pipe)]
 //! # #[cfg(miri)] fn main() {}
 //! # #[cfg(not(miri))]
 //! # fn main() -> std::io::Result<()> {
-//! let (reader, writer) = std::pipe::pipe()?;
+//! # use std::process::Command;
+//! # use std::io::{Read, Write};
+//! let (ping_rx, mut ping_tx) = std::pipe::pipe()?;
+//! let (mut pong_rx, pong_tx) = std::pipe::pipe()?;
+//!
+//! // Spawn a process that echoes its input.
+//! let mut echo_server = Command::new("cat").stdin(ping_rx).stdout(pong_tx).spawn()?;
+//!
+//! ping_tx.write_all(b"hello")?;
+//! // Close to unblock echo_server's reader.
+//! drop(ping_tx);
+//!
+//! let mut buf = String::new();
+//! // Block until echo_server's writer is closed.
+//! pong_rx.read_to_string(&mut buf)?;
+//! assert_eq!(&buf, "hello");
+//!
+//! echo_server.wait()?;
 //! # Ok(())
 //! # }
 //! ```
-
+//! [pipe]: https://man7.org/linux/man-pages/man2/pipe.2.html
+//! [CreatePipe]: https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-createpipe
+//! [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html
 use crate::io;
 use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
 
 /// Create anonymous pipe that is close-on-exec and blocking.
+///
+/// # Examples
+///
+/// See the [module-level](crate::pipe) documentation for examples.
 #[unstable(feature = "anonymous_pipe", issue = "127154")]
 #[inline]
 pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> {
@@ -33,6 +79,58 @@ pub struct PipeWriter(pub(crate) AnonPipe);
 
 impl PipeReader {
     /// Create a new [`PipeReader`] instance that shares the same underlying file description.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(anonymous_pipe)]
+    /// # #[cfg(miri)] fn main() {}
+    /// # #[cfg(not(miri))]
+    /// # fn main() -> std::io::Result<()> {
+    /// # use std::fs;
+    /// # use std::io::Write;
+    /// # use std::process::Command;
+    /// const NUM_SLOT: u8 = 2;
+    /// const NUM_PROC: u8 = 5;
+    /// const OUTPUT: &str = "work.txt";
+    ///
+    /// let mut jobs = vec![];
+    /// let (reader, mut writer) = std::pipe::pipe()?;
+    ///
+    /// // Write NUM_SLOT characters the the pipe.
+    /// writer.write_all(&[b'|'; NUM_SLOT as usize])?;
+    ///
+    /// // Spawn several processes that read a character from the pipe, do some work, then
+    /// // write back to the pipe. When the pipe is empty, the processes block, so only
+    /// // NUM_SLOT processes can be working at any given time.
+    /// for _ in 0..NUM_PROC {
+    ///     jobs.push(
+    ///         Command::new("bash")
+    ///             .args(["-c",
+    ///                 &format!(
+    ///                      "read -n 1\n\
+    ///                       echo -n 'x' >> '{OUTPUT}'\n\
+    ///                       echo -n '|'",
+    ///                 ),
+    ///             ])
+    ///             .stdin(reader.try_clone()?)
+    ///             .stdout(writer.try_clone()?)
+    ///             .spawn()?,
+    ///     );
+    /// }
+    ///
+    /// // Wait for all jobs to finish.
+    /// for mut job in jobs {
+    ///     job.wait()?;
+    /// }
+    ///
+    /// // Check our work and clean up.
+    /// let xs = fs::read_to_string(OUTPUT)?;
+    /// fs::remove_file(OUTPUT)?;
+    /// assert_eq!(xs, "x".repeat(NUM_PROC.into()));
+    /// # Ok(())
+    /// # }
+    /// ```
     #[unstable(feature = "anonymous_pipe", issue = "127154")]
     pub fn try_clone(&self) -> io::Result<Self> {
         self.0.try_clone().map(Self)
@@ -41,6 +139,38 @@ impl PipeReader {
 
 impl PipeWriter {
     /// Create a new [`PipeWriter`] instance that shares the same underlying file description.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(anonymous_pipe)]
+    /// # #[cfg(miri)] fn main() {}
+    /// # #[cfg(not(miri))]
+    /// # fn main() -> std::io::Result<()> {
+    /// # use std::process::Command;
+    /// # use std::io::Read;
+    /// let (mut reader, writer) = std::pipe::pipe()?;
+    ///
+    /// // Spawn a process that writes to stdout and stderr.
+    /// let mut peer = Command::new("bash")
+    ///     .args([
+    ///         "-c",
+    ///         "echo -n foo\n\
+    ///          echo -n bar >&2"
+    ///     ])
+    ///     .stdout(writer.try_clone()?)
+    ///     .stderr(writer)
+    ///     .spawn()?;
+    ///
+    /// // Read and check the result.
+    /// let mut msg = String::new();
+    /// reader.read_to_string(&mut msg)?;
+    /// assert_eq!(&msg, "foobar");
+    ///
+    /// peer.wait()?;
+    /// # Ok(())
+    /// # }
+    /// ```
     #[unstable(feature = "anonymous_pipe", issue = "127154")]
     pub fn try_clone(&self) -> io::Result<Self> {
         self.0.try_clone().map(Self)
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/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index fe2aca031a2..e28c2090afe 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -4,10 +4,10 @@ mod tests;
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::marker::PhantomData;
-use crate::mem::ManuallyDrop;
+use crate::mem::{self, ManuallyDrop};
 use crate::ops::{Deref, DerefMut};
 use crate::ptr::NonNull;
-use crate::sync::{LockResult, TryLockError, TryLockResult, poison};
+use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison};
 use crate::sys::sync as sys;
 
 /// A mutual exclusion primitive useful for protecting shared data
@@ -273,6 +273,100 @@ impl<T> Mutex<T> {
     pub const fn new(t: T) -> Mutex<T> {
         Mutex { inner: sys::Mutex::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) }
     }
+
+    /// Returns the contained value by cloning it.
+    ///
+    /// # Errors
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will return an error instead.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lock_value_accessors)]
+    ///
+    /// use std::sync::Mutex;
+    ///
+    /// let mut mutex = Mutex::new(7);
+    ///
+    /// assert_eq!(mutex.get_cloned().unwrap(), 7);
+    /// ```
+    #[unstable(feature = "lock_value_accessors", issue = "133407")]
+    pub fn get_cloned(&self) -> Result<T, PoisonError<()>>
+    where
+        T: Clone,
+    {
+        match self.lock() {
+            Ok(guard) => Ok((*guard).clone()),
+            Err(_) => Err(PoisonError::new(())),
+        }
+    }
+
+    /// Sets the contained value.
+    ///
+    /// # Errors
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will return an error containing the provided `value` instead.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lock_value_accessors)]
+    ///
+    /// use std::sync::Mutex;
+    ///
+    /// let mut mutex = Mutex::new(7);
+    ///
+    /// assert_eq!(mutex.get_cloned().unwrap(), 7);
+    /// mutex.set(11).unwrap();
+    /// assert_eq!(mutex.get_cloned().unwrap(), 11);
+    /// ```
+    #[unstable(feature = "lock_value_accessors", issue = "133407")]
+    pub fn set(&self, value: T) -> Result<(), PoisonError<T>> {
+        if mem::needs_drop::<T>() {
+            // If the contained value has non-trivial destructor, we
+            // call that destructor after the lock being released.
+            self.replace(value).map(drop)
+        } else {
+            match self.lock() {
+                Ok(mut guard) => {
+                    *guard = value;
+
+                    Ok(())
+                }
+                Err(_) => Err(PoisonError::new(value)),
+            }
+        }
+    }
+
+    /// Replaces the contained value with `value`, and returns the old contained value.
+    ///
+    /// # Errors
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will return an error containing the provided `value` instead.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lock_value_accessors)]
+    ///
+    /// use std::sync::Mutex;
+    ///
+    /// let mut mutex = Mutex::new(7);
+    ///
+    /// assert_eq!(mutex.replace(11).unwrap(), 7);
+    /// assert_eq!(mutex.get_cloned().unwrap(), 11);
+    /// ```
+    #[unstable(feature = "lock_value_accessors", issue = "133407")]
+    pub fn replace(&self, value: T) -> LockResult<T> {
+        match self.lock() {
+            Ok(mut guard) => Ok(mem::replace(&mut *guard, value)),
+            Err(_) => Err(PoisonError::new(value)),
+        }
+    }
 }
 
 impl<T: ?Sized> Mutex<T> {
@@ -290,7 +384,8 @@ impl<T: ?Sized> Mutex<T> {
     /// # Errors
     ///
     /// If another user of this mutex panicked while holding the mutex, then
-    /// this call will return an error once the mutex is acquired.
+    /// this call will return an error once the mutex is acquired. The acquired
+    /// mutex guard will be contained in the returned error.
     ///
     /// # Panics
     ///
@@ -331,7 +426,8 @@ impl<T: ?Sized> Mutex<T> {
     ///
     /// If another user of this mutex panicked while holding the mutex, then
     /// this call will return the [`Poisoned`] error if the mutex would
-    /// otherwise be acquired.
+    /// otherwise be acquired. An acquired lock guard will be contained
+    /// in the returned error.
     ///
     /// If the mutex could not be acquired because it is already locked, then
     /// this call will return the [`WouldBlock`] error.
@@ -438,7 +534,8 @@ impl<T: ?Sized> Mutex<T> {
     /// # Errors
     ///
     /// If another user of this mutex panicked while holding the mutex, then
-    /// this call will return an error instead.
+    /// this call will return an error containing the the underlying data
+    /// instead.
     ///
     /// # Examples
     ///
@@ -465,7 +562,8 @@ impl<T: ?Sized> Mutex<T> {
     /// # Errors
     ///
     /// If another user of this mutex panicked while holding the mutex, then
-    /// this call will return an error instead.
+    /// this call will return an error containing a mutable reference to the
+    /// underlying data instead.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/sync/mutex/tests.rs b/library/std/src/sync/mutex/tests.rs
index 19ec096c593..395c8aada08 100644
--- a/library/std/src/sync/mutex/tests.rs
+++ b/library/std/src/sync/mutex/tests.rs
@@ -1,13 +1,34 @@
+use crate::fmt::Debug;
+use crate::ops::FnMut;
+use crate::panic::{self, AssertUnwindSafe};
 use crate::sync::atomic::{AtomicUsize, Ordering};
 use crate::sync::mpsc::channel;
 use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
-use crate::thread;
+use crate::{hint, mem, thread};
 
 struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
 
 #[derive(Eq, PartialEq, Debug)]
 struct NonCopy(i32);
 
+#[derive(Eq, PartialEq, Debug)]
+struct NonCopyNeedsDrop(i32);
+
+impl Drop for NonCopyNeedsDrop {
+    fn drop(&mut self) {
+        hint::black_box(());
+    }
+}
+
+#[test]
+fn test_needs_drop() {
+    assert!(!mem::needs_drop::<NonCopy>());
+    assert!(mem::needs_drop::<NonCopyNeedsDrop>());
+}
+
+#[derive(Clone, Eq, PartialEq, Debug)]
+struct Cloneable(i32);
+
 #[test]
 fn smoke() {
     let m = Mutex::new(());
@@ -57,6 +78,21 @@ fn try_lock() {
     *m.try_lock().unwrap() = ();
 }
 
+fn new_poisoned_mutex<T>(value: T) -> Mutex<T> {
+    let mutex = Mutex::new(value);
+
+    let catch_unwind_result = panic::catch_unwind(AssertUnwindSafe(|| {
+        let _guard = mutex.lock().unwrap();
+
+        panic!("test panic to poison mutex");
+    }));
+
+    assert!(catch_unwind_result.is_err());
+    assert!(mutex.is_poisoned());
+
+    mutex
+}
+
 #[test]
 fn test_into_inner() {
     let m = Mutex::new(NonCopy(10));
@@ -83,22 +119,32 @@ fn test_into_inner_drop() {
 
 #[test]
 fn test_into_inner_poison() {
-    let m = Arc::new(Mutex::new(NonCopy(10)));
-    let m2 = m.clone();
-    let _ = thread::spawn(move || {
-        let _lock = m2.lock().unwrap();
-        panic!("test panic in inner thread to poison mutex");
-    })
-    .join();
+    let m = new_poisoned_mutex(NonCopy(10));
 
-    assert!(m.is_poisoned());
-    match Arc::try_unwrap(m).unwrap().into_inner() {
+    match m.into_inner() {
         Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
         Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {x:?}"),
     }
 }
 
 #[test]
+fn test_get_cloned() {
+    let m = Mutex::new(Cloneable(10));
+
+    assert_eq!(m.get_cloned().unwrap(), Cloneable(10));
+}
+
+#[test]
+fn test_get_cloned_poison() {
+    let m = new_poisoned_mutex(Cloneable(10));
+
+    match m.get_cloned() {
+        Err(e) => assert_eq!(e.into_inner(), ()),
+        Ok(x) => panic!("get of poisoned Mutex is Ok: {x:?}"),
+    }
+}
+
+#[test]
 fn test_get_mut() {
     let mut m = Mutex::new(NonCopy(10));
     *m.get_mut().unwrap() = NonCopy(20);
@@ -107,22 +153,91 @@ fn test_get_mut() {
 
 #[test]
 fn test_get_mut_poison() {
-    let m = Arc::new(Mutex::new(NonCopy(10)));
-    let m2 = m.clone();
-    let _ = thread::spawn(move || {
-        let _lock = m2.lock().unwrap();
-        panic!("test panic in inner thread to poison mutex");
-    })
-    .join();
+    let mut m = new_poisoned_mutex(NonCopy(10));
 
-    assert!(m.is_poisoned());
-    match Arc::try_unwrap(m).unwrap().get_mut() {
+    match m.get_mut() {
         Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
         Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {x:?}"),
     }
 }
 
 #[test]
+fn test_set() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = Mutex::new(init());
+
+        assert_eq!(*m.lock().unwrap(), init());
+        m.set(value()).unwrap();
+        assert_eq!(*m.lock().unwrap(), value());
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
+fn test_set_poison() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = new_poisoned_mutex(init());
+
+        match m.set(value()) {
+            Err(e) => {
+                assert_eq!(e.into_inner(), value());
+                assert_eq!(m.into_inner().unwrap_err().into_inner(), init());
+            }
+            Ok(x) => panic!("set of poisoned Mutex is Ok: {x:?}"),
+        }
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
+fn test_replace() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = Mutex::new(init());
+
+        assert_eq!(*m.lock().unwrap(), init());
+        assert_eq!(m.replace(value()).unwrap(), init());
+        assert_eq!(*m.lock().unwrap(), value());
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
+fn test_replace_poison() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = new_poisoned_mutex(init());
+
+        match m.replace(value()) {
+            Err(e) => {
+                assert_eq!(e.into_inner(), value());
+                assert_eq!(m.into_inner().unwrap_err().into_inner(), init());
+            }
+            Ok(x) => panic!("replace of poisoned Mutex is Ok: {x:?}"),
+        }
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
 fn test_mutex_arc_condvar() {
     let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
     let packet2 = Packet(packet.0.clone());
@@ -269,7 +384,7 @@ fn test_mapping_mapped_guard() {
 fn panic_while_mapping_unlocked_poison() {
     let lock = Mutex::new(());
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.lock().unwrap();
         let _guard = MutexGuard::map::<(), _>(guard, |_| panic!());
     });
@@ -282,7 +397,7 @@ fn panic_while_mapping_unlocked_poison() {
         Err(TryLockError::Poisoned(_)) => {}
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.lock().unwrap();
         let _guard = MutexGuard::try_map::<(), _>(guard, |_| panic!());
     });
@@ -295,7 +410,7 @@ fn panic_while_mapping_unlocked_poison() {
         Err(TryLockError::Poisoned(_)) => {}
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.lock().unwrap();
         let guard = MutexGuard::map::<(), _>(guard, |val| val);
         let _guard = MappedMutexGuard::map::<(), _>(guard, |_| panic!());
@@ -309,7 +424,7 @@ fn panic_while_mapping_unlocked_poison() {
         Err(TryLockError::Poisoned(_)) => {}
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.lock().unwrap();
         let guard = MutexGuard::map::<(), _>(guard, |val| val);
         let _guard = MappedMutexGuard::try_map::<(), _>(guard, |_| panic!());
diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs
index da66a088e51..9eb900c2103 100644
--- a/library/std/src/sync/poison.rs
+++ b/library/std/src/sync/poison.rs
@@ -87,8 +87,8 @@ pub struct Guard {
 ///
 /// Both [`Mutex`]es and [`RwLock`]s are poisoned whenever a thread fails while the lock
 /// is held. The precise semantics for when a lock is poisoned is documented on
-/// each lock, but once a lock is poisoned then all future acquisitions will
-/// return this error.
+/// each lock. For a lock in the poisoned state, unless the state is cleared manually,
+/// all future acquisitions will return this error.
 ///
 /// # Examples
 ///
@@ -118,7 +118,7 @@ pub struct Guard {
 /// [`RwLock`]: crate::sync::RwLock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct PoisonError<T> {
-    guard: T,
+    data: T,
     #[cfg(not(panic = "unwind"))]
     _never: !,
 }
@@ -147,14 +147,15 @@ pub enum TryLockError<T> {
 /// A type alias for the result of a lock method which can be poisoned.
 ///
 /// The [`Ok`] variant of this result indicates that the primitive was not
-/// poisoned, and the `Guard` is contained within. The [`Err`] variant indicates
+/// poisoned, and the operation result is contained within. The [`Err`] variant indicates
 /// that the primitive was poisoned. Note that the [`Err`] variant *also* carries
-/// the associated guard, and it can be acquired through the [`into_inner`]
-/// method.
+/// an associated value assigned by the lock method, and it can be acquired through the
+/// [`into_inner`] method. The semantics of the associated value depends on the corresponding
+/// lock method.
 ///
 /// [`into_inner`]: PoisonError::into_inner
 #[stable(feature = "rust1", since = "1.0.0")]
-pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
+pub type LockResult<T> = Result<T, PoisonError<T>>;
 
 /// A type alias for the result of a nonblocking locking method.
 ///
@@ -195,8 +196,8 @@ impl<T> PoisonError<T> {
     /// This method may panic if std was built with `panic="abort"`.
     #[cfg(panic = "unwind")]
     #[stable(feature = "sync_poison", since = "1.2.0")]
-    pub fn new(guard: T) -> PoisonError<T> {
-        PoisonError { guard }
+    pub fn new(data: T) -> PoisonError<T> {
+        PoisonError { data }
     }
 
     /// Creates a `PoisonError`.
@@ -208,12 +209,12 @@ impl<T> PoisonError<T> {
     #[cfg(not(panic = "unwind"))]
     #[stable(feature = "sync_poison", since = "1.2.0")]
     #[track_caller]
-    pub fn new(_guard: T) -> PoisonError<T> {
+    pub fn new(_data: T) -> PoisonError<T> {
         panic!("PoisonError created in a libstd built with panic=\"abort\"")
     }
 
     /// Consumes this error indicating that a lock is poisoned, returning the
-    /// underlying guard to allow access regardless.
+    /// associated data.
     ///
     /// # Examples
     ///
@@ -238,21 +239,21 @@ impl<T> PoisonError<T> {
     /// ```
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn into_inner(self) -> T {
-        self.guard
+        self.data
     }
 
     /// Reaches into this error indicating that a lock is poisoned, returning a
-    /// reference to the underlying guard to allow access regardless.
+    /// reference to the associated data.
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn get_ref(&self) -> &T {
-        &self.guard
+        &self.data
     }
 
     /// Reaches into this error indicating that a lock is poisoned, returning a
-    /// mutable reference to the underlying guard to allow access regardless.
+    /// mutable reference to the associated data.
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn get_mut(&mut self) -> &mut T {
-        &mut self.guard
+        &mut self.data
     }
 }
 
@@ -322,6 +323,6 @@ where
     match result {
         Ok(t) => Ok(f(t)),
         #[cfg(panic = "unwind")]
-        Err(PoisonError { guard }) => Err(PoisonError::new(f(guard))),
+        Err(PoisonError { data }) => Err(PoisonError::new(f(data))),
     }
 }
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index d55d1c80dca..1519baf99a8 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -4,7 +4,7 @@ mod tests;
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::marker::PhantomData;
-use crate::mem::{ManuallyDrop, forget};
+use crate::mem::{self, ManuallyDrop, forget};
 use crate::ops::{Deref, DerefMut};
 use crate::ptr::NonNull;
 use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison};
@@ -224,6 +224,103 @@ impl<T> RwLock<T> {
     pub const fn new(t: T) -> RwLock<T> {
         RwLock { inner: sys::RwLock::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) }
     }
+
+    /// Returns the contained value by cloning it.
+    ///
+    /// # Errors
+    ///
+    /// This function will return an error if the `RwLock` is poisoned. An
+    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
+    /// lock.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lock_value_accessors)]
+    ///
+    /// use std::sync::RwLock;
+    ///
+    /// let mut lock = RwLock::new(7);
+    ///
+    /// assert_eq!(lock.get_cloned().unwrap(), 7);
+    /// ```
+    #[unstable(feature = "lock_value_accessors", issue = "133407")]
+    pub fn get_cloned(&self) -> Result<T, PoisonError<()>>
+    where
+        T: Clone,
+    {
+        match self.read() {
+            Ok(guard) => Ok((*guard).clone()),
+            Err(_) => Err(PoisonError::new(())),
+        }
+    }
+
+    /// Sets the contained value.
+    ///
+    /// # Errors
+    ///
+    /// This function will return an error containing the provided `value` if
+    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
+    /// panics while holding an exclusive lock.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lock_value_accessors)]
+    ///
+    /// use std::sync::RwLock;
+    ///
+    /// let mut lock = RwLock::new(7);
+    ///
+    /// assert_eq!(lock.get_cloned().unwrap(), 7);
+    /// lock.set(11).unwrap();
+    /// assert_eq!(lock.get_cloned().unwrap(), 11);
+    /// ```
+    #[unstable(feature = "lock_value_accessors", issue = "133407")]
+    pub fn set(&self, value: T) -> Result<(), PoisonError<T>> {
+        if mem::needs_drop::<T>() {
+            // If the contained value has non-trivial destructor, we
+            // call that destructor after the lock being released.
+            self.replace(value).map(drop)
+        } else {
+            match self.write() {
+                Ok(mut guard) => {
+                    *guard = value;
+
+                    Ok(())
+                }
+                Err(_) => Err(PoisonError::new(value)),
+            }
+        }
+    }
+
+    /// Replaces the contained value with `value`, and returns the old contained value.
+    ///
+    /// # Errors
+    ///
+    /// This function will return an error containing the provided `value` if
+    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
+    /// panics while holding an exclusive lock.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lock_value_accessors)]
+    ///
+    /// use std::sync::RwLock;
+    ///
+    /// let mut lock = RwLock::new(7);
+    ///
+    /// assert_eq!(lock.replace(11).unwrap(), 7);
+    /// assert_eq!(lock.get_cloned().unwrap(), 11);
+    /// ```
+    #[unstable(feature = "lock_value_accessors", issue = "133407")]
+    pub fn replace(&self, value: T) -> LockResult<T> {
+        match self.write() {
+            Ok(mut guard) => Ok(mem::replace(&mut *guard, value)),
+            Err(_) => Err(PoisonError::new(value)),
+        }
+    }
 }
 
 impl<T: ?Sized> RwLock<T> {
@@ -244,7 +341,8 @@ impl<T: ?Sized> RwLock<T> {
     /// This function will return an error if the `RwLock` is poisoned. An
     /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
     /// lock. The failure will occur immediately after the lock has been
-    /// acquired.
+    /// acquired. The acquired lock guard will be contained in the returned
+    /// error.
     ///
     /// # Panics
     ///
@@ -292,7 +390,8 @@ impl<T: ?Sized> RwLock<T> {
     /// This function will return the [`Poisoned`] error if the `RwLock` is
     /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
     /// an exclusive lock. `Poisoned` will only be returned if the lock would
-    /// have otherwise been acquired.
+    /// have otherwise been acquired. An acquired lock guard will be contained
+    /// in the returned error.
     ///
     /// This function will return the [`WouldBlock`] error if the `RwLock` could
     /// not be acquired because it was already locked exclusively.
@@ -337,7 +436,8 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// This function will return an error if the `RwLock` is poisoned. An
     /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
-    /// lock. An error will be returned when the lock is acquired.
+    /// lock. An error will be returned when the lock is acquired. The acquired
+    /// lock guard will be contained in the returned error.
     ///
     /// # Panics
     ///
@@ -380,7 +480,8 @@ impl<T: ?Sized> RwLock<T> {
     /// This function will return the [`Poisoned`] error if the `RwLock` is
     /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
     /// an exclusive lock. `Poisoned` will only be returned if the lock would
-    /// have otherwise been acquired.
+    /// have otherwise been acquired. An acquired lock guard will be contained
+    /// in the returned error.
     ///
     /// This function will return the [`WouldBlock`] error if the `RwLock` could
     /// not be acquired because it was already locked exclusively.
@@ -481,10 +582,10 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// # Errors
     ///
-    /// This function will return an error if the `RwLock` is poisoned. An
-    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
-    /// lock. An error will only be returned if the lock would have otherwise
-    /// been acquired.
+    /// This function will return an error containing the underlying data if
+    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
+    /// panics while holding an exclusive lock. An error will only be returned
+    /// if the lock would have otherwise been acquired.
     ///
     /// # Examples
     ///
@@ -514,10 +615,11 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// # Errors
     ///
-    /// This function will return an error if the `RwLock` is poisoned. An
-    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
-    /// lock. An error will only be returned if the lock would have otherwise
-    /// been acquired.
+    /// This function will return an error containing a mutable reference to
+    /// the underlying data if the `RwLock` is poisoned. An `RwLock` is
+    /// poisoned whenever a writer panics while holding an exclusive lock.
+    /// An error will only be returned if the lock would have otherwise been
+    /// acquired.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs
index 48d442921f7..057c2f1a5d7 100644
--- a/library/std/src/sync/rwlock/tests.rs
+++ b/library/std/src/sync/rwlock/tests.rs
@@ -1,16 +1,37 @@
 use rand::Rng;
 
+use crate::fmt::Debug;
+use crate::ops::FnMut;
+use crate::panic::{self, AssertUnwindSafe};
 use crate::sync::atomic::{AtomicUsize, Ordering};
 use crate::sync::mpsc::channel;
 use crate::sync::{
     Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
     TryLockError,
 };
-use crate::thread;
+use crate::{hint, mem, thread};
 
 #[derive(Eq, PartialEq, Debug)]
 struct NonCopy(i32);
 
+#[derive(Eq, PartialEq, Debug)]
+struct NonCopyNeedsDrop(i32);
+
+impl Drop for NonCopyNeedsDrop {
+    fn drop(&mut self) {
+        hint::black_box(());
+    }
+}
+
+#[test]
+fn test_needs_drop() {
+    assert!(!mem::needs_drop::<NonCopy>());
+    assert!(mem::needs_drop::<NonCopyNeedsDrop>());
+}
+
+#[derive(Clone, Eq, PartialEq, Debug)]
+struct Cloneable(i32);
+
 #[test]
 fn smoke() {
     let l = RwLock::new(());
@@ -255,6 +276,21 @@ fn test_rwlock_try_write() {
     drop(mapped_read_guard);
 }
 
+fn new_poisoned_rwlock<T>(value: T) -> RwLock<T> {
+    let lock = RwLock::new(value);
+
+    let catch_unwind_result = panic::catch_unwind(AssertUnwindSafe(|| {
+        let _guard = lock.write().unwrap();
+
+        panic!("test panic to poison RwLock");
+    }));
+
+    assert!(catch_unwind_result.is_err());
+    assert!(lock.is_poisoned());
+
+    lock
+}
+
 #[test]
 fn test_into_inner() {
     let m = RwLock::new(NonCopy(10));
@@ -281,22 +317,32 @@ fn test_into_inner_drop() {
 
 #[test]
 fn test_into_inner_poison() {
-    let m = Arc::new(RwLock::new(NonCopy(10)));
-    let m2 = m.clone();
-    let _ = thread::spawn(move || {
-        let _lock = m2.write().unwrap();
-        panic!("test panic in inner thread to poison RwLock");
-    })
-    .join();
+    let m = new_poisoned_rwlock(NonCopy(10));
 
-    assert!(m.is_poisoned());
-    match Arc::try_unwrap(m).unwrap().into_inner() {
+    match m.into_inner() {
         Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
         Ok(x) => panic!("into_inner of poisoned RwLock is Ok: {x:?}"),
     }
 }
 
 #[test]
+fn test_get_cloned() {
+    let m = RwLock::new(Cloneable(10));
+
+    assert_eq!(m.get_cloned().unwrap(), Cloneable(10));
+}
+
+#[test]
+fn test_get_cloned_poison() {
+    let m = new_poisoned_rwlock(Cloneable(10));
+
+    match m.get_cloned() {
+        Err(e) => assert_eq!(e.into_inner(), ()),
+        Ok(x) => panic!("get of poisoned RwLock is Ok: {x:?}"),
+    }
+}
+
+#[test]
 fn test_get_mut() {
     let mut m = RwLock::new(NonCopy(10));
     *m.get_mut().unwrap() = NonCopy(20);
@@ -305,22 +351,91 @@ fn test_get_mut() {
 
 #[test]
 fn test_get_mut_poison() {
-    let m = Arc::new(RwLock::new(NonCopy(10)));
-    let m2 = m.clone();
-    let _ = thread::spawn(move || {
-        let _lock = m2.write().unwrap();
-        panic!("test panic in inner thread to poison RwLock");
-    })
-    .join();
+    let mut m = new_poisoned_rwlock(NonCopy(10));
 
-    assert!(m.is_poisoned());
-    match Arc::try_unwrap(m).unwrap().get_mut() {
+    match m.get_mut() {
         Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
         Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {x:?}"),
     }
 }
 
 #[test]
+fn test_set() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = RwLock::new(init());
+
+        assert_eq!(*m.read().unwrap(), init());
+        m.set(value()).unwrap();
+        assert_eq!(*m.read().unwrap(), value());
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
+fn test_set_poison() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = new_poisoned_rwlock(init());
+
+        match m.set(value()) {
+            Err(e) => {
+                assert_eq!(e.into_inner(), value());
+                assert_eq!(m.into_inner().unwrap_err().into_inner(), init());
+            }
+            Ok(x) => panic!("set of poisoned RwLock is Ok: {x:?}"),
+        }
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
+fn test_replace() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = RwLock::new(init());
+
+        assert_eq!(*m.read().unwrap(), init());
+        assert_eq!(m.replace(value()).unwrap(), init());
+        assert_eq!(*m.read().unwrap(), value());
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
+fn test_replace_poison() {
+    fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
+    where
+        T: Debug + Eq,
+    {
+        let m = new_poisoned_rwlock(init());
+
+        match m.replace(value()) {
+            Err(e) => {
+                assert_eq!(e.into_inner(), value());
+                assert_eq!(m.into_inner().unwrap_err().into_inner(), init());
+            }
+            Ok(x) => panic!("replace of poisoned RwLock is Ok: {x:?}"),
+        }
+    }
+
+    inner(|| NonCopy(10), || NonCopy(20));
+    inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
+}
+
+#[test]
 fn test_read_guard_covariance() {
     fn do_stuff<'a>(_: RwLockReadGuard<'_, &'a i32>, _: &'a i32) {}
     let j: i32 = 5;
@@ -370,7 +485,7 @@ fn test_mapping_mapped_guard() {
 fn panic_while_mapping_read_unlocked_no_poison() {
     let lock = RwLock::new(());
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.read().unwrap();
         let _guard = RwLockReadGuard::map::<(), _>(guard, |_| panic!());
     });
@@ -385,7 +500,7 @@ fn panic_while_mapping_read_unlocked_no_poison() {
         }
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.read().unwrap();
         let _guard = RwLockReadGuard::try_map::<(), _>(guard, |_| panic!());
     });
@@ -400,7 +515,7 @@ fn panic_while_mapping_read_unlocked_no_poison() {
         }
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.read().unwrap();
         let guard = RwLockReadGuard::map::<(), _>(guard, |val| val);
         let _guard = MappedRwLockReadGuard::map::<(), _>(guard, |_| panic!());
@@ -416,7 +531,7 @@ fn panic_while_mapping_read_unlocked_no_poison() {
         }
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.read().unwrap();
         let guard = RwLockReadGuard::map::<(), _>(guard, |val| val);
         let _guard = MappedRwLockReadGuard::try_map::<(), _>(guard, |_| panic!());
@@ -439,7 +554,7 @@ fn panic_while_mapping_read_unlocked_no_poison() {
 fn panic_while_mapping_write_unlocked_poison() {
     let lock = RwLock::new(());
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.write().unwrap();
         let _guard = RwLockWriteGuard::map::<(), _>(guard, |_| panic!());
     });
@@ -452,7 +567,7 @@ fn panic_while_mapping_write_unlocked_poison() {
         Err(TryLockError::Poisoned(_)) => {}
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.write().unwrap();
         let _guard = RwLockWriteGuard::try_map::<(), _>(guard, |_| panic!());
     });
@@ -467,7 +582,7 @@ fn panic_while_mapping_write_unlocked_poison() {
         Err(TryLockError::Poisoned(_)) => {}
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.write().unwrap();
         let guard = RwLockWriteGuard::map::<(), _>(guard, |val| val);
         let _guard = MappedRwLockWriteGuard::map::<(), _>(guard, |_| panic!());
@@ -483,7 +598,7 @@ fn panic_while_mapping_write_unlocked_poison() {
         Err(TryLockError::Poisoned(_)) => {}
     }
 
-    let _ = crate::panic::catch_unwind(|| {
+    let _ = panic::catch_unwind(|| {
         let guard = lock.write().unwrap();
         let guard = RwLockWriteGuard::map::<(), _>(guard, |val| val);
         let _guard = MappedRwLockWriteGuard::try_map::<(), _>(guard, |_| panic!());
diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs
index 11862a07608..88fc4068719 100644
--- a/library/std/src/sys/pal/hermit/fs.rs
+++ b/library/std/src/sys/pal/hermit/fs.rs
@@ -3,7 +3,7 @@ use super::hermit_abi::{
     self, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY,
     O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, dirent64, stat as stat_struct,
 };
-use crate::ffi::{CStr, OsStr, OsString};
+use crate::ffi::{CStr, OsStr, OsString, c_char};
 use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
 use crate::os::hermit::ffi::OsStringExt;
 use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
@@ -204,7 +204,7 @@ impl Iterator for ReadDir {
                 // the size of dirent64. The file name is always a C string and terminated by `\0`.
                 // Consequently, we are able to ignore the last byte.
                 let name_bytes =
-                    unsafe { CStr::from_ptr(&dir.d_name as *const _ as *const i8).to_bytes() };
+                    unsafe { CStr::from_ptr(&dir.d_name as *const _ as *const c_char).to_bytes() };
                 let entry = DirEntry {
                     root: self.inner.root.clone(),
                     ino: dir.d_ino,
@@ -445,7 +445,7 @@ impl DirBuilder {
 
     pub fn mkdir(&self, path: &Path) -> io::Result<()> {
         run_path_with_cstr(path, &|path| {
-            cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode.into()) }).map(|_| ())
+            cvt(unsafe { hermit_abi::mkdir(path.as_ptr().cast(), self.mode.into()) }).map(|_| ())
         })
     }
 
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index f03fca60344..d833c9d632c 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -85,7 +85,7 @@ pub unsafe extern "C" fn runtime_entry(
     }
 
     // initialize environment
-    os::init_environment(env as *const *const i8);
+    os::init_environment(env);
 
     let result = unsafe { main(argc as isize, argv) };
 
diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs
index f8ea80afa43..791cdb1e57e 100644
--- a/library/std/src/sys/pal/hermit/os.rs
+++ b/library/std/src/sys/pal/hermit/os.rs
@@ -3,7 +3,7 @@ use core::slice::memchr;
 use super::hermit_abi;
 use crate::collections::HashMap;
 use crate::error::Error as StdError;
-use crate::ffi::{CStr, OsStr, OsString};
+use crate::ffi::{CStr, OsStr, OsString, c_char};
 use crate::marker::PhantomData;
 use crate::os::hermit::ffi::OsStringExt;
 use crate::path::{self, PathBuf};
@@ -70,7 +70,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 static ENV: Mutex<Option<HashMap<OsString, OsString>>> = Mutex::new(None);
 
-pub fn init_environment(env: *const *const i8) {
+pub fn init_environment(env: *const *const c_char) {
     let mut guard = ENV.lock().unwrap();
     let map = guard.insert(HashMap::new());
 
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index d140607869c..d73b9fd5eb8 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -81,6 +81,7 @@ impl Socket {
                     target_os = "netbsd",
                     target_os = "openbsd",
                     target_os = "nto",
+                    target_os = "solaris",
                 ))] {
                     // On platforms that support it we pass the SOCK_CLOEXEC
                     // flag to atomically create the socket and set it as
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..89b2d73f74a 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -471,7 +471,7 @@ impl Step for Rustc {
                 }
             }
 
-            {
+            if builder.config.llvm_enabled(compiler.host) && builder.config.llvm_tools_enabled {
                 let src_dir = builder.sysroot_target_bindir(compiler, host);
                 let llvm_objcopy = exe("llvm-objcopy", compiler.host);
                 let rust_objcopy = exe("rust-objcopy", compiler.host);
@@ -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..8d9d2b6b6a1 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)
     }
 }
@@ -2442,7 +2442,9 @@ impl Step for ErrorIndex {
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/tools/error_index_generator")
+        // Also add `error-index` here since that is what appears in the error message
+        // when this fails.
+        run.path("src/tools/error_index_generator").alias("error-index")
     }
 
     fn make_run(run: RunConfig<'_>) {
@@ -2488,7 +2490,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..96d3162a8c5 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.
@@ -1208,6 +1203,11 @@ impl Builder<'_> {
             // even if we're not going to output debuginfo for the crate we're currently building,
             // so that it'll be available when downstream consumers of std try to use it.
             rustflags.arg("-Zinline-mir-preserve-debug");
+
+            // FIXME: always pass this after the next `#[cfg(bootstrap)]` update.
+            if compiler.stage != 0 {
+                rustflags.arg("-Zmir_strip_debuginfo=locals-in-tiny-functions");
+            }
         }
 
         Cargo {
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..22d361ff091 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)
                         );
@@ -1320,7 +1320,31 @@ impl Config {
 
         // Set flags.
         config.paths = std::mem::take(&mut flags.paths);
-        config.skip = flags.skip.into_iter().chain(flags.exclude).collect();
+        config.skip = flags
+            .skip
+            .into_iter()
+            .chain(flags.exclude)
+            .map(|p| {
+                let p = if cfg!(windows) {
+                    PathBuf::from(p.to_str().unwrap().replace('/', "\\"))
+                } else {
+                    p
+                };
+
+                // Jump to top-level project path to support passing paths
+                // from sub directories.
+                let top_level_path = config.src.join(&p);
+                if !config.src.join(&top_level_path).exists() {
+                    eprintln!("WARNING: '{}' does not exist.", top_level_path.display());
+                }
+
+                // Never return top-level path here as it would break `--skip`
+                // logic on rustc's internal test framework which is utilized
+                // by compiletest.
+                p
+            })
+            .collect();
+
         config.include_default_paths = flags.include_default_paths;
         config.rustc_error_format = flags.rustc_error_format;
         config.json_output = flags.json_output;
@@ -1565,7 +1589,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 +1876,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 +1908,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 +1937,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 +2027,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 +2049,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 +2123,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 +2339,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 +2514,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 +2525,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 +2551,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 +2736,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 +2859,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 +2892,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 +2934,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 +2983,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 +2998,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 +3042,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 +3147,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..4aec554b432 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -44,6 +44,16 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> {
         Some(PathBuf::from("ar"))
     } else if target.contains("vxworks") {
         Some(PathBuf::from("wr-ar"))
+    } else if target.contains("-nto-") {
+        if target.starts_with("i586") {
+            Some(PathBuf::from("ntox86-ar"))
+        } else if target.starts_with("aarch64") {
+            Some(PathBuf::from("ntoaarch64-ar"))
+        } else if target.starts_with("x86_64") {
+            Some(PathBuf::from("ntox86_64-ar"))
+        } else {
+            panic!("Unknown architecture, cannot determine archiver for Neutrino QNX");
+        }
     } else if target.contains("android") || target.contains("-wasi") {
         Some(cc.parent().unwrap().join(PathBuf::from("llvm-ar")))
     } else {
@@ -155,15 +165,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/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index c40de76abbf..03ec77f507e 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -90,9 +90,9 @@ RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc sun
 COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
 RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh
 
-RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-23/wasi-sdk-23.0-x86_64-linux.tar.gz | \
+RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-linux.tar.gz | \
   tar -xz
-ENV WASI_SDK_PATH=/tmp/wasi-sdk-23.0-x86_64-linux
+ENV WASI_SDK_PATH=/tmp/wasi-sdk-25.0-x86_64-linux
 
 COPY scripts/freebsd-toolchain.sh /tmp/
 RUN /tmp/freebsd-toolchain.sh i686
diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile
index c2f5a87b123..8d2e45ae497 100644
--- a/src/ci/docker/host-x86_64/test-various/Dockerfile
+++ b/src/ci/docker/host-x86_64/test-various/Dockerfile
@@ -40,9 +40,9 @@ WORKDIR /
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
-RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-23/wasi-sdk-23.0-x86_64-linux.tar.gz | \
+RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-linux.tar.gz | \
   tar -xz
-ENV WASI_SDK_PATH=/wasi-sdk-23.0-x86_64-linux
+ENV WASI_SDK_PATH=/wasi-sdk-25.0-x86_64-linux
 
 ENV RUST_CONFIGURE_ARGS \
   --musl-root-x86_64=/usr/local/x86_64-linux-musl \
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/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
index 487da580152..42df58517ca 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
@@ -59,5 +59,10 @@ COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
 
 RUN /scripts/build-gccjit.sh /scripts
 
-COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh
-ENV SCRIPT /tmp/script.sh
+ARG SCRIPT_ARG
+COPY scripts/add_dummy_commit.sh /tmp/add_dummy_commit.sh
+COPY scripts/x86_64-gnu-llvm.sh /tmp/x86_64-gnu-llvm.sh
+COPY scripts/x86_64-gnu-llvm1.sh /tmp/x86_64-gnu-llvm1.sh
+COPY scripts/x86_64-gnu-llvm2.sh /tmp/x86_64-gnu-llvm2.sh
+COPY scripts/x86_64-gnu-llvm3.sh /tmp/x86_64-gnu-llvm3.sh
+ENV SCRIPT /tmp/${SCRIPT_ARG}
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
index 4991908fe77..f2aadbe87cf 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
@@ -59,5 +59,10 @@ COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
 
 RUN /scripts/build-gccjit.sh /scripts
 
-COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh
-ENV SCRIPT /tmp/script.sh
+ARG SCRIPT_ARG
+COPY scripts/add_dummy_commit.sh /tmp/add_dummy_commit.sh
+COPY scripts/x86_64-gnu-llvm.sh /tmp/x86_64-gnu-llvm.sh
+COPY scripts/x86_64-gnu-llvm1.sh /tmp/x86_64-gnu-llvm1.sh
+COPY scripts/x86_64-gnu-llvm2.sh /tmp/x86_64-gnu-llvm2.sh
+COPY scripts/x86_64-gnu-llvm3.sh /tmp/x86_64-gnu-llvm3.sh
+ENV SCRIPT /tmp/${SCRIPT_ARG}
diff --git a/src/ci/docker/scripts/add_dummy_commit.sh b/src/ci/docker/scripts/add_dummy_commit.sh
new file mode 100755
index 00000000000..029e4ae141f
--- /dev/null
+++ b/src/ci/docker/scripts/add_dummy_commit.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -ex
+
+if [ "$READ_ONLY_SRC" = "0" ]; then
+    # `core::builder::tests::ci_rustc_if_unchanged_logic` bootstrap test ensures that
+    # "download-rustc=if-unchanged" logic don't use CI rustc while there are changes on
+    # compiler and/or library. Here we are adding a dummy commit on compiler and running
+    # that test to make sure we never download CI rustc with a change on the compiler tree.
+    echo "" >> ../compiler/rustc/src/main.rs
+    git config --global user.email "dummy@dummy.com"
+    git config --global user.name "dummy"
+    git add ../compiler/rustc/src/main.rs
+    git commit -m "test commit for rust.download-rustc=if-unchanged logic"
+    DISABLE_CI_RUSTC_IF_INCOMPATIBLE=0 ../x.py test bootstrap \
+        -- core::builder::tests::ci_rustc_if_unchanged_logic
+    # Revert the dummy commit
+    git reset --hard HEAD~1
+fi
diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm.sh b/src/ci/docker/scripts/x86_64-gnu-llvm.sh
index dea38b6fd2a..e7dcc1ddff4 100755
--- a/src/ci/docker/scripts/x86_64-gnu-llvm.sh
+++ b/src/ci/docker/scripts/x86_64-gnu-llvm.sh
@@ -2,42 +2,7 @@
 
 set -ex
 
-if [ "$READ_ONLY_SRC" = "0" ]; then
-    # `core::builder::tests::ci_rustc_if_unchanged_logic` bootstrap test ensures that
-    # "download-rustc=if-unchanged" logic don't use CI rustc while there are changes on
-    # compiler and/or library. Here we are adding a dummy commit on compiler and running
-    # that test to make sure we never download CI rustc with a change on the compiler tree.
-    echo "" >> ../compiler/rustc/src/main.rs
-    git config --global user.email "dummy@dummy.com"
-    git config --global user.name "dummy"
-    git add ../compiler/rustc/src/main.rs
-    git commit -m "test commit for rust.download-rustc=if-unchanged logic"
-    DISABLE_CI_RUSTC_IF_INCOMPATIBLE=0 ../x.py test bootstrap \
-        -- core::builder::tests::ci_rustc_if_unchanged_logic
-    # Revert the dummy commit
-    git reset --hard HEAD~1
-fi
-
-# Only run the stage 1 tests on merges, not on PR CI jobs.
-if [[ -z "${PR_CI_JOB}" ]]; then
-    ../x.py --stage 1 test --skip src/tools/tidy
-
-    # Run the `mir-opt` tests again but this time for a 32-bit target.
-    # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
-    # both 32-bit and 64-bit outputs updated by the PR author, before
-    # the PR is approved and tested for merging.
-    # It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
-    # despite having different output on 32-bit vs 64-bit targets.
-    ../x.py --stage 1 test tests/mir-opt --host='' --target=i686-unknown-linux-gnu
-
-    # Run `ui-fulldeps` in `--stage=1`, which actually uses the stage0
-    # compiler, and is sensitive to the addition of new flags.
-    ../x.py --stage 1 test tests/ui-fulldeps
-
-    # Rebuild the stdlib with the size optimizations enabled and run tests again.
-    RUSTFLAGS_NOT_BOOTSTRAP="--cfg feature=\"optimize_for_size\"" ../x.py --stage 1 test \
-        library/std library/alloc library/core
-fi
+/tmp/add_dummy_commit.sh
 
 # NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
 ../x.py --stage 2 test --skip src/tools/tidy
diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm1.sh b/src/ci/docker/scripts/x86_64-gnu-llvm1.sh
new file mode 100755
index 00000000000..56ef39aae15
--- /dev/null
+++ b/src/ci/docker/scripts/x86_64-gnu-llvm1.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -ex
+
+/tmp/add_dummy_commit.sh
+
+../x.py --stage 2 test \
+  --skip tests \
+  --skip coverage-map \
+  --skip coverage-run \
+  --skip library \
+  --skip tidyselftest
diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm2.sh b/src/ci/docker/scripts/x86_64-gnu-llvm2.sh
new file mode 100755
index 00000000000..c9f6b98f01f
--- /dev/null
+++ b/src/ci/docker/scripts/x86_64-gnu-llvm2.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -ex
+
+/tmp/add_dummy_commit.sh
+
+##### Test stage 2 #####
+
+../x.py --stage 2 test \
+  --skip compiler \
+  --skip src
+
+# Run the `mir-opt` tests again but this time for a 32-bit target.
+# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
+# both 32-bit and 64-bit outputs updated by the PR author, before
+# the PR is approved and tested for merging.
+# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
+# despite having different output on 32-bit vs 64-bit targets.
+../x --stage 2 test tests/mir-opt --host='' --target=i686-unknown-linux-gnu
+
+# Run the UI test suite again, but in `--pass=check` mode
+#
+# This is intended to make sure that both `--pass=check` continues to
+# work.
+../x.ps1 --stage 2 test tests/ui --pass=check --host='' --target=i686-unknown-linux-gnu
diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm3.sh b/src/ci/docker/scripts/x86_64-gnu-llvm3.sh
new file mode 100755
index 00000000000..d1bf2dab1e2
--- /dev/null
+++ b/src/ci/docker/scripts/x86_64-gnu-llvm3.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -ex
+
+/tmp/add_dummy_commit.sh
+
+##### Test stage 1 #####
+
+../x.py --stage 1 test --skip src/tools/tidy
+
+# Run the `mir-opt` tests again but this time for a 32-bit target.
+# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
+# both 32-bit and 64-bit outputs updated by the PR author, before
+# the PR is approved and tested for merging.
+# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
+# despite having different output on 32-bit vs 64-bit targets.
+../x.py --stage 1 test tests/mir-opt --host='' --target=i686-unknown-linux-gnu
+
+# Run `ui-fulldeps` in `--stage=1`, which actually uses the stage0
+# compiler, and is sensitive to the addition of new flags.
+../x.py --stage 1 test tests/ui-fulldeps
+
+# Rebuild the stdlib with the size optimizations enabled and run tests again.
+RUSTFLAGS_NOT_BOOTSTRAP="--cfg feature=\"optimize_for_size\"" ../x.py --stage 1 test \
+    library/std library/alloc library/core
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 959a9580e60..5732a428f67 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -117,6 +117,7 @@ pr:
       ENABLE_GCC_CODEGEN: "1"
       # We are adding (temporarily) a dummy commit on the compiler
       READ_ONLY_SRC: "0"
+      DOCKER_SCRIPT: x86_64-gnu-llvm.sh
     <<: *job-linux-16c
   - image: x86_64-gnu-tools
     <<: *job-linux-16c
@@ -312,16 +313,58 @@ auto:
   - image: x86_64-gnu-distcheck
     <<: *job-linux-8c
 
-  - image: x86_64-gnu-llvm-19
+  # The x86_64-gnu-llvm-19 job is split into multiple jobs to run tests in parallel.
+  # x86_64-gnu-llvm-19-1 skips tests that run in x86_64-gnu-llvm-19-{2,3}.
+  - image: x86_64-gnu-llvm-19-1
     env:
       RUST_BACKTRACE: 1
-    <<: *job-linux-8c
+      IMAGE: x86_64-gnu-llvm-19
+      DOCKER_SCRIPT: x86_64-gnu-llvm1.sh
+    <<: *job-linux-4c
 
-  - image: x86_64-gnu-llvm-18
+  # Skip tests that run in x86_64-gnu-llvm-19-{1,3}
+  - image: x86_64-gnu-llvm-19-2
+    env:
+      RUST_BACKTRACE: 1
+      IMAGE: x86_64-gnu-llvm-19
+      DOCKER_SCRIPT: x86_64-gnu-llvm2.sh
+    <<: *job-linux-4c
+
+  # Skip tests that run in x86_64-gnu-llvm-19-{1,2}
+  - image: x86_64-gnu-llvm-19-3
+    env:
+      RUST_BACKTRACE: 1
+      IMAGE: x86_64-gnu-llvm-19
+      DOCKER_SCRIPT: x86_64-gnu-llvm3.sh
+    <<: *job-linux-4c
+
+  # The x86_64-gnu-llvm-18 job is split into multiple jobs to run tests in parallel.
+  # x86_64-gnu-llvm-18-1 skips tests that run in x86_64-gnu-llvm-18-{2,3}.
+  - image: x86_64-gnu-llvm-18-1
     env:
       RUST_BACKTRACE: 1
       READ_ONLY_SRC: "0"
-    <<: *job-linux-8c
+      IMAGE: x86_64-gnu-llvm-18
+      DOCKER_SCRIPT: x86_64-gnu-llvm1.sh
+    <<: *job-linux-4c
+
+  # Skip tests that run in x86_64-gnu-llvm-18-{1,3}
+  - image: x86_64-gnu-llvm-18-2
+    env:
+      RUST_BACKTRACE: 1
+      READ_ONLY_SRC: "0"
+      IMAGE: x86_64-gnu-llvm-18
+      DOCKER_SCRIPT: x86_64-gnu-llvm2.sh
+    <<: *job-linux-4c
+
+  # Skip tests that run in x86_64-gnu-llvm-18-{1,2}
+  - image: x86_64-gnu-llvm-18-3
+    env:
+      RUST_BACKTRACE: 1
+      READ_ONLY_SRC: "0"
+      IMAGE: x86_64-gnu-llvm-18
+      DOCKER_SCRIPT: x86_64-gnu-llvm3.sh
+    <<: *job-linux-4c
 
   - image: x86_64-gnu-nopt
     <<: *job-linux-4c
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index f3d8a4edd6c..2341d25ff09 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -75,6 +75,7 @@
     - [s390x-unknown-linux-gnu](platform-support/s390x-unknown-linux-gnu.md)
     - [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md)
     - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
+    - [sparcv9-sun-solaris](platform-support/solaris.md)
     - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
     - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
     - [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
@@ -93,6 +94,7 @@
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
     - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
     - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
+    - [x86_64-pc-solaris](platform-support/solaris.md)
     - [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.md)
     - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
     - [xtensa-\*-none-elf](platform-support/xtensa.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 3b82d123276..c4efe27efc2 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -180,7 +180,7 @@ target | std | notes
 `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA)
 `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA)
 `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23)
-`sparcv9-sun-solaris` | ✓ | SPARC Solaris 11, illumos
+[`sparcv9-sun-solaris`](platform-support/solaris.md) | ✓ | SPARC V9 Solaris 11.4
 [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M
 [`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M
 [`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M, hardfloat
@@ -201,7 +201,7 @@ target | std | notes
 [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
 [`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia
 [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android
-`x86_64-pc-solaris` | ✓ | 64-bit Solaris 11, illumos
+[`x86_64-pc-solaris`](platform-support/solaris.md) | ✓ | 64-bit x86 Solaris 11.4
 [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI
 `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
 [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony
@@ -343,7 +343,7 @@ target | std | host | notes
 [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * |  |
 [`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ |  |
 [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
-`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
+`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv2)
 `powerpc64le-unknown-freebsd` | ✓ | ✓ | PPC64LE FreeBSD
 `powerpc-unknown-freebsd` | ? |   | PowerPC FreeBSD
 `powerpc64-unknown-linux-musl` | ? |  | 64-bit PowerPC Linux with musl 1.2.3
diff --git a/src/doc/rustc/src/platform-support/solaris.md b/src/doc/rustc/src/platform-support/solaris.md
new file mode 100644
index 00000000000..1e0a241f840
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/solaris.md
@@ -0,0 +1,32 @@
+# sparcv9-sun-solaris
+# x86_64-pc-solaris
+
+**Tier: 2**
+
+Rust for Solaris operating system.
+
+## Target maintainers
+
+- Petr Sumbera `sumbera@volny.cz`, https://github.com/psumbera
+
+## Requirements
+
+Binary built for this target is expected to run on sparcv9 or x86_64, and Solaris 11.4.
+
+## Testing
+
+For testing you can download Oracle Solaris 11.4 CBE release from:
+
+  https://www.oracle.com/uk/solaris/solaris11/downloads/solaris-downloads.html
+
+Solaris CBE release is also available for GitHub CI:
+
+  https://github.com/vmactions/solaris-vm
+
+Latest Solaris 11.4 SRU can be tested at Compile farm project:
+
+  https://portal.cfarm.net/machines/list/ (cfarm215, cfarm215)
+
+There are no official Rust binaries for Solaris available for Rustup yet. But you can eventually download unofficial from:
+
+  https://github.com/psumbera/solaris-rust
diff --git a/src/doc/rustdoc/src/read-documentation/search.md b/src/doc/rustdoc/src/read-documentation/search.md
index 718d2201c3a..e06dcdb7ed2 100644
--- a/src/doc/rustdoc/src/read-documentation/search.md
+++ b/src/doc/rustdoc/src/read-documentation/search.md
@@ -149,12 +149,16 @@ will match these queries:
 * `&mut Read -> Result<Vec<u8>, Error>`
 * `Read -> Result<Vec<u8>, Error>`
 * `Read -> Result<Vec<u8>>`
-* `Read -> u8`
+* `Read -> Vec<u8>`
 
 But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`,
 because those are nested incorrectly, and it does not match
 `Result<Error, Vec<u8>>` or `Result<Error>`, because those are
-in the wrong order.
+in the wrong order. It also does not match `Read -> u8`, because
+only [certain generic wrapper types] can be left out, and `Vec` isn't
+one of them.
+
+[certain generic wrapper types]: #wrappers-that-can-be-omitted
 
 To search for a function that accepts a function as a parameter,
 like `Iterator::all`, wrap the nested signature in parenthesis,
@@ -165,6 +169,18 @@ but you need to know which one you want.
 
 [iterator-all]: ../../std/vec/struct.Vec.html?search=Iterator<T>%2C+(T+->+bool)+->+bool&filter-crate=std
 
+### Wrappers that can be omitted
+
+* References
+* Box
+* Rc
+* Arc
+* Option
+* Result
+* From
+* Into
+* Future
+
 ### Primitives with Special Syntax
 
 | Shorthand        | Explicit names                                    |
@@ -234,11 +250,6 @@ Most of these limitations should be addressed in future version of Rustdoc.
     that you don't want a type parameter, you can force it to match
     something else by giving it a different prefix like `struct:T`.
 
-  * It's impossible to search for references or pointers. The
-    wrapped types can be searched for, so a function that takes `&File` can
-    be found with `File`, but you'll get a parse error when typing an `&`
-    into the search field.
-
   * Searching for lifetimes is not supported.
 
   * It's impossible to search based on the length of an array.
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index d81c47886d2..019a888bd2f 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -4,6 +4,7 @@ use std::iter::once;
 use std::sync::Arc;
 
 use rustc_data_structures::fx::FxHashSet;
+use rustc_hir as hir;
 use rustc_hir::Mutability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, DefIdSet, LocalDefId, LocalModDefId};
@@ -15,7 +16,6 @@ use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{Symbol, sym};
 use thin_vec::{ThinVec, thin_vec};
 use tracing::{debug, trace};
-use {rustc_ast as ast, rustc_hir as hir};
 
 use super::Item;
 use crate::clean::{
@@ -43,7 +43,7 @@ pub(crate) fn try_inline(
     cx: &mut DocContext<'_>,
     res: Res,
     name: Symbol,
-    attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>,
+    attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
     visited: &mut DefIdSet,
 ) -> Option<Vec<clean::Item>> {
     let did = res.opt_def_id()?;
@@ -206,7 +206,7 @@ pub(crate) fn try_inline_glob(
     }
 }
 
-pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast::Attribute] {
+pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [hir::Attribute] {
     cx.tcx.get_attrs_unchecked(did)
 }
 
@@ -360,7 +360,7 @@ fn build_type_alias(
 pub(crate) fn build_impls(
     cx: &mut DocContext<'_>,
     did: DefId,
-    attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>,
+    attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
     ret: &mut Vec<clean::Item>,
 ) {
     let _prof_timer = cx.tcx.sess.prof.generic_activity("build_inherent_impls");
@@ -392,8 +392,8 @@ pub(crate) fn build_impls(
 
 pub(crate) fn merge_attrs(
     cx: &mut DocContext<'_>,
-    old_attrs: &[ast::Attribute],
-    new_attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>,
+    old_attrs: &[hir::Attribute],
+    new_attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
 ) -> (clean::Attributes, Option<Arc<clean::cfg::Cfg>>) {
     // NOTE: If we have additional attributes (from a re-export),
     // always insert them first. This ensure that re-export
@@ -404,14 +404,14 @@ pub(crate) fn merge_attrs(
         both.extend_from_slice(old_attrs);
         (
             if let Some(item_id) = item_id {
-                Attributes::from_ast_with_additional(old_attrs, (inner, item_id.to_def_id()))
+                Attributes::from_hir_with_additional(old_attrs, (inner, item_id.to_def_id()))
             } else {
-                Attributes::from_ast(&both)
+                Attributes::from_hir(&both)
             },
             both.cfg(cx.tcx, &cx.cache.hidden_cfg),
         )
     } else {
-        (Attributes::from_ast(old_attrs), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg))
+        (Attributes::from_hir(old_attrs), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg))
     }
 }
 
@@ -419,7 +419,7 @@ pub(crate) fn merge_attrs(
 pub(crate) fn build_impl(
     cx: &mut DocContext<'_>,
     did: DefId,
-    attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>,
+    attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
     ret: &mut Vec<clean::Item>,
 ) {
     if !cx.inlined.insert(did.into()) {
@@ -629,7 +629,7 @@ fn build_module_items(
     visited: &mut DefIdSet,
     inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
     allowed_def_ids: Option<&DefIdSet>,
-    attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>,
+    attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
 ) -> Vec<clean::Item> {
     let mut items = Vec::new();
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 50dfe0a1b56..9903d0faf43 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -201,7 +201,7 @@ fn generate_item_with_correct_attrs(
     };
 
     let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
-    let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false);
+    let attrs = Attributes::from_hir_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false);
 
     let name = renamed.or(Some(name));
     let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, attrs, cfg);
@@ -1036,7 +1036,7 @@ fn clean_fn_or_proc_macro<'tcx>(
 /// This is needed to make it more "readable" when documenting functions using
 /// `rustc_legacy_const_generics`. More information in
 /// <https://github.com/rust-lang/rust/issues/83167>.
-fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attribute]) {
+fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attribute]) {
     for meta_item_list in attrs
         .iter()
         .filter(|a| a.has_name(sym::rustc_legacy_const_generics))
@@ -1839,8 +1839,15 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
             DynTrait(bounds, lifetime)
         }
         TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
+        TyKind::UnsafeBinder(..) => {
+            unimplemented!("unsafe binders are not supported yet")
+        }
         // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
-        TyKind::Infer | TyKind::Err(_) | TyKind::Typeof(..) | TyKind::InferDelegation(..) => Infer,
+        TyKind::Infer
+        | TyKind::Err(_)
+        | TyKind::Typeof(..)
+        | TyKind::InferDelegation(..)
+        | TyKind::TraitAscription(_) => Infer,
     }
 }
 
@@ -2571,7 +2578,7 @@ fn get_all_import_attributes<'hir>(
     import_def_id: LocalDefId,
     target_def_id: DefId,
     is_inline: bool,
-) -> Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)> {
+) -> Vec<(Cow<'hir, hir::Attribute>, Option<DefId>)> {
     let mut attrs = Vec::new();
     let mut first = true;
     for def_id in reexport_chain(cx.tcx, import_def_id, target_def_id)
@@ -2624,9 +2631,9 @@ fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool {
 
 /// Remove attributes from `normal` that should not be inherited by `use` re-export.
 /// Before calling this function, make sure `normal` is a `#[doc]` attribute.
-fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) {
-    match normal.item.args {
-        ast::AttrArgs::Delimited(ref mut args) => {
+fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) {
+    match args {
+        hir::AttrArgs::Delimited(ref mut args) => {
             let tokens = filter_tokens_from_list(&args.tokens, |token| {
                 !matches!(
                     token,
@@ -2644,7 +2651,7 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) {
             });
             args.tokens = TokenStream::new(tokens);
         }
-        ast::AttrArgs::Empty | ast::AttrArgs::Eq { .. } => {}
+        hir::AttrArgs::Empty | hir::AttrArgs::Eq { .. } => {}
     }
 }
 
@@ -2669,23 +2676,23 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) {
 /// * `doc(no_inline)`
 /// * `doc(hidden)`
 fn add_without_unwanted_attributes<'hir>(
-    attrs: &mut Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)>,
-    new_attrs: &'hir [ast::Attribute],
+    attrs: &mut Vec<(Cow<'hir, hir::Attribute>, Option<DefId>)>,
+    new_attrs: &'hir [hir::Attribute],
     is_inline: bool,
     import_parent: Option<DefId>,
 ) {
     for attr in new_attrs {
-        if matches!(attr.kind, ast::AttrKind::DocComment(..)) {
+        if matches!(attr.kind, hir::AttrKind::DocComment(..)) {
             attrs.push((Cow::Borrowed(attr), import_parent));
             continue;
         }
         let mut attr = attr.clone();
         match attr.kind {
-            ast::AttrKind::Normal(ref mut normal) => {
-                if let [ident] = &*normal.item.path.segments {
-                    let ident = ident.ident.name;
+            hir::AttrKind::Normal(ref mut normal) => {
+                if let [ident] = &*normal.path.segments {
+                    let ident = ident.name;
                     if ident == sym::doc {
-                        filter_doc_attr(normal, is_inline);
+                        filter_doc_attr(&mut normal.args, is_inline);
                         attrs.push((Cow::Owned(attr), import_parent));
                     } else if is_inline || ident != sym::cfg {
                         // If it's not a `cfg()` attribute, we keep it.
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index cba947eb833..d4dc35b6c9c 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -6,8 +6,6 @@ use std::{fmt, iter};
 
 use arrayvec::ArrayVec;
 use rustc_abi::{ExternAbi, VariantIdx};
-use rustc_ast::MetaItemInner;
-use rustc_ast_pretty::pprust;
 use rustc_attr::{ConstStability, Deprecation, Stability, StableSince};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -454,14 +452,14 @@ impl Item {
         kind: ItemKind,
         cx: &mut DocContext<'_>,
     ) -> Item {
-        let ast_attrs = cx.tcx.get_attrs_unchecked(def_id);
+        let hir_attrs = cx.tcx.get_attrs_unchecked(def_id);
 
         Self::from_def_id_and_attrs_and_parts(
             def_id,
             name,
             kind,
-            Attributes::from_ast(ast_attrs),
-            ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
+            Attributes::from_hir(hir_attrs),
+            hir_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
         )
     }
 
@@ -742,10 +740,10 @@ impl Item {
             .iter()
             .filter_map(|attr| {
                 if keep_as_is {
-                    Some(pprust::attribute_to_string(attr))
+                    Some(rustc_hir_pretty::attribute_to_string(&tcx, attr))
                 } else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
                     Some(
-                        pprust::attribute_to_string(attr)
+                        rustc_hir_pretty::attribute_to_string(&tcx, attr)
                             .replace("\\\n", "")
                             .replace('\n', "")
                             .replace("  ", " "),
@@ -955,7 +953,7 @@ pub(crate) trait AttributesExt {
     type AttributeIterator<'a>: Iterator<Item = ast::MetaItemInner>
     where
         Self: 'a;
-    type Attributes<'a>: Iterator<Item = &'a ast::Attribute>
+    type Attributes<'a>: Iterator<Item = &'a hir::Attribute>
     where
         Self: 'a;
 
@@ -1009,7 +1007,7 @@ pub(crate) trait AttributesExt {
             // #[doc]
             if attr.doc_str().is_none() && attr.has_name(sym::doc) {
                 // #[doc(...)]
-                if let Some(list) = attr.meta().as_ref().and_then(|mi| mi.meta_item_list()) {
+                if let Some(list) = attr.meta_item_list() {
                     for item in list {
                         // #[doc(hidden)]
                         if !item.has_name(sym::cfg) {
@@ -1042,7 +1040,7 @@ pub(crate) trait AttributesExt {
                     let mut meta = attr.meta_item().unwrap().clone();
                     meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature));
 
-                    if let Ok(feat_cfg) = Cfg::parse(&MetaItemInner::MetaItem(meta)) {
+                    if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) {
                         cfg &= feat_cfg;
                     }
                 }
@@ -1053,14 +1051,14 @@ pub(crate) trait AttributesExt {
     }
 }
 
-impl AttributesExt for [ast::Attribute] {
+impl AttributesExt for [hir::Attribute] {
     type AttributeIterator<'a> = impl Iterator<Item = ast::MetaItemInner> + 'a;
-    type Attributes<'a> = impl Iterator<Item = &'a ast::Attribute> + 'a;
+    type Attributes<'a> = impl Iterator<Item = &'a hir::Attribute> + 'a;
 
     fn lists(&self, name: Symbol) -> Self::AttributeIterator<'_> {
         self.iter()
             .filter(move |attr| attr.has_name(name))
-            .filter_map(ast::Attribute::meta_item_list)
+            .filter_map(ast::attr::AttributeExt::meta_item_list)
             .flatten()
     }
 
@@ -1069,20 +1067,20 @@ impl AttributesExt for [ast::Attribute] {
     }
 }
 
-impl AttributesExt for [(Cow<'_, ast::Attribute>, Option<DefId>)] {
+impl AttributesExt for [(Cow<'_, hir::Attribute>, Option<DefId>)] {
     type AttributeIterator<'a>
         = impl Iterator<Item = ast::MetaItemInner> + 'a
     where
         Self: 'a;
     type Attributes<'a>
-        = impl Iterator<Item = &'a ast::Attribute> + 'a
+        = impl Iterator<Item = &'a hir::Attribute> + 'a
     where
         Self: 'a;
 
     fn lists(&self, name: Symbol) -> Self::AttributeIterator<'_> {
         AttributesExt::iter(self)
             .filter(move |attr| attr.has_name(name))
-            .filter_map(ast::Attribute::meta_item_list)
+            .filter_map(hir::Attribute::meta_item_list)
             .flatten()
     }
 
@@ -1152,7 +1150,7 @@ pub struct RenderedLink {
 #[derive(Clone, Debug, Default)]
 pub(crate) struct Attributes {
     pub(crate) doc_strings: Vec<DocFragment>,
-    pub(crate) other_attrs: ast::AttrVec,
+    pub(crate) other_attrs: Vec<hir::Attribute>,
 }
 
 impl Attributes {
@@ -1180,22 +1178,22 @@ impl Attributes {
         self.has_doc_flag(sym::hidden)
     }
 
-    pub(crate) fn from_ast(attrs: &[ast::Attribute]) -> Attributes {
-        Attributes::from_ast_iter(attrs.iter().map(|attr| (attr, None)), false)
+    pub(crate) fn from_hir(attrs: &[hir::Attribute]) -> Attributes {
+        Attributes::from_hir_iter(attrs.iter().map(|attr| (attr, None)), false)
     }
 
-    pub(crate) fn from_ast_with_additional(
-        attrs: &[ast::Attribute],
-        (additional_attrs, def_id): (&[ast::Attribute], DefId),
+    pub(crate) fn from_hir_with_additional(
+        attrs: &[hir::Attribute],
+        (additional_attrs, def_id): (&[hir::Attribute], DefId),
     ) -> Attributes {
         // Additional documentation should be shown before the original documentation.
         let attrs1 = additional_attrs.iter().map(|attr| (attr, Some(def_id)));
         let attrs2 = attrs.iter().map(|attr| (attr, None));
-        Attributes::from_ast_iter(attrs1.chain(attrs2), false)
+        Attributes::from_hir_iter(attrs1.chain(attrs2), false)
     }
 
-    pub(crate) fn from_ast_iter<'a>(
-        attrs: impl Iterator<Item = (&'a ast::Attribute, Option<DefId>)>,
+    pub(crate) fn from_hir_iter<'a>(
+        attrs: impl Iterator<Item = (&'a hir::Attribute, Option<DefId>)>,
         doc_only: bool,
     ) -> Attributes {
         let (doc_strings, other_attrs) = attrs_to_doc_fragments(attrs, doc_only);
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index d59b4e4081c..617a7ab8097 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -578,7 +578,7 @@ pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
 }
 
 pub(crate) fn attrs_have_doc_flag<'a>(
-    mut attrs: impl Iterator<Item = &'a ast::Attribute>,
+    mut attrs: impl Iterator<Item = &'a hir::Attribute>,
     flag: Symbol,
 ) -> bool {
     attrs
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 70d9269ae5c..6fee049cdf0 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -13,10 +13,10 @@ use std::{panic, str};
 
 pub(crate) use make::DocTestBuilder;
 pub(crate) use markdown::test as test_markdown;
-use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
 use rustc_errors::emitter::HumanReadableErrorType;
 use rustc_errors::{ColorConfig, DiagCtxtHandle};
+use rustc_hir as hir;
 use rustc_hir::CRATE_HIR_ID;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_interface::interface;
@@ -325,7 +325,7 @@ pub(crate) fn run_tests(
 // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
 fn scrape_test_config(
     crate_name: String,
-    attrs: &[ast::Attribute],
+    attrs: &[hir::Attribute],
     args_file: PathBuf,
 ) -> GlobalTestOptions {
     use rustc_ast_pretty::pprust;
diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs
index 3ae60938749..a188bc8ebd9 100644
--- a/src/librustdoc/doctest/make.rs
+++ b/src/librustdoc/doctest/make.rs
@@ -51,8 +51,17 @@ impl DocTestBuilder {
                 !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate
             });
 
-        let SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else } =
-            partition_source(source, edition);
+        let Some(SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else }) =
+            partition_source(source, edition)
+        else {
+            return Self::invalid(
+                String::new(),
+                String::new(),
+                String::new(),
+                source.to_string(),
+                test_id,
+            );
+        };
 
         // Uses librustc_ast to parse the doctest and find if there's a main fn and the extern
         // crate already is included.
@@ -77,18 +86,7 @@ impl DocTestBuilder {
         else {
             // If the parser panicked due to a fatal error, pass the test code through unchanged.
             // The error will be reported during compilation.
-            return Self {
-                supports_color: false,
-                has_main_fn: false,
-                crate_attrs,
-                maybe_crate_attrs,
-                crates,
-                everything_else,
-                already_has_extern_crate: false,
-                test_id,
-                failed_ast: true,
-                can_be_merged: false,
-            };
+            return Self::invalid(crate_attrs, maybe_crate_attrs, crates, everything_else, test_id);
         };
         // If the AST returned an error, we don't want this doctest to be merged with the
         // others. Same if it contains `#[feature]` or `#[no_std]`.
@@ -113,6 +111,27 @@ impl DocTestBuilder {
         }
     }
 
+    fn invalid(
+        crate_attrs: String,
+        maybe_crate_attrs: String,
+        crates: String,
+        everything_else: String,
+        test_id: Option<String>,
+    ) -> Self {
+        Self {
+            supports_color: false,
+            has_main_fn: false,
+            crate_attrs,
+            maybe_crate_attrs,
+            crates,
+            everything_else,
+            already_has_extern_crate: false,
+            test_id,
+            failed_ast: true,
+            can_be_merged: false,
+        }
+    }
+
     /// Transforms a test into code that can be compiled into a Rust binary, and returns the number of
     /// lines before the test code begins.
     pub(crate) fn generate_unique_doctest(
@@ -518,8 +537,8 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit
         push_to.push('\n');
         // If it's complete, then we can clear the pending content.
         mod_attr_pending.clear();
-    } else if mod_attr_pending.ends_with('\\') {
-        mod_attr_pending.push('n');
+    } else {
+        mod_attr_pending.push_str("\n");
     }
 }
 
@@ -531,7 +550,7 @@ struct SourceInfo {
     everything_else: String,
 }
 
-fn partition_source(s: &str, edition: Edition) -> SourceInfo {
+fn partition_source(s: &str, edition: Edition) -> Option<SourceInfo> {
     #[derive(Copy, Clone, PartialEq)]
     enum PartitionState {
         Attrs,
@@ -606,11 +625,16 @@ fn partition_source(s: &str, edition: Edition) -> SourceInfo {
         }
     }
 
+    if !mod_attr_pending.is_empty() {
+        debug!("invalid doctest code: {s:?}");
+        return None;
+    }
+
     source_info.everything_else = source_info.everything_else.trim().to_string();
 
     debug!("crate_attrs:\n{}{}", source_info.crate_attrs, source_info.maybe_crate_attrs);
     debug!("crates:\n{}", source_info.crates);
     debug!("after:\n{}", source_info.everything_else);
 
-    source_info
+    Some(source_info)
 }
diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs
index dc68f48f635..0903baddabe 100644
--- a/src/librustdoc/doctest/rust.rs
+++ b/src/librustdoc/doctest/rust.rs
@@ -110,7 +110,7 @@ impl HirCollector<'_> {
 
         // The collapse-docs pass won't combine sugared/raw doc attributes, or included files with
         // anything else, this will combine them for us.
-        let attrs = Attributes::from_ast(ast_attrs);
+        let attrs = Attributes::from_hir(ast_attrs);
         if let Some(doc) = attrs.opt_doc_value() {
             let span = span_of_fragments(&attrs.doc_strings).unwrap_or(sp);
             self.collector.position = if span.edition().at_least_rust_2024() {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 0a563b1df26..7d40f662ed0 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1626,10 +1626,7 @@ pub(crate) trait PrintWithSpace {
 
 impl PrintWithSpace for hir::Safety {
     fn print_with_space(&self) -> &str {
-        match self {
-            hir::Safety::Unsafe => "unsafe ",
-            hir::Safety::Safe => "",
-        }
+        self.prefix_str()
     }
 }
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 4c8d704e65b..ced9ff2d685 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -469,7 +469,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
 
                 let unsafety_flag = match myitem.kind {
                     clean::FunctionItem(_) | clean::ForeignFunctionItem(..)
-                        if myitem.fn_header(tcx).unwrap().safety == hir::Safety::Unsafe =>
+                        if myitem.fn_header(tcx).unwrap().safety.is_unsafe() =>
                     {
                         "<sup title=\"unsafe function\">⚠</sup>"
                     }
@@ -1926,9 +1926,7 @@ fn item_static(
             buffer,
             "{vis}{safe}static {mutability}{name}: {typ}",
             vis = visibility_print_with_space(it, cx),
-            safe = safety
-                .map(|safe| if safe == hir::Safety::Unsafe { "unsafe " } else { "" })
-                .unwrap_or(""),
+            safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""),
             mutability = s.mutability.print_with_space(),
             name = it.name.unwrap(),
             typ = s.type_.print(cx)
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index cfb62c3ca16..2c26ffa76f6 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),
@@ -423,6 +423,14 @@ pub(crate) fn build_index(
                     }
                     Some(path)
                 });
+            } else if let Some(parent_idx) = item.parent_idx {
+                let i = <isize as TryInto<usize>>::try_into(parent_idx).unwrap();
+                item.path = {
+                    let p = &crate_paths[i].1;
+                    join_with_double_colon(&p[..p.len() - 1])
+                };
+                item.exact_path =
+                    crate_paths[i].2.as_ref().map(|xp| join_with_double_colon(&xp[..xp.len() - 1]));
             }
 
             // Omit the parent path if it is same to that of the prior item.
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 9e5cf497211..04eeee37fe8 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2592,7 +2592,12 @@ class DocSearch {
             const writeFn = (fnType, result) => {
                 if (fnType.id < 0) {
                     if (fnParamNames[-1 - fnType.id] === "") {
-                        for (const nested of fnType.generics) {
+                        // Normally, there's no need to shown an unhighlighted
+                        // where clause, but if it's impl Trait, then we do.
+                        const generics = fnType.generics.length > 0 ?
+                            fnType.generics :
+                            obj.type.where_clause[-1 - fnType.id];
+                        for (const nested of generics) {
                             writeFn(nested, result);
                         }
                         return;
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index bb967b7f163..be39984c3da 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -639,7 +639,7 @@ impl FromClean<clean::BareFunctionDecl> for FunctionPointer {
         let clean::BareFunctionDecl { safety, generic_params, decl, abi } = bare_decl;
         FunctionPointer {
             header: FunctionHeader {
-                is_unsafe: matches!(safety, rustc_hir::Safety::Unsafe),
+                is_unsafe: safety.is_unsafe(),
                 is_const: false,
                 is_async: false,
                 abi: convert_abi(abi),
@@ -669,7 +669,7 @@ impl FromClean<clean::Trait> for Trait {
     fn from_clean(trait_: clean::Trait, renderer: &JsonRenderer<'_>) -> Self {
         let tcx = renderer.tcx;
         let is_auto = trait_.is_auto(tcx);
-        let is_unsafe = trait_.safety(tcx) == rustc_hir::Safety::Unsafe;
+        let is_unsafe = trait_.safety(tcx).is_unsafe();
         let is_dyn_compatible = trait_.is_dyn_compatible(tcx);
         let clean::Trait { items, generics, bounds, .. } = trait_;
         Trait {
@@ -711,7 +711,7 @@ impl FromClean<clean::Impl> for Impl {
             ty::ImplPolarity::Negative => true,
         };
         Impl {
-            is_unsafe: safety == rustc_hir::Safety::Unsafe,
+            is_unsafe: safety.is_unsafe(),
             generics: generics.into_json(renderer),
             provided_trait_methods: provided_trait_methods
                 .into_iter()
@@ -840,7 +840,7 @@ fn convert_static(
     Static {
         type_: (*stat.type_).into_json(renderer),
         is_mutable: stat.mutability == ast::Mutability::Mut,
-        is_unsafe: safety == rustc_hir::Safety::Unsafe,
+        is_unsafe: safety.is_unsafe(),
         expr: stat
             .expr
             .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e)))
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index a384c286039..5d82b8e309a 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -846,11 +846,13 @@ fn main_args(
 
     let config = core::create_config(input, options, &render_options, using_internal_features);
 
+    let registered_lints = config.register_lints.is_some();
+
     interface::run_compiler(config, |compiler| {
         let sess = &compiler.sess;
 
         if sess.opts.describe_lints {
-            rustc_driver::describe_lints(sess);
+            rustc_driver::describe_lints(sess, registered_lints);
             return;
         }
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 20a443231846b81c7b909691ec3f15eb173f2b1
+Subproject 769f622e12db0001431d8ae36d1093fb8727c5d
diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
index d41bb580c6c..2325f914b0b 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
@@ -1,7 +1,7 @@
 use super::INLINE_ALWAYS;
 use super::utils::is_word;
 use clippy_utils::diagnostics::span_lint;
-use rustc_ast::Attribute;
+use rustc_hir::Attribute;
 use rustc_lint::LateContext;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, sym};
diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs
index 97cffeb098e..b4ed8a68a32 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs
@@ -2,14 +2,14 @@ use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_ast::token::{Token, TokenKind};
 use rustc_ast::tokenstream::TokenTree;
-use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind};
+use rustc_ast::{AttrArgs, AttrKind};
 use rustc_errors::Applicability;
 use rustc_lint::EarlyContext;
 use rustc_span::sym;
 
 pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
     if let AttrKind::Normal(normal_attr) = &attr.kind {
-        if let AttrArgs::Eq { value:  AttrArgsEq::Ast(_), .. } = &normal_attr.item.args {
+        if let AttrArgs::Eq { .. } = &normal_attr.item.args {
             // `#[should_panic = ".."]` found, good
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 383fae7992b..a1ff20dee72 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -5,9 +5,8 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{LimitStack, get_async_fn_body, is_async_fn};
 use core::ops::ControlFlow;
-use rustc_ast::ast::Attribute;
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{Body, Expr, ExprKind, FnDecl};
+use rustc_hir::{Attribute, Body, Expr, ExprKind, FnDecl};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index c300f7cd665..e3959903fdd 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -814,11 +814,13 @@ impl TyCoercionStability {
                 | TyKind::Tup(_)
                 | TyKind::Path(_) => Self::Deref,
                 TyKind::OpaqueDef(..)
+                | TyKind::TraitAscription(..)
                 | TyKind::Infer
                 | TyKind::Typeof(..)
                 | TyKind::TraitObject(..)
                 | TyKind::InferDelegation(..)
                 | TyKind::Err(_) => Self::Reborrow,
+                TyKind::UnsafeBinder(..) => Self::None,
             };
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 8125dab8adf..f65edd36253 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -7,7 +7,7 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item};
 use rustc_hir::{
-    self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, Safety, UnsafeSource,
+    self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
@@ -421,7 +421,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
         id: LocalDefId,
     ) -> Self::Result {
         if let Some(header) = kind.header()
-            && header.safety == Safety::Unsafe
+            && header.safety.is_unsafe()
         {
             ControlFlow::Break(())
         } else {
diff --git a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
index de7a2c2433f..099194d4e74 100644
--- a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
@@ -2,10 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{SpanRangeExt, snippet_indent};
 use clippy_utils::tokenize_with_text;
 use itertools::Itertools;
+use rustc_ast::AttrStyle;
 use rustc_ast::token::CommentKind;
-use rustc_ast::{AttrKind, AttrStyle, Attribute};
 use rustc_errors::{Applicability, Diag, SuggestionStyle};
-use rustc_hir::{ItemKind, Node};
+use rustc_hir::{AttrKind, Attribute, ItemKind, Node};
 use rustc_lexer::TokenKind;
 use rustc_lint::LateContext;
 use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData};
diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs
index 2182689f985..0bb16a0c77d 100644
--- a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs
@@ -1,18 +1,18 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_opt;
-use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute};
+use rustc_ast::{AttrStyle};
 use rustc_errors::Applicability;
 use rustc_lint::LateContext;
-use rustc_span::sym;
+use rustc_hir::{Attribute, AttrKind, AttrArgs};
 
 use super::DOC_INCLUDE_WITHOUT_CFG;
 
 pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
     for attr in attrs {
         if !attr.span.from_expansion()
-            && let AttrKind::Normal(ref normal) = attr.kind
-            && normal.item.path == sym::doc
-            && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
+            && let AttrKind::Normal(ref item) = attr.kind
+            && attr.doc_str().is_some()
+            && let AttrArgs::Eq { expr: meta, .. } = &item.args
             && !attr.span.contains(meta.span)
             // Since the `include_str` is already expanded at this point, we can only take the
             // whole attribute snippet and then modify for our suggestion.
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 88ac871acf6..f65acd7978a 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -16,10 +16,9 @@ use pulldown_cmark::Event::{
 };
 use pulldown_cmark::Tag::{BlockQuote, CodeBlock, FootnoteDefinition, Heading, Item, Link, Paragraph};
 use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options, TagEnd};
-use rustc_ast::ast::Attribute;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{AnonConst, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
+use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::lint::in_external_macro;
diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
index f6f942b10ca..84393213e6f 100644
--- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
@@ -1,7 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_ast::AttrStyle;
 use rustc_ast::token::CommentKind;
-use rustc_ast::{AttrKind, AttrStyle, Attribute};
 use rustc_errors::Applicability;
+use rustc_hir::Attribute;
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
@@ -35,7 +36,7 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> {
     attrs
         .iter()
         .filter_map(|attr| {
-            if let AttrKind::DocComment(com_kind, sym) = attr.kind
+            if let Some((sym, com_kind)) = attr.doc_str_and_comment_kind()
                 && let AttrStyle::Outer = attr.style
                 && let Some(com) = sym.as_str().strip_prefix('!')
             {
diff --git a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
index 0165d24c7df..0f9ff550853 100644
--- a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
@@ -1,6 +1,5 @@
-use rustc_ast::ast::Attribute;
 use rustc_errors::Applicability;
-use rustc_hir::{Item, ItemKind};
+use rustc_hir::{Attribute, Item, ItemKind};
 use rustc_lint::LateContext;
 
 use clippy_utils::diagnostics::span_lint_and_then;
diff --git a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
index ed27e38ef2d..1dac7b971f9 100644
--- a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
+++ b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
@@ -63,7 +63,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);
 
 impl EarlyLintPass for DuplicateMod {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, mod_spans)) = &item.kind
+        if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind
             && let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)
             && let Some(local_path) = real.into_local_path()
             && let Ok(absolute_path) = local_path.canonicalize()
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 8c22e43349f..2cd48ef98e5 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -281,7 +281,7 @@ fn check_inputs(
 }
 
 fn check_sig<'tcx>(closure_sig: FnSig<'tcx>, call_sig: FnSig<'tcx>) -> bool {
-    call_sig.safety == Safety::Safe && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig)
+    call_sig.safety.is_safe() && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig)
 }
 
 /// This walks through both signatures and checks for any time a late-bound region is expected by an
diff --git a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
index ffc76366983..dfea40db182 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
@@ -163,7 +163,7 @@ impl Visitor<'_> for NestingVisitor<'_, '_> {
         }
 
         match &item.kind {
-            ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => {
+            ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _, _)) => {
                 self.nest_level += 1;
 
                 if !self.check_indent(item.span, item.id) {
diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
index 2cbc4b07234..017571c38db 100644
--- a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind, Safety};
+use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::Span;
@@ -34,7 +34,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
         ImplicitSelfKind::None => return,
     };
 
-    let name = if sig.header.safety == Safety::Unsafe {
+    let name = if sig.header.safety.is_unsafe() {
         name.strip_suffix("_unchecked").unwrap_or(name)
     } else {
         name
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index 175d92d2d79..2b26285429a 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -1,9 +1,8 @@
 use hir::FnSig;
-use rustc_ast::ast::Attribute;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::DefIdSet;
-use rustc_hir::{self as hir, QPath};
+use rustc_hir::{self as hir, Attribute, QPath};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index 4986a311eba..3ded8dc3012 100644
--- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -42,7 +42,7 @@ fn check_raw_ptr<'tcx>(
     body: &'tcx hir::Body<'tcx>,
     def_id: LocalDefId,
 ) {
-    if safety == hir::Safety::Safe && cx.effective_visibilities.is_exported(def_id) {
+    if safety.is_safe() && cx.effective_visibilities.is_exported(def_id) {
         let raw_ptrs = iter_input_pats(decl, body)
             .filter_map(|arg| raw_ptr_arg(cx, arg))
             .collect::<HirIdSet>();
@@ -58,7 +58,7 @@ fn check_raw_ptr<'tcx>(
                     },
                     hir::ExprKind::MethodCall(_, recv, args, _) => {
                         let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap();
-                        if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety == hir::Safety::Unsafe {
+                        if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety.is_unsafe() {
                             check_arg(cx, &raw_ptrs, recv);
                             for arg in args {
                                 check_arg(cx, &raw_ptrs, arg);
diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
index ec6174bc030..e096dd25175 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::{implements_trait, is_type_lang_item};
 use clippy_utils::{return_ty, trait_ref_of_method};
-use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem, Safety};
+use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
@@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
         if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
             // #11201
             && let header = signature.header
-            && header.safety == Safety::Safe
+            && header.safety.is_safe()
             && header.abi == Abi::Rust
             && impl_item.ident.name == sym::to_string
             && let decl = signature.decl
diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs
index b38e362410e..66d4c40ab5e 100644
--- a/src/tools/clippy/clippy_lints/src/large_include_file.rs
+++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs
@@ -2,8 +2,8 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::source::snippet_opt;
-use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, LitKind};
-use rustc_hir::{Expr, ExprKind};
+use rustc_ast::{LitKind};
+use rustc_hir::{Expr, ExprKind, Attribute, AttrArgs, AttrKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
@@ -93,10 +93,10 @@ impl LateLintPass<'_> for LargeIncludeFile {
         if !attr.span.from_expansion()
             // Currently, rustc limits the usage of macro at the top-level of attributes,
             // so we don't need to recurse into each level.
-            && let AttrKind::Normal(ref normal) = attr.kind
+            && let AttrKind::Normal(ref item) = attr.kind
             && let Some(doc) = attr.doc_str()
             && doc.as_str().len() as u64 > self.max_file_size
-            && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
+            && let AttrArgs::Eq { expr: meta, .. } = &item.args
             && !attr.span.contains(meta.span)
             // Since the `include_str` is already expanded at this point, we can only take the
             // whole attribute snippet and then modify for our suggestion.
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index ed9879de13b..b679fdfadc3 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -156,7 +156,8 @@ fn never_loop_expr<'tcx>(
         | ExprKind::Field(e, _)
         | ExprKind::AddrOf(_, _, e)
         | ExprKind::Repeat(e, _)
-        | ExprKind::DropTemps(e) => never_loop_expr(cx, e, local_labels, main_loop_id),
+        | ExprKind::DropTemps(e)
+        | ExprKind::UnsafeBinderCast(_, e, _) => never_loop_expr(cx, e, local_labels, main_loop_id),
         ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id),
         ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id),
         ExprKind::MethodCall(_, receiver, es, _) => {
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index 22aa681b681..3c669d94d69 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet;
 use hir::def::{DefKind, Res};
-use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -104,7 +103,7 @@ impl LateLintPass<'_> for MacroUseImports {
             self.push_unique_macro_pat_ty(cx, item.span);
         }
     }
-    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
+    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) {
         if attr.span.from_expansion() {
             self.push_unique_macro(cx, attr.span);
         }
diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
index b12f575e81a..0e08e2eb83d 100644
--- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
@@ -6,8 +6,11 @@ use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_from_proc_macro, path_to_local};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::DefId;
 use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -94,6 +97,44 @@ impl ManualFloatMethods {
     }
 }
 
+fn is_not_const(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+    match tcx.def_kind(def_id) {
+        DefKind::Mod
+        | DefKind::Struct
+        | DefKind::Union
+        | DefKind::Enum
+        | DefKind::Variant
+        | DefKind::Trait
+        | DefKind::TyAlias
+        | DefKind::ForeignTy
+        | DefKind::TraitAlias
+        | DefKind::AssocTy
+        | DefKind::Macro(..)
+        | DefKind::Field
+        | DefKind::LifetimeParam
+        | DefKind::ExternCrate
+        | DefKind::Use
+        | DefKind::ForeignMod
+        | DefKind::GlobalAsm
+        | DefKind::Impl { .. }
+        | DefKind::OpaqueTy
+        | DefKind::SyntheticCoroutineBody
+        | DefKind::TyParam => true,
+
+        DefKind::AnonConst
+        | DefKind::InlineConst
+        | DefKind::Const
+        | DefKind::ConstParam
+        | DefKind::Static { .. }
+        | DefKind::Ctor(..)
+        | DefKind::AssocConst => false,
+
+        DefKind::Fn
+        | DefKind::AssocFn
+        | DefKind::Closure => tcx.constness(def_id) == Constness::NotConst,
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if let ExprKind::Binary(kind, lhs, rhs) = expr.kind
@@ -105,7 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
             && exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
             && !in_external_macro(cx.sess(), expr.span)
             && (
-                matches!(cx.tcx.constness(cx.tcx.hir().enclosing_body_owner(expr.hir_id)), Constness::NotConst)
+                is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into())
                     || self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
             )
             && let [first, second, const_1, const_2] = exprs
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
index 47472ab831f..223d0dc7656 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
@@ -2,9 +2,9 @@ use super::REDUNDANT_PATTERN_MATCHING;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment};
-use rustc_ast::{Attribute, LitKind};
+use rustc_ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath};
+use rustc_hir::{Arm, Attribute, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty;
 use rustc_span::source_map::Spanned;
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
index 3de51bc661e..5b9e9e70e47 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -3,13 +3,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::is_copy;
 use clippy_utils::usage::mutated_variables;
 use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
-use clippy_utils::{MaybePath, is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
+use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_lint::LateContext;
-use rustc_middle::query::Key;
 use rustc_middle::ty;
 use rustc_span::sym;
 
@@ -44,7 +43,6 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
             if name == "filter_map"
                 && let hir::ExprKind::Call(expr, args) = body.value.kind
                 && is_res_lang_ctor(cx, path_res(cx, expr), OptionSome)
-                && arg_id.ty_def_id() == args[0].hir_id().ty_def_id()
                 && let hir::ExprKind::Path(_) = args[0].kind
             {
                 span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 1300c7d1062..b6f49dcc163 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -10,8 +10,9 @@ use clippy_utils::attrs::is_doc_hidden;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::source::SpanRangeExt;
-use rustc_ast::ast::{self, MetaItem, MetaItemKind};
+use rustc_ast::ast::MetaItemInner;
 use rustc_hir as hir;
+use rustc_hir::Attribute;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -67,9 +68,8 @@ impl MissingDoc {
         *self.doc_hidden_stack.last().expect("empty doc_hidden_stack")
     }
 
-    fn has_include(meta: Option<MetaItem>) -> bool {
-        if let Some(meta) = meta
-            && let MetaItemKind::List(list) = meta.kind
+    fn has_include(meta: Option<&[MetaItemInner]>) -> bool {
+        if let Some(list) = meta
             && let Some(meta) = list.first()
             && let Some(name) = meta.ident()
         {
@@ -83,7 +83,7 @@ impl MissingDoc {
         &self,
         cx: &LateContext<'_>,
         def_id: LocalDefId,
-        attrs: &[ast::Attribute],
+        attrs: &[Attribute],
         sp: Span,
         article: &'static str,
         desc: &'static str,
@@ -129,7 +129,7 @@ impl MissingDoc {
 
         let has_doc = attrs
             .iter()
-            .any(|a| a.doc_str().is_some() || Self::has_include(a.meta()))
+            .any(|a| a.doc_str().is_some() || Self::has_include(a.meta_item_list().as_deref()))
             || matches!(self.search_span(sp), Some(span) if span_to_snippet_contains_docs(cx, span));
 
         if !has_doc {
@@ -172,12 +172,12 @@ impl MissingDoc {
 impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]);
 
 impl<'tcx> LateLintPass<'tcx> for MissingDoc {
-    fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) {
+    fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {
         let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs);
         self.doc_hidden_stack.push(doc_hidden);
     }
 
-    fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) {
+    fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [Attribute]) {
         self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index e587d695c84..11ff779d531 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
-use rustc_ast::ast;
 use rustc_hir as hir;
+use rustc_hir::Attribute;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::AssocItemContainer;
 use rustc_session::declare_lint_pass;
@@ -63,7 +63,7 @@ declare_clippy_lint! {
     "detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)"
 }
 
-fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) {
+fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[Attribute], sp: Span, desc: &'static str) {
     let has_inline = attrs.iter().any(|a| a.has_name(sym::inline));
     if !has_inline {
         span_lint(
diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
index 12bcc608174..79252bba74d 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::visitors::{Descend, Visitable, for_each_expr};
 use core::ops::ControlFlow::Continue;
 use hir::def::{DefKind, Res};
-use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp};
+use hir::{BlockCheckMode, ExprKind, QPath, UnOp};
 use rustc_ast::Mutability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -133,7 +133,7 @@ fn collect_unsafe_exprs<'tcx>(
                     ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
                     _ => return Continue(Descend::Yes),
                 };
-                if sig.safety() == Safety::Unsafe {
+                if sig.safety().is_unsafe() {
                     unsafe_ops.push(("unsafe function call occurs here", expr.span));
                 }
             },
@@ -144,7 +144,7 @@ fn collect_unsafe_exprs<'tcx>(
                     .type_dependent_def_id(expr.hir_id)
                     .map(|def_id| cx.tcx.fn_sig(def_id))
                 {
-                    if sig.skip_binder().safety() == Safety::Unsafe {
+                    if sig.skip_binder().safety().is_unsafe() {
                         unsafe_ops.push(("unsafe method call occurs here", expr.span));
                     }
                 }
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 6f3f371a68d..30846fb46ac 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -5,12 +5,11 @@ use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::ty::{
     implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
 };
-use rustc_ast::ast::Attribute;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, QPath,
-    TyKind,
+    Attribute, BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node,
+    PatKind, QPath, TyKind,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index b60fea3f03e..abdce69e764 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                     if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
                         let name = impl_item.ident.name;
                         let id = impl_item.owner_id;
-                        if sig.header.safety == hir::Safety::Unsafe {
+                        if sig.header.safety.is_unsafe() {
                             // can't be implemented for unsafe new
                             return;
                         }
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index dec4c18a309..44a8789462b 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -8,7 +8,7 @@ use rustc_hir::hir_id::{HirId, HirIdMap};
 use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{
     self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, ImplItemKind,
-    ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, Safety, TraitFn, TraitItem, TraitItemKind, TyKind,
+    ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind, TyKind,
 };
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{Obligation, ObligationCause};
@@ -541,7 +541,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
             .collect();
         if let Some(args) = args
             && !args.is_empty()
-            && body.is_none_or(|body| sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value))
+            && body.is_none_or(|body| sig.header.safety.is_unsafe() || contains_unsafe_block(cx, body.value))
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
index 0361836cdec..9596b85664b 100644
--- a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
@@ -1,5 +1,4 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::implements_trait;
 use rustc_hir::{Impl, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -54,8 +53,6 @@ impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl {
         }) = it.kind
             && let Some(trait_did) = trait_ref.trait_def_id()
             && cx.tcx.is_diagnostic_item(sym::ToString, trait_did)
-            && let Some(display_did) = cx.tcx.get_diagnostic_item(sym::Display)
-            && !implements_trait(cx, cx.tcx.type_of(it.owner_id).instantiate_identity(), display_did, &[])
         {
             span_lint_and_help(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index b79e59f857b..45d730985bb 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -203,7 +203,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
         let item_has_safety_comment = item_has_safety_comment(cx, item);
         match (&item.kind, item_has_safety_comment) {
             // lint unsafe impl without safety comment
-            (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety == hir::Safety::Unsafe => {
+            (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety.is_unsafe() => {
                 if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())
                     && !is_unsafe_from_proc_macro(cx, item.span)
                 {
@@ -227,7 +227,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
                 }
             },
             // lint safe impl with unnecessary safety comment
-            (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety == hir::Safety::Safe => {
+            (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety.is_safe() => {
                 if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {
                     let (span, help_span) = mk_spans(pos);
 
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 311ed427cb9..521bf6a5fed 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -623,6 +623,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 kind!("DropTemps({expr})");
                 self.expr(expr);
             },
+            ExprKind::UnsafeBinderCast(..) => {
+                unimplemented!("unsafe binders are not implemented yet");
+            }
         }
     }
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 620a9b56eb5..623d9c76086 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -379,7 +379,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         (Mod(lu, lmk), Mod(ru, rmk)) => {
             lu == ru
                 && match (lmk, rmk) {
-                    (ModKind::Loaded(litems, linline, _), ModKind::Loaded(ritems, rinline, _)) => {
+                    (ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => {
                         linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind))
                     },
                     (ModKind::Unloaded, ModKind::Unloaded) => true,
@@ -872,8 +872,7 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool {
     match (l, r) {
         (Empty, Empty) => true,
         (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra),
-        (Eq { value: AttrArgsEq::Ast(le), .. }, Eq{ value: AttrArgsEq::Ast(re), .. }) => eq_expr(le, re),
-        (Eq { value: AttrArgsEq::Hir(ll), .. }, Eq{ value: AttrArgsEq::Hir(rl), .. }) => ll.kind == rl.kind,
+        (Eq { eq_span: _, expr: le }, Eq { eq_span: _, expr: re }) => eq_expr(le, re),
         _ => false,
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index b2a6657baad..922afffb876 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -1,4 +1,5 @@
-use rustc_ast::{ast, attr};
+use rustc_ast::attr;
+use rustc_ast::attr::AttributeExt;
 use rustc_errors::Applicability;
 use rustc_lexer::TokenKind;
 use rustc_lint::LateContext;
@@ -51,33 +52,31 @@ impl LimitStack {
     pub fn limit(&self) -> u64 {
         *self.stack.last().expect("there should always be a value in the stack")
     }
-    pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
+    pub fn push_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) {
         let stack = &mut self.stack;
         parse_attrs(sess, attrs, name, |val| stack.push(val));
     }
-    pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
+    pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) {
         let stack = &mut self.stack;
         parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val)));
     }
 }
 
-pub fn get_attr<'a>(
+pub fn get_attr<'a, A: AttributeExt + 'a>(
     sess: &'a Session,
-    attrs: &'a [ast::Attribute],
+    attrs: &'a [A],
     name: &'static str,
-) -> impl Iterator<Item = &'a ast::Attribute> {
+) -> impl Iterator<Item = &'a A> {
     attrs.iter().filter(move |attr| {
-        let attr = if let ast::AttrKind::Normal(ref normal) = attr.kind {
-            &normal.item
-        } else {
+        let Some(attr_segments) = attr.ident_path() else {
             return false;
         };
-        let attr_segments = &attr.path.segments;
-        if attr_segments.len() == 2 && attr_segments[0].ident.name == sym::clippy {
+
+        if attr_segments.len() == 2 && attr_segments[0].name == sym::clippy {
             BUILTIN_ATTRIBUTES
                 .iter()
                 .find_map(|&(builtin_name, ref deprecation_status)| {
-                    if attr_segments[1].ident.name.as_str() == builtin_name {
+                    if attr_segments[1].name.as_str() == builtin_name {
                         Some(deprecation_status)
                     } else {
                         None
@@ -85,14 +84,13 @@ pub fn get_attr<'a>(
                 })
                 .map_or_else(
                     || {
-                        sess.dcx()
-                            .span_err(attr_segments[1].ident.span, "usage of unknown attribute");
+                        sess.dcx().span_err(attr_segments[1].span, "usage of unknown attribute");
                         false
                     },
                     |deprecation_status| {
                         let mut diag = sess
                             .dcx()
-                            .struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute");
+                            .struct_span_err(attr_segments[1].span, "usage of deprecated attribute");
                         match *deprecation_status {
                             DeprecationStatus::Deprecated => {
                                 diag.emit();
@@ -100,7 +98,7 @@ pub fn get_attr<'a>(
                             },
                             DeprecationStatus::Replaced(new_name) => {
                                 diag.span_suggestion(
-                                    attr_segments[1].ident.span,
+                                    attr_segments[1].span,
                                     "consider using",
                                     new_name,
                                     Applicability::MachineApplicable,
@@ -110,7 +108,7 @@ pub fn get_attr<'a>(
                             },
                             DeprecationStatus::None => {
                                 diag.cancel();
-                                attr_segments[1].ident.name.as_str() == name
+                                attr_segments[1].as_str() == name
                             },
                         }
                     },
@@ -121,31 +119,31 @@ pub fn get_attr<'a>(
     })
 }
 
-fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
+fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name: &'static str, mut f: F) {
     for attr in get_attr(sess, attrs, name) {
         if let Some(ref value) = attr.value_str() {
             if let Ok(value) = FromStr::from_str(value.as_str()) {
                 f(value);
             } else {
-                sess.dcx().span_err(attr.span, "not a number");
+                sess.dcx().span_err(attr.span(), "not a number");
             }
         } else {
-            sess.dcx().span_err(attr.span, "bad clippy attribute");
+            sess.dcx().span_err(attr.span(), "bad clippy attribute");
         }
     }
 }
 
-pub fn get_unique_attr<'a>(
+pub fn get_unique_attr<'a, A: AttributeExt>(
     sess: &'a Session,
-    attrs: &'a [ast::Attribute],
+    attrs: &'a [A],
     name: &'static str,
-) -> Option<&'a ast::Attribute> {
-    let mut unique_attr: Option<&ast::Attribute> = None;
+) -> Option<&'a A> {
+    let mut unique_attr: Option<&A> = None;
     for attr in get_attr(sess, attrs, name) {
         if let Some(duplicate) = unique_attr {
             sess.dcx()
-                .struct_span_err(attr.span, format!("`{name}` is defined multiple times"))
-                .with_span_note(duplicate.span, "first definition found here")
+                .struct_span_err(attr.span(), format!("`{name}` is defined multiple times"))
+                .with_span_note(duplicate.span(), "first definition found here")
                 .emit();
         } else {
             unique_attr = Some(attr);
@@ -156,16 +154,16 @@ pub fn get_unique_attr<'a>(
 
 /// Returns true if the attributes contain any of `proc_macro`,
 /// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
-pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
-    attrs.iter().any(rustc_ast::Attribute::is_proc_macro_attr)
+pub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool {
+    attrs.iter().any(AttributeExt::is_proc_macro_attr)
 }
 
 /// Returns true if the attributes contain `#[doc(hidden)]`
-pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool {
+pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool {
     attrs
         .iter()
         .filter(|attr| attr.has_name(sym::doc))
-        .filter_map(ast::Attribute::meta_item_list)
+        .filter_map(AttributeExt::meta_item_list)
         .any(|l| attr::list_contains_name(&l, sym::hidden))
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index 3269bf758ac..b71b53ea3bb 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -373,7 +373,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
         TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1),
         TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1),
         TyKind::BareFn(bare_fn) => (
-            if bare_fn.safety == Safety::Unsafe {
+            if bare_fn.safety.is_unsafe() {
                 Pat::Str("unsafe")
             } else if bare_fn.abi != Abi::Rust {
                 Pat::Str("extern")
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index 7f0363ac942..b5bb174e737 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -303,7 +303,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
                 | ExprKind::AddrOf(..)
                 | ExprKind::Repeat(..)
                 | ExprKind::Block(Block { stmts: [], .. }, _)
-                | ExprKind::OffsetOf(..) => (),
+                | ExprKind::OffsetOf(..)
+                | ExprKind::UnsafeBinderCast(..) => (),
 
                 // Assignment might be to a local defined earlier, so don't eagerly evaluate.
                 // Blocks with multiple statements might be expensive, so don't eagerly evaluate.
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index e318ad8671c..4b604f658b8 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -370,6 +370,10 @@ impl HirEqInterExpr<'_, '_, '_> {
                     && self.eq_expr(l_receiver, r_receiver)
                     && self.eq_exprs(l_args, r_args)
             },
+            (&ExprKind::UnsafeBinderCast(lkind, le, None), &ExprKind::UnsafeBinderCast(rkind, re, None)) =>
+                lkind == rkind && self.eq_expr(le, re),
+            (&ExprKind::UnsafeBinderCast(lkind, le, Some(lt)), &ExprKind::UnsafeBinderCast(rkind, re, Some(rt))) =>
+                lkind == rkind && self.eq_expr(le, re) && self.eq_ty(lt, rt),
             (&ExprKind::OffsetOf(l_container, l_fields), &ExprKind::OffsetOf(r_container, r_fields)) => {
                 self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name)
             },
@@ -424,6 +428,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 | &ExprKind::Type(..)
                 | &ExprKind::Unary(..)
                 | &ExprKind::Yield(..)
+                | &ExprKind::UnsafeBinderCast(..)
 
                 // --- Special cases that do not have a positive branch.
 
@@ -1032,6 +1037,13 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 std::mem::discriminant(&lop).hash(&mut self.s);
                 self.hash_expr(le);
             },
+            ExprKind::UnsafeBinderCast(kind, expr, ty) => {
+                std::mem::discriminant(&kind).hash(&mut self.s);
+                self.hash_expr(expr);
+                if let Some(ty) = ty {
+                    self.hash_ty(ty);
+                }
+            }
             ExprKind::Err(_) => {},
         }
     }
@@ -1241,11 +1253,15 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             TyKind::Typeof(anon_const) => {
                 self.hash_body(anon_const.body);
             },
+            TyKind::UnsafeBinder(binder) => {
+                self.hash_ty(binder.inner_ty);
+            }
             TyKind::Err(_)
             | TyKind::Infer
             | TyKind::Never
             | TyKind::InferDelegation(..)
-            | TyKind::OpaqueDef(_) => {},
+            | TyKind::OpaqueDef(_)
+            | TyKind::TraitAscription(_) => {},
         }
     }
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 8d48cdd3cbb..96139a08c3d 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -135,13 +135,24 @@ use rustc_middle::hir::nested_filter;
 
 #[macro_export]
 macro_rules! extract_msrv_attr {
-    ($context:ident) => {
-        fn check_attributes(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
+    (LateContext) => {
+        fn check_attributes(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) {
             let sess = rustc_lint::LintContext::sess(cx);
             self.msrv.check_attributes(sess, attrs);
         }
 
-        fn check_attributes_post(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
+        fn check_attributes_post(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) {
+            let sess = rustc_lint::LintContext::sess(cx);
+            self.msrv.check_attributes_post(sess, attrs);
+        }
+    };
+    (EarlyContext) => {
+        fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) {
+            let sess = rustc_lint::LintContext::sess(cx);
+            self.msrv.check_attributes(sess, attrs);
+        }
+
+        fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) {
             let sess = rustc_lint::LintContext::sess(cx);
             self.msrv.check_attributes_post(sess, attrs);
         }
@@ -1912,7 +1923,7 @@ pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: UintTy) -> u128 {
     (u << amt) >> amt
 }
 
-pub fn has_attr(attrs: &[ast::Attribute], symbol: Symbol) -> bool {
+pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool {
     attrs.iter().any(|attr| attr.has_name(symbol))
 }
 
@@ -2263,21 +2274,13 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
 
 pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
     cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
-        if let ast::AttrKind::Normal(ref normal) = attr.kind {
-            normal.item.path == sym::no_std
-        } else {
-            false
-        }
+        attr.name_or_empty() == sym::no_std
     })
 }
 
 pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
     cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
-        if let ast::AttrKind::Normal(ref normal) = attr.kind {
-            normal.item.path == sym::no_core
-        } else {
-            false
-        }
+        attr.name_or_empty() == sym::no_core
     })
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 1eb7d54e133..5b1c3465d05 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -1,4 +1,4 @@
-use rustc_ast::Attribute;
+use rustc_attr::AttributeExt;
 use rustc_attr::parse_version;
 use rustc_session::{RustcVersion, Session};
 use rustc_span::{Symbol, sym};
@@ -124,15 +124,15 @@ impl Msrv {
         self.current().is_none_or(|msrv| msrv >= required)
     }
 
-    fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
+    fn parse_attr(sess: &Session, attrs: &[impl AttributeExt]) -> Option<RustcVersion> {
         let sym_msrv = Symbol::intern("msrv");
         let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv]));
 
         if let Some(msrv_attr) = msrv_attrs.next() {
             if let Some(duplicate) = msrv_attrs.last() {
                 sess.dcx()
-                    .struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times")
-                    .with_span_note(msrv_attr.span, "first definition found here")
+                    .struct_span_err(duplicate.span(), "`clippy::msrv` is defined multiple times")
+                    .with_span_note(msrv_attr.span(), "first definition found here")
                     .emit();
             }
 
@@ -142,22 +142,22 @@ impl Msrv {
                 }
 
                 sess.dcx()
-                    .span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version"));
+                    .span_err(msrv_attr.span(), format!("`{msrv}` is not a valid Rust version"));
             } else {
-                sess.dcx().span_err(msrv_attr.span, "bad clippy attribute");
+                sess.dcx().span_err(msrv_attr.span(), "bad clippy attribute");
             }
         }
 
         None
     }
 
-    pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) {
+    pub fn check_attributes(&mut self, sess: &Session, attrs: &[impl AttributeExt]) {
         if let Some(version) = Self::parse_attr(sess, attrs) {
             self.stack.push(version);
         }
     }
 
-    pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) {
+    pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[impl AttributeExt]) {
         if Self::parse_attr(sess, attrs).is_some() {
             self.stack.pop();
         }
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 25ebe879192..088abd7c479 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -151,7 +151,8 @@ impl<'a> Sugg<'a> {
             | ExprKind::Become(..)
             | ExprKind::Struct(..)
             | ExprKind::Tup(..)
-            | ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)),
+            | ExprKind::Err(_)
+            | ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(get_snippet(expr.span)),
             ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet),
             ExprKind::Assign(lhs, rhs, _) => {
                 Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span))
@@ -226,7 +227,8 @@ impl<'a> Sugg<'a> {
             | ast::ExprKind::While(..)
             | ast::ExprKind::Await(..)
             | ast::ExprKind::Err(_)
-            | ast::ExprKind::Dummy => Sugg::NonParen(snippet(expr.span)),
+            | ast::ExprKind::Dummy
+            | ast::ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(snippet(expr.span)),
             ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp(
                 AssocOp::DotDot,
                 lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)),
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 260d1b801e3..bc3c3ca5c21 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind};
+use rustc_hir::{Expr, FnDecl, LangItem, TyKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::mir::ConstValue;
@@ -531,7 +531,7 @@ pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) {
 /// Returns `true` if the given type is an `unsafe` function.
 pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
     match ty.kind() {
-        ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety() == Safety::Unsafe,
+        ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety().is_unsafe(),
         _ => false,
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 351e619d7b1..71499b1293a 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr};
 use rustc_hir::{
     AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath,
-    Safety, Stmt, UnOp, UnsafeSource, StructTailExpr,
+    Stmt, UnOp, UnsafeSource, StructTailExpr,
 };
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
@@ -426,15 +426,15 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
                         .cx
                         .typeck_results()
                         .type_dependent_def_id(e.hir_id)
-                        .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe) =>
+                        .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe()) =>
                 {
                     ControlFlow::Break(())
                 },
                 ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() {
-                    ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => {
+                    ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe() => {
                         ControlFlow::Break(())
                     },
-                    ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => ControlFlow::Break(()),
+                    ty::FnPtr(_, hdr) if hdr.safety.is_unsafe() => ControlFlow::Break(()),
                     _ => walk_expr(self, e),
                 },
                 ExprKind::Path(ref p)
@@ -458,7 +458,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
         }
         fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
             if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind
-                && i.safety == Safety::Unsafe
+                && i.safety.is_unsafe()
             {
                 ControlFlow::Break(())
             } else {
@@ -694,6 +694,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
             | ExprKind::Continue(_)
             | ExprKind::InlineAsm(_)
             | ExprKind::OffsetOf(..)
+            | ExprKind::UnsafeBinderCast(..)
             | ExprKind::Err(_) => (),
         }
         ControlFlow::Continue(())
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
index 062bf25ea62..ee2868869de 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
@@ -20,7 +20,6 @@ LL | |     fn clone_self(&self) -> Self {
 LL | |         Self {
 LL | |             a: true,
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -32,7 +31,6 @@ LL | |     fn default() -> Self {
 LL | |         Self {
 LL | |             a: true,
 ...  |
-LL | |     }
 LL | | }
    | |_^
 
diff --git a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr
index ccdaecdd481..9cf6fc66757 100644
--- a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr
+++ b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr
@@ -66,8 +66,7 @@ error: this block is too nested
 LL |                   if true {
    |  _________________________^
 LL | |                     if true {
-LL | |
-LL | |                     }
+...  |
 LL | |                 }
    | |_________________^
    |
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index a44c810b135..9677beeb2c2 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
@@ -286,7 +286,6 @@ LL | |         if unsafe { true } {
 LL | |             todo!();
 LL | |         } else {
 ...  |
-LL | |         }
 LL | |     };
    | |______^
    |
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index db5ea5b6289..0eccdd42800 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -294,7 +294,6 @@ LL | |         if unsafe { true } {
 LL | |             todo!();
 LL | |         } else {
 ...  |
-LL | |         }
 LL | |     };
    | |______^
    |
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..474914299d0 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,12 +75,11 @@ 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 || {
    |  _______________________-
 LL | |         println!("I'm bored");
-LL | |         // Some more stuff
 ...  |
 LL | |         CustomFutureType
    | |         ^^^^^^^^^^^^^^^^
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/bind_instead_of_map_multipart.stderr b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
index 2adaecc96d6..d271381adea 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
@@ -44,7 +44,6 @@ LL | |         if {
 LL | |             if s == "43" {
 LL | |                 return Some(43);
 ...  |
-LL | |         }
 LL | |     });
    | |______^
    |
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
index 68ebb6ad781..36b17773973 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
@@ -115,8 +115,7 @@ error: all if blocks contain the same code at the end
   --> tests/ui/branches_sharing_code/shared_at_bottom.rs:183:5
    |
 LL | /         x << 2
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -131,8 +130,7 @@ error: all if blocks contain the same code at the end
   --> tests/ui/branches_sharing_code/shared_at_bottom.rs:192:5
    |
 LL | /         x * 4
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____^
    |
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.stderr b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
index 395c2dcf68d..45566a78bd8 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
@@ -43,9 +43,7 @@ LL |       } else {
    |  ____________^
 LL | |         if y == "world" {
 LL | |             println!("world")
-LL | |         }
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -66,9 +64,7 @@ LL |       } else {
    |  ____________^
 LL | |         if let Some(42) = Some(42) {
 LL | |             println!("world")
-LL | |         }
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -89,9 +85,7 @@ LL |       } else {
    |  ____________^
 LL | |         if let Some(42) = Some(42) {
 LL | |             println!("world")
-LL | |         }
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -112,9 +106,7 @@ LL |       } else {
    |  ____________^
 LL | |         if x == "hello" {
 LL | |             println!("world")
-LL | |         }
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -135,9 +127,7 @@ LL |       } else {
    |  ____________^
 LL | |         if let Some(42) = Some(42) {
 LL | |             println!("world")
-LL | |         }
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
diff --git a/src/tools/clippy/tests/ui/copy_iterator.stderr b/src/tools/clippy/tests/ui/copy_iterator.stderr
index 990b1ce628d..2f6378a85fe 100644
--- a/src/tools/clippy/tests/ui/copy_iterator.stderr
+++ b/src/tools/clippy/tests/ui/copy_iterator.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |
 LL | |     type Item = u8;
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
diff --git a/src/tools/clippy/tests/ui/crashes/ice-360.stderr b/src/tools/clippy/tests/ui/crashes/ice-360.stderr
index 50b245c65cd..9961eb21485 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-360.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-360.stderr
@@ -2,11 +2,7 @@ error: this loop never actually loops
   --> tests/ui/crashes/ice-360.rs:5:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     }
    | |_____^
    |
@@ -16,11 +12,7 @@ error: this loop could be written as a `while let` loop
   --> tests/ui/crashes/ice-360.rs:5:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     }
    | |_____^ help: try: `while let Some(ele) = iter.next() { .. }`
    |
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
index 7d7922ae8ca..bcc8684f7c2 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
+++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
@@ -2,8 +2,7 @@ error: this looks like you are trying to swap `a` and `b`
   --> tests/ui/crate_level_checks/no_std_swap.rs:12:5
    |
 LL | /     a = b;
-LL | |
-LL | |
+...  |
 LL | |     b = a;
    | |_________^ help: try: `core::mem::swap(&mut a, &mut b)`
    |
diff --git a/src/tools/clippy/tests/ui/derivable_impls.stderr b/src/tools/clippy/tests/ui/derivable_impls.stderr
index c22569145bd..0caea892358 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.stderr
+++ b/src/tools/clippy/tests/ui/derivable_impls.stderr
@@ -6,7 +6,6 @@ LL | |     fn default() -> Self {
 LL | |         Self {
 LL | |             a: false,
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
index 2852e26680f..c5d5f3d3759 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
@@ -99,8 +99,7 @@ LL | /     /// for OldA
 LL | |     // struct OldA;
 LL | |
 LL | |     /// Docs
-LL | |     /// for OldB
-LL | |     // struct OldB;
+...  |
 LL | |
    | |_^
 ...
diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
index 75fc23e9e7e..a95306e2fa3 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
@@ -103,8 +103,7 @@ error: empty lines after outer attribute
   --> tests/ui/empty_line_after/outer_attribute.rs:64:1
    |
 LL | / #[allow(unused)]
-LL | |
-LL | | // This comment is isolated
+...  |
 LL | |
    | |_^
 LL |   pub fn isolated_comment() {}
diff --git a/src/tools/clippy/tests/ui/entry.stderr b/src/tools/clippy/tests/ui/entry.stderr
index fb467676606..4b6bd3b4a25 100644
--- a/src/tools/clippy/tests/ui/entry.stderr
+++ b/src/tools/clippy/tests/ui/entry.stderr
@@ -16,8 +16,7 @@ LL | /     if !m.contains_key(&k) {
 LL | |         if true {
 LL | |             m.insert(k, v);
 LL | |         } else {
-LL | |             m.insert(k, v2);
-LL | |         }
+...  |
 LL | |     }
    | |_____^
    |
@@ -63,7 +62,6 @@ LL | |         if true {
 LL | |             m.insert(k, v);
 LL | |         } else {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -154,7 +152,6 @@ LL | |         foo();
 LL | |         match 0 {
 LL | |             0 if false => {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
diff --git a/src/tools/clippy/tests/ui/enum_variants.stderr b/src/tools/clippy/tests/ui/enum_variants.stderr
index aaac3cbb82d..ecca6c833ac 100644
--- a/src/tools/clippy/tests/ui/enum_variants.stderr
+++ b/src/tools/clippy/tests/ui/enum_variants.stderr
@@ -13,7 +13,6 @@ error: all variants have the same prefix: `c`
 LL | / enum Foo {
 LL | |
 LL | |     cFoo,
-LL | |
 ...  |
 LL | |     cBaz,
 LL | | }
@@ -45,9 +44,7 @@ error: all variants have the same prefix: `Food`
 LL | / enum Food {
 LL | |
 LL | |     FoodGood,
-LL | |
 ...  |
-LL | |
 LL | | }
    | |_^
    |
diff --git a/src/tools/clippy/tests/ui/fallible_impl_from.stderr b/src/tools/clippy/tests/ui/fallible_impl_from.stderr
index 62496148924..cc3739031b7 100644
--- a/src/tools/clippy/tests/ui/fallible_impl_from.stderr
+++ b/src/tools/clippy/tests/ui/fallible_impl_from.stderr
@@ -29,7 +29,6 @@ LL | |
 LL | |     fn from(i: usize) -> Invalid {
 LL | |         if i != 42 {
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -49,7 +48,6 @@ LL | |
 LL | |     fn from(s: Option<String>) -> Invalid {
 LL | |         let s = s.unwrap();
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -76,7 +74,6 @@ LL | |
 LL | |     fn from(s: &'a mut <Box<u32> as ProjStrTrait>::ProjString) -> Invalid {
 LL | |         if s.parse::<u32>().ok().unwrap() != 42 {
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.stderr b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
index 93507eb2c6f..369d6f66737 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
@@ -7,7 +7,6 @@ LL | |         for _ in &[42] {
 LL | |             let foo: &Option<_> = &Some::<u8>(42);
 LL | |             if foo.is_some() {
 ...  |
-LL | |         }
 LL | |     } else {
    | |_____^
    |
@@ -20,7 +19,6 @@ LL | |         for _ in &[42] {
 LL | |             let bar: &Option<_> = &Some::<u8>(42);
 LL | |             if bar.is_some() {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    = note: `-D clippy::if-same-then-else` implied by `-D warnings`
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..3b5705d5f21 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,12 +15,11 @@ 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 | |
 LL | |         loop {
-LL | |
 ...  |
 LL | |         do_something();
 LL | |     }
@@ -32,14 +31,12 @@ 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 | |
 LL | |             loop {
-LL | |
-LL | |                 do_something();
-LL | |             }
+...  |
 LL | |         }
    | |_________^
    |
@@ -49,7 +46,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 +60,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,13 +71,12 @@ 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() -> ! {
 LL | |             std::process::exit(0);
-LL | |         }
-LL | |         do_something();
+...  |
 LL | |     }
    | |_____^
    |
@@ -90,14 +86,13 @@ 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 | |
 LL | |         loop {
 LL | |             if cond {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -107,14 +102,13 @@ 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 | |
 LL | |         'inner: loop {
 LL | |             loop {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -124,7 +118,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,14 +132,13 @@ 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 | |
 LL | |             'inner: loop {
 LL | |                 loop {
 ...  |
-LL | |             }
 LL | |         }
    | |_________^
    |
@@ -155,14 +148,13 @@ 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 | |
 LL | |         match opt {
 LL | |             Some(v) => {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -172,7 +164,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 +178,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 +195,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 +209,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 +223,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 +237,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 +248,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,14 +264,13 @@ 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 | |
 LL | |         'inner: loop {
 LL | |             loop {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -289,7 +280,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 +295,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/into_iter_without_iter.stderr b/src/tools/clippy/tests/ui/into_iter_without_iter.stderr
index 533a7f68593..cde1b60c2ab 100644
--- a/src/tools/clippy/tests/ui/into_iter_without_iter.stderr
+++ b/src/tools/clippy/tests/ui/into_iter_without_iter.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |     type IntoIter = std::slice::Iter<'a, u8>;
 LL | |     type Item = &'a u8;
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -30,7 +29,6 @@ LL | |
 LL | |     type IntoIter = std::slice::IterMut<'a, u8>;
 LL | |     type Item = &'a mut u8;
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -52,7 +50,6 @@ LL | |
 LL | |     type IntoIter = std::slice::Iter<'a, T>;
 LL | |     type Item = &'a T;
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -74,7 +71,6 @@ LL | |
 LL | |     type IntoIter = std::slice::IterMut<'a, T>;
 LL | |     type Item = &'a mut T;
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -96,7 +92,6 @@ LL | |
 LL | |     type IntoIter = std::slice::IterMut<'a, T>;
 LL | |     type Item = &'a mut T;
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -117,8 +112,7 @@ LL | /         impl<'a> IntoIterator for &'a Issue12037 {
 LL | |             type IntoIter = std::slice::Iter<'a, u8>;
 LL | |             type Item = &'a u8;
 LL | |             fn into_iter(self) -> Self::IntoIter {
-LL | |                 todo!()
-LL | |             }
+...  |
 LL | |         }
    | |_________^
 ...
diff --git a/src/tools/clippy/tests/ui/manual_find.stderr b/src/tools/clippy/tests/ui/manual_find.stderr
index eb55a0c11f2..a4e7878a247 100644
--- a/src/tools/clippy/tests/ui/manual_find.stderr
+++ b/src/tools/clippy/tests/ui/manual_find.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |
 LL | |         if s == String::new() {
 ...  |
-LL | |     }
 LL | |     None
    | |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())`
    |
@@ -22,7 +21,6 @@ LL | |
 LL | |
 LL | |         if s == String::new() {
 ...  |
-LL | |     }
 LL | |     None
    | |________^ help: replace with an iterator: `arr.into_iter().map(|(s, _)| s).find(|s| s == String::new())`
    |
diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.stderr b/src/tools/clippy/tests/ui/manual_find_fixable.stderr
index c3f48fb9f98..5ed8be1b3ee 100644
--- a/src/tools/clippy/tests/ui/manual_find_fixable.stderr
+++ b/src/tools/clippy/tests/ui/manual_find_fixable.stderr
@@ -4,8 +4,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for &v in ARRAY {
 LL | |         if v == n {
 LL | |             return Some(v);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `ARRAY.iter().find(|&&v| v == n).copied()`
    |
@@ -18,8 +17,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for (a, _) in arr {
 LL | |         if a % 2 == 0 {
 LL | |             return Some(a);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0)`
 
@@ -29,8 +27,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for el in arr {
 LL | |         if el.name.len() == 10 {
 LL | |             return Some(el);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.name.len() == 10)`
    |
@@ -42,8 +39,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for Tuple(a, _) in arr {
 LL | |         if a >= 3 {
 LL | |             return Some(a);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `arr.into_iter().map(|Tuple(a, _)| a).find(|&a| a >= 3)`
 
@@ -53,8 +49,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for el in arr {
 LL | |         if el.should_keep() {
 LL | |             return Some(el);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.should_keep())`
    |
@@ -66,8 +61,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for el in arr {
 LL | |         if f(el) == 20 {
 LL | |             return Some(el);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `arr.into_iter().find(|&el| f(el) == 20)`
 
@@ -77,8 +71,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for &el in arr.values() {
 LL | |         if f(el) {
 LL | |             return Some(el);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `arr.values().find(|&&el| f(el)).copied()`
 
@@ -88,8 +81,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for el in arr {
 LL | |         if el.is_true {
 LL | |             return Some(el);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.is_true)`
    |
@@ -101,8 +93,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for (_, &x) in v {
 LL | |         if x > 10 {
 LL | |             return Some(x);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `v.into_iter().map(|(_, &x)| x).find(|&x| x > 10)`
 
@@ -112,8 +103,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for &(_, &x) in v {
 LL | |         if x > 10 {
 LL | |             return Some(x);
-LL | |         }
-LL | |     }
+...  |
 LL | |     None
    | |________^ help: replace with an iterator: `v.iter().map(|&(_, &x)| x).find(|&x| x > 10)`
 
@@ -123,8 +113,7 @@ error: manual implementation of `Iterator::find`
 LL | /     for x in arr {
 LL | |         if x >= 5 {
 LL | |             return Some(x);
-LL | |         }
-LL | |     }
+...  |
 LL | |     return None;
    | |________________^ help: replace with an iterator: `arr.into_iter().find(|&x| x >= 5)`
 
@@ -134,8 +123,7 @@ error: manual implementation of `Iterator::find`
 LL | /         for x in arr {
 LL | |             if x < 1 {
 LL | |                 return Some(x);
-LL | |             }
-LL | |         }
+...  |
 LL | |         None
    | |____________^ help: replace with an iterator: `arr.into_iter().find(|&x| x < 1)`
 
diff --git a/src/tools/clippy/tests/ui/manual_flatten.stderr b/src/tools/clippy/tests/ui/manual_flatten.stderr
index 3b64d9ef859..cf1b0a1c8bb 100644
--- a/src/tools/clippy/tests/ui/manual_flatten.stderr
+++ b/src/tools/clippy/tests/ui/manual_flatten.stderr
@@ -184,7 +184,6 @@ LL | |
 LL | |         Some(1),
 LL | |         Some(2),
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr
index 55a410982ad..dcd5d456111 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else.stderr
@@ -148,7 +148,6 @@ LL | |
 LL | |         v_some
 LL | |     } else {
 ...  |
-LL | |         }
 LL | |     };
    | |______^
    |
@@ -175,7 +174,6 @@ LL | |
 LL | |         v_some
 LL | |     } else {
 ...  |
-LL | |         }
 LL | |     };
    | |______^
    |
@@ -197,7 +195,6 @@ LL | |
 LL | |         v_some
 LL | |     } else {
 ...  |
-LL | |         }
 LL | |     };
    | |______^
    |
@@ -306,7 +303,6 @@ LL | |
 LL | |         v_some
 LL | |     } else {
 ...  |
-LL | |         }
 LL | |     };
    | |______^
    |
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.stderr b/src/tools/clippy/tests/ui/manual_unwrap_or.stderr
index c93a8952a08..a5a64ecb9a3 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.stderr
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.stderr
@@ -36,7 +36,6 @@ LL | |         Some(i) => i,
 LL | |         None => {
 LL | |             42 + 42
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -130,7 +129,6 @@ LL | |         Ok(i) => i,
 LL | |         Err(_) => {
 LL | |             42 + 42
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
index 128c95146aa..095bee52d6d 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
@@ -77,9 +77,6 @@ error: called `map(..).flatten()` on `Option`
    |
 LL |           .map(|_| {
    |  __________^
-LL | | // we need some newlines
-LL | | // so that the span is big enough
-LL | | // for a split output of the diagnostic
 ...  |
 LL | |         })
 LL | |         .flatten();
diff --git a/src/tools/clippy/tests/ui/match_bool.stderr b/src/tools/clippy/tests/ui/match_bool.stderr
index 1303e082daf..fb24e67ecee 100644
--- a/src/tools/clippy/tests/ui/match_bool.stderr
+++ b/src/tools/clippy/tests/ui/match_bool.stderr
@@ -75,9 +75,6 @@ error: you seem to be trying to match on a boolean expression
   --> tests/ui/match_bool.rs:36:5
    |
 LL | /     match test && test {
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |         _ => (),
 LL | |     };
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr
index 201b977e558..ffe5772ece9 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr
@@ -68,8 +68,7 @@ LL |           let _ans = match x {
    |  ____________________^
 LL | |             E::A(_) => {
 LL | |                 true
-LL | |             }
-LL | |             E::B(_) => true,
+...  |
 LL | |             _ => false,
 LL | |         };
    | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))`
diff --git a/src/tools/clippy/tests/ui/missing_doc.stderr b/src/tools/clippy/tests/ui/missing_doc.stderr
index 133c76ac9d4..6554eed1610 100644
--- a/src/tools/clippy/tests/ui/missing_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc.stderr
@@ -72,7 +72,6 @@ LL | |     /// dox
 LL | |     pub fn documented() {}
 LL | |     pub fn undocumented1() {}
 ...  |
-LL | |     }
 LL | | }
    | |_^
 
diff --git a/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
index a421fb986d3..d6a4342c503 100644
--- a/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
@@ -2,9 +2,7 @@ error: missing documentation for the crate
   --> tests/ui/missing_doc_crate_missing.rs:1:1
    |
 LL | / #![warn(clippy::missing_docs_in_private_items)]
-LL | |
-LL | |
-LL | |
+...  |
 LL | | fn main() {}
    | |____________^
    |
diff --git a/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr b/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr
index 8c1810909dd..5e51194c4b3 100644
--- a/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr
+++ b/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |     // unused field: hidden
 LL | |     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -28,7 +27,6 @@ LL | |
 LL | |     // unused fields: hidden, hidden2, hidden4
 LL | |     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -58,7 +56,6 @@ LL | |
 LL | |     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
 LL | |         let mut f = formatter.debug_struct("MultiExprDebugImpl");
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
index 9d3f639efbf..682140a1dfd 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |
 LL | |         if *v == 10 {
 ...  |
-LL | |         }
 LL | |     });
    | |_______^
    |
diff --git a/src/tools/clippy/tests/ui/needless_if.stderr b/src/tools/clippy/tests/ui/needless_if.stderr
index 9beae596ee3..cbfeb979d2f 100644
--- a/src/tools/clippy/tests/ui/needless_if.stderr
+++ b/src/tools/clippy/tests/ui/needless_if.stderr
@@ -34,7 +34,6 @@ error: this `if` branch is empty
 LL | /     if {
 LL | |         if let true = true
 LL | |             && true
-LL | |         {
 ...  |
 LL | |     } && true
 LL | |     {}
diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr
index 440a2b5aaba..dab3488af10 100644
--- a/src/tools/clippy/tests/ui/never_loop.stderr
+++ b/src/tools/clippy/tests/ui/never_loop.stderr
@@ -2,9 +2,6 @@ error: this loop never actually loops
   --> tests/ui/never_loop.rs:12:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |         // clippy::never_loop
 ...  |
 LL | |         break;
 LL | |     }
@@ -75,7 +72,6 @@ LL | |
 LL | |         // never loops
 LL | |         match x {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
@@ -126,7 +122,6 @@ LL | |
 LL | |         'b: {
 LL | |             break 'b 'c: {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr
index 37ef791edb0..32ff2276323 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.stderr
+++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr
@@ -115,8 +115,7 @@ LL |       let _ = if let Some(x) = arg {
    |  _____________^
 LL | |         x
 LL | |     } else {
-LL | |         // map_or_else must be suggested
-LL | |         side_effect()
+...  |
 LL | |     };
    | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)`
 
diff --git a/src/tools/clippy/tests/ui/question_mark.stderr b/src/tools/clippy/tests/ui/question_mark.stderr
index 0a48c4e80cb..06a8bd0de34 100644
--- a/src/tools/clippy/tests/ui/question_mark.stderr
+++ b/src/tools/clippy/tests/ui/question_mark.stderr
@@ -183,8 +183,7 @@ error: this block may be rewritten with the `?` operator
    |
 LL | /             if a.is_none() {
 LL | |                 return None;
-LL | |                 // do lint here, the outer `try` is not relevant here
-LL | |                 // https://github.com/rust-lang/rust-clippy/pull/11001#issuecomment-1610636867
+...  |
 LL | |             }
    | |_____________^ help: replace it with: `a?;`
 
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/clippy/tests/ui/significant_drop_tightening.stderr b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
index 2d7da4f394d..7d7e3ac7d0a 100644
--- a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
@@ -5,8 +5,7 @@ LL |   pub fn complex_return_triggers_the_lint() -> i32 {
    |  __________________________________________________-
 LL | |     fn foo() -> i32 {
 LL | |         1
-LL | |     }
-LL | |     let mutex = Mutex::new(1);
+...  |
 LL | |     let lock = mutex.lock().unwrap();
    | |         ^^^^
 ...  |
diff --git a/src/tools/clippy/tests/ui/single_match.stderr b/src/tools/clippy/tests/ui/single_match.stderr
index 9240b09c50a..dd03737279a 100644
--- a/src/tools/clippy/tests/ui/single_match.stderr
+++ b/src/tools/clippy/tests/ui/single_match.stderr
@@ -22,10 +22,7 @@ error: you seem to be trying to use `match` for destructuring a single pattern.
   --> tests/ui/single_match.rs:23:5
    |
 LL | /     match x {
-LL | |         // Note the missing block braces.
-LL | |         // We suggest `if let Some(y) = x { .. }` because the macro
-LL | |         // is expanded before we can do anything.
-LL | |         Some(y) => println!("{:?}", y),
+...  |
 LL | |         _ => (),
 LL | |     }
    | |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index a2801751a43..aa494520b84 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -68,8 +68,7 @@ LL | /     match Result::<i32, &Infallible>::Ok(1) {
 LL | |         Ok(a) => println!("${:?}", a),
 LL | |         Err(_) => {
 LL | |             println!("else block");
-LL | |             return;
-LL | |         }
+...  |
 LL | |     }
    | |_____^
    |
@@ -88,8 +87,7 @@ LL | /     match Cow::from("moo") {
 LL | |         Cow::Owned(a) => println!("${:?}", a),
 LL | |         Cow::Borrowed(_) => {
 LL | |             println!("else block");
-LL | |             return;
-LL | |         }
+...  |
 LL | |     }
    | |_____^
    |
diff --git a/src/tools/clippy/tests/ui/temporary_assignment.stderr b/src/tools/clippy/tests/ui/temporary_assignment.stderr
index 8c284594075..7e6529cb213 100644
--- a/src/tools/clippy/tests/ui/temporary_assignment.stderr
+++ b/src/tools/clippy/tests/ui/temporary_assignment.stderr
@@ -13,8 +13,7 @@ error: assignment to temporary
 LL | /     MultiStruct {
 LL | |
 LL | |         structure: Struct { field: 0 },
-LL | |     }
-LL | |     .structure
+...  |
 LL | |     .field = 1;
    | |______________^
 
diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.rs b/src/tools/clippy/tests/ui/to_string_trait_impl.rs
index 4c1202d4203..7be9f7994f0 100644
--- a/src/tools/clippy/tests/ui/to_string_trait_impl.rs
+++ b/src/tools/clippy/tests/ui/to_string_trait_impl.rs
@@ -30,46 +30,3 @@ impl Bar {
         String::from("Bar")
     }
 }
-
-mod issue12263 {
-    pub struct MyStringWrapper<'a>(&'a str);
-
-    impl std::fmt::Display for MyStringWrapper<'_> {
-        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-            self.0.fmt(f)
-        }
-    }
-
-    impl ToString for MyStringWrapper<'_> {
-        fn to_string(&self) -> String {
-            self.0.to_string()
-        }
-    }
-
-    pub struct S<T>(T);
-    impl std::fmt::Display for S<String> {
-        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-            todo!()
-        }
-    }
-    // no specialization if the generics differ, so lint
-    impl ToString for S<i32> {
-        fn to_string(&self) -> String {
-            todo!()
-        }
-    }
-
-    pub struct S2<T>(T);
-    impl std::fmt::Display for S2<String> {
-        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-            todo!()
-        }
-    }
-
-    // also specialization if the generics don't differ
-    impl ToString for S2<String> {
-        fn to_string(&self) -> String {
-            todo!()
-        }
-    }
-}
diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.stderr b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr
index 304c9a5e1fb..fe8afc215f0 100644
--- a/src/tools/clippy/tests/ui/to_string_trait_impl.stderr
+++ b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr
@@ -12,17 +12,5 @@ LL | | }
    = note: `-D clippy::to-string-trait-impl` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::to_string_trait_impl)]`
 
-error: direct implementation of `ToString`
-  --> tests/ui/to_string_trait_impl.rs:56:5
-   |
-LL | /     impl ToString for S<i32> {
-LL | |         fn to_string(&self) -> String {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
-   |
-   = help: prefer implementing `Display` instead
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/unit_cmp.stderr b/src/tools/clippy/tests/ui/unit_cmp.stderr
index f9473d3be26..9e067edb846 100644
--- a/src/tools/clippy/tests/ui/unit_cmp.stderr
+++ b/src/tools/clippy/tests/ui/unit_cmp.stderr
@@ -34,7 +34,6 @@ LL | |
 LL | |         {
 LL | |             true;
 ...  |
-LL | |         }
 LL | |     );
    | |_____^
 
@@ -46,7 +45,6 @@ LL | |
 LL | |         {
 LL | |             true;
 ...  |
-LL | |         }
 LL | |     );
    | |_____^
 
@@ -58,7 +56,6 @@ LL | |
 LL | |         {
 LL | |             true;
 ...  |
-LL | |         }
 LL | |     );
    | |_____^
 
@@ -70,7 +67,6 @@ LL | |
 LL | |         {
 LL | |             true;
 ...  |
-LL | |         }
 LL | |     );
    | |_____^
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
index bcdf65b217e..35a2144c389 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
@@ -434,11 +434,7 @@ error: unnecessary closure used to substitute value for `Result::Err`
    |
 LL |       let _: Result<usize, usize> = res.
    |  ___________________________________^
-LL | |     // some lines
-LL | |     // some lines
-LL | |     // some lines
 ...  |
-LL | |     // some lines
 LL | |     or_else(|_| Ok(ext_str.some_field));
    | |_______________________________________^
    |
diff --git a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
index 59986d895b3..b304d4dce6e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |
 LL | |     if a && b {
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -112,7 +111,6 @@ LL | |
 LL | |     if a && b {
 LL | |         return Some(());
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
@@ -139,7 +137,6 @@ LL | |
 LL | |     if a && b {
 LL | |         return Ok(());
 ...  |
-LL | |     }
 LL | | }
    | |_^
    |
diff --git a/src/tools/clippy/tests/ui/unwrap_in_result.stderr b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
index 752177aaca5..201d4ae36ae 100644
--- a/src/tools/clippy/tests/ui/unwrap_in_result.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |         // checks whether a string represents a number divisible by 3
 LL | |         let i = i_str.parse::<i32>().unwrap();
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
    |
diff --git a/src/tools/clippy/tests/ui/vec_init_then_push.stderr b/src/tools/clippy/tests/ui/vec_init_then_push.stderr
index 58720c9a181..f35625c9b08 100644
--- a/src/tools/clippy/tests/ui/vec_init_then_push.stderr
+++ b/src/tools/clippy/tests/ui/vec_init_then_push.stderr
@@ -2,8 +2,7 @@ error: calls to `push` immediately after creation
   --> tests/ui/vec_init_then_push.rs:5:5
    |
 LL | /     let mut def_err: Vec<u32> = Default::default();
-LL | |
-LL | |
+...  |
 LL | |     def_err.push(0);
    | |____________________^ help: consider using the `vec![]` macro: `let def_err: Vec<u32> = vec![..];`
    |
diff --git a/src/tools/clippy/tests/ui/while_let_loop.stderr b/src/tools/clippy/tests/ui/while_let_loop.stderr
index 5212d4fdcc7..10c2311d82f 100644
--- a/src/tools/clippy/tests/ui/while_let_loop.stderr
+++ b/src/tools/clippy/tests/ui/while_let_loop.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |
 LL | |         if let Some(_x) = y {
 ...  |
-LL | |         }
 LL | |     }
    | |_____^ help: try: `while let Some(_x) = y { .. }`
    |
@@ -45,7 +44,6 @@ LL | |
 LL | |         let x = match y {
 LL | |             Some(x) => x,
 ...  |
-LL | |         }
 LL | |     }
    | |_____^ help: try: `while let Some(x) = y { .. }`
 
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..8af4325e7b1 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1,6 +1,6 @@
 use std::borrow::Cow;
 use std::collections::{HashMap, HashSet};
-use std::ffi::OsString;
+use std::ffi::{OsStr, OsString};
 use std::fs::{self, File, create_dir_all};
 use std::hash::{DefaultHasher, Hash, Hasher};
 use std::io::prelude::*;
@@ -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, || ());
                 };
@@ -410,7 +410,12 @@ impl<'test> TestCx<'test> {
             truncated: Truncated::No,
             cmdline: format!("{cmd:?}"),
         };
-        self.dump_output(&proc_res.stdout, &proc_res.stderr);
+        self.dump_output(
+            self.config.verbose,
+            &cmd.get_program().to_string_lossy(),
+            &proc_res.stdout,
+            &proc_res.stderr,
+        );
 
         proc_res
     }
@@ -774,20 +779,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");
         }
@@ -1401,7 +1406,12 @@ impl<'test> TestCx<'test> {
             cmdline,
         };
 
-        self.dump_output(&result.stdout, &result.stderr);
+        self.dump_output(
+            self.config.verbose,
+            &command.get_program().to_string_lossy(),
+            &result.stdout,
+            &result.stderr,
+        );
 
         result
     }
@@ -1816,12 +1826,35 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn dump_output(&self, out: &str, err: &str) {
+    fn dump_output(&self, print_output: bool, proc_name: &str, out: &str, err: &str) {
         let revision = if let Some(r) = self.revision { format!("{}.", r) } else { String::new() };
 
         self.dump_output_file(out, &format!("{}out", revision));
         self.dump_output_file(err, &format!("{}err", revision));
-        self.maybe_dump_to_stdout(out, err);
+
+        if !print_output {
+            return;
+        }
+
+        let path = Path::new(proc_name);
+        let proc_name = if path.file_stem().is_some_and(|p| p == "rmake") {
+            OsString::from_iter(
+                path.parent()
+                    .unwrap()
+                    .file_name()
+                    .into_iter()
+                    .chain(Some(OsStr::new("/")))
+                    .chain(path.file_name()),
+            )
+        } else {
+            path.file_name().unwrap().into()
+        };
+        let proc_name = proc_name.to_string_lossy();
+        println!("------{proc_name} stdout------------------------------");
+        println!("{}", out);
+        println!("------{proc_name} stderr------------------------------");
+        println!("{}", err);
+        println!("------------------------------------------");
     }
 
     fn dump_output_file(&self, out: &str, extension: &str) {
@@ -1874,20 +1907,10 @@ impl<'test> TestCx<'test> {
         output_base_name(self.config, self.testpaths, self.safe_revision())
     }
 
-    fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
-        if self.config.verbose {
-            eprintln!("------stdout------------------------------");
-            eprintln!("{}", out);
-            eprintln!("------stderr------------------------------");
-            eprintln!("{}", err);
-            eprintln!("------------------------------------------");
-        }
-    }
-
     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 +1995,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 +2105,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 +2519,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 +2624,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 +2654,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 +2806,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 +2864,7 @@ impl ProcRes {
             }
         }
 
-        eprintln!(
+        println!(
             "status: {}\ncommand: {}\n{}\n{}\n",
             self.status,
             self.cmdline,
@@ -2852,7 +2875,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/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
index 04bc2d7787d..85ade5b727a 100644
--- a/src/tools/compiletest/src/runtest/run_make.rs
+++ b/src/tools/compiletest/src/runtest/run_make.rs
@@ -517,14 +517,13 @@ impl TestCx<'_> {
 
         let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn `rmake`"));
         let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc);
+        let stdout = String::from_utf8_lossy(&stdout).into_owned();
+        let stderr = String::from_utf8_lossy(&stderr).into_owned();
+        // This conditions on `status.success()` so we don't print output twice on error.
+        // NOTE: this code is called from a libtest thread, so it's hidden by default unless --nocapture is passed.
+        self.dump_output(status.success(), &cmd.get_program().to_string_lossy(), &stdout, &stderr);
         if !status.success() {
-            let res = ProcRes {
-                status,
-                stdout: String::from_utf8_lossy(&stdout).into_owned(),
-                stderr: String::from_utf8_lossy(&stderr).into_owned(),
-                truncated,
-                cmdline: format!("{:?}", cmd),
-            };
+            let res = ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) };
             self.fatal_proc_rec("rmake recipe failed to complete", &res);
         }
     }
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/src/helpers.rs b/src/tools/miri/src/helpers.rs
index b57ce4e070c..1f7c60ad1bd 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -149,10 +149,9 @@ pub fn iter_exported_symbols<'tcx>(
     let dependency_formats = tcx.dependency_formats(());
     // Find the dependencies of the executable we are running.
     let dependency_format = dependency_formats
-        .iter()
-        .find(|(crate_type, _)| *crate_type == CrateType::Executable)
+        .get(&CrateType::Executable)
         .expect("interpreting a non-executable crate");
-    for cnum in dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| {
+    for cnum in dependency_format.iter().enumerate().filter_map(|(num, &linkage)| {
         // We add 1 to the number because that's what rustc also does everywhere it
         // calls `CrateNum::new`...
         #[expect(clippy::arithmetic_side_effects)]
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 7cc22f83a24..ac26feb345c 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1571,8 +1571,12 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         res
     }
 
-    fn after_local_read(ecx: &InterpCx<'tcx, Self>, local: mir::Local) -> InterpResult<'tcx> {
-        if let Some(data_race) = &ecx.frame().extra.data_race {
+    fn after_local_read(
+        ecx: &InterpCx<'tcx, Self>,
+        frame: &Frame<'tcx, Provenance, FrameExtra<'tcx>>,
+        local: mir::Local,
+    ) -> InterpResult<'tcx> {
+        if let Some(data_race) = &frame.extra.data_race {
             data_race.local_read(local, &ecx.machine);
         }
         interp_ok(())
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr
index 23a9f8f9c28..6540543d8da 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr
@@ -24,8 +24,7 @@ note: inside `main`
 LL | /     thread::spawn(|| {
 LL | |         unsafe {
 LL | |             assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0);
-LL | |         }
-LL | |     })
+...  |
 LL | |     .join()
    | |___________^
 
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr
index d9ab782986f..2875a5be285 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr
@@ -14,7 +14,6 @@ LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: <TAG> is this argument
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr
index 677952b39da..c699987b796 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr
@@ -16,7 +16,6 @@ LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: the protected tag <TAG> was created here, in the initial state Reserved
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr
index efdd6129d74..f20ec00f97b 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr
@@ -14,7 +14,6 @@ LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
-LL | |
 LL | |     }
    | |_____^
 help: <TAG> is this argument
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr
index 5746ad1e13d..8996c3643db 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr
@@ -16,7 +16,6 @@ LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
-LL | |
 LL | |     }
    | |_____^
 help: the protected tag <TAG> was created here, in the initial state Reserved
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr
index b009b0901c4..47e5ee48292 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr
@@ -14,7 +14,6 @@ LL | |         {
 LL | |             let x = 0;
 LL | |             let ptr = &raw mut x;
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: <TAG> is this argument
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr
index 6d2cbe9b7cd..7eb237ca1a7 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr
@@ -16,7 +16,6 @@ LL | |         {
 LL | |             let x = 0;
 LL | |             let ptr = &raw mut x;
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: the protected tag <TAG> was created here, in the initial state Reserved
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr
index 54f9a7aebd6..813042f06a6 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr
@@ -14,7 +14,6 @@ LL | |         {
 LL | |             let _x = 0;
 LL | |             let ptr = &raw mut _x;
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: <TAG> is this argument
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr
index 693534be2e0..5090ec06b78 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr
@@ -16,7 +16,6 @@ LL | |         {
 LL | |             let _x = 0;
 LL | |             let ptr = &raw mut _x;
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: the protected tag <TAG> was created here, in the initial state Reserved
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr
index 520937beaeb..a6a0362a226 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr
@@ -14,7 +14,6 @@ LL | |         {
 LL | |             let _x = 0;
 LL | |             let ptr = &raw mut _x;
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: <TAG> is this argument
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr
index a879189d0c1..26a54fe8748 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr
@@ -16,7 +16,6 @@ LL | |         {
 LL | |             let _x = 0;
 LL | |             let ptr = &raw mut _x;
 ...  |
-LL | |         }
 LL | |     }
    | |_____^
 help: the protected tag <TAG> was created here, in the initial state Reserved
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/src/tools/run-make-support/src/assertion_helpers.rs b/src/tools/run-make-support/src/assertion_helpers.rs
index b4da65aff4a..e84a3cf633f 100644
--- a/src/tools/run-make-support/src/assertion_helpers.rs
+++ b/src/tools/run-make-support/src/assertion_helpers.rs
@@ -5,16 +5,31 @@ use std::path::Path;
 
 use crate::{fs, regex};
 
+fn print<'a, 'e, A: AsRef<str>, E: AsRef<str>>(
+    assertion_kind: &str,
+    haystack: &'a A,
+    needle: &'e E,
+) -> (&'a str, &'e str) {
+    let haystack = haystack.as_ref();
+    let needle = needle.as_ref();
+    eprintln!("{assertion_kind}:");
+    eprintln!("=== HAYSTACK ===");
+    eprintln!("{}", haystack);
+    eprintln!("=== NEEDLE ===");
+    eprintln!("{}", needle);
+    (haystack, needle)
+}
+
 /// Assert that `actual` is equal to `expected`.
 #[track_caller]
 pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) {
     let actual = actual.as_ref();
     let expected = expected.as_ref();
+    eprintln!("=== ACTUAL TEXT ===");
+    eprintln!("{}", actual);
+    eprintln!("=== EXPECTED ===");
+    eprintln!("{}", expected);
     if actual != expected {
-        eprintln!("=== ACTUAL TEXT ===");
-        eprintln!("{}", actual);
-        eprintln!("=== EXPECTED ===");
-        eprintln!("{}", expected);
         panic!("expected text was not found in actual text");
     }
 }
@@ -22,13 +37,8 @@ pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) {
 /// Assert that `haystack` contains `needle`.
 #[track_caller]
 pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
-    let haystack = haystack.as_ref();
-    let needle = needle.as_ref();
+    let (haystack, needle) = print("assert_contains", &haystack, &needle);
     if !haystack.contains(needle) {
-        eprintln!("=== HAYSTACK ===");
-        eprintln!("{}", haystack);
-        eprintln!("=== NEEDLE ===");
-        eprintln!("{}", needle);
         panic!("needle was not found in haystack");
     }
 }
@@ -36,13 +46,8 @@ pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
 /// Assert that `haystack` does not contain `needle`.
 #[track_caller]
 pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
-    let haystack = haystack.as_ref();
-    let needle = needle.as_ref();
+    let (haystack, needle) = print("assert_not_contains", &haystack, &needle);
     if haystack.contains(needle) {
-        eprintln!("=== HAYSTACK ===");
-        eprintln!("{}", haystack);
-        eprintln!("=== NEEDLE ===");
-        eprintln!("{}", needle);
         panic!("needle was unexpectedly found in haystack");
     }
 }
@@ -50,14 +55,9 @@ pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N)
 /// Assert that `haystack` contains the regex pattern `needle`.
 #[track_caller]
 pub fn assert_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
-    let haystack = haystack.as_ref();
-    let needle = needle.as_ref();
+    let (haystack, needle) = print("assert_contains_regex", &haystack, &needle);
     let re = regex::Regex::new(needle).unwrap();
     if !re.is_match(haystack) {
-        eprintln!("=== HAYSTACK ===");
-        eprintln!("{}", haystack);
-        eprintln!("=== NEEDLE ===");
-        eprintln!("{}", needle);
         panic!("needle was not found in haystack");
     }
 }
@@ -65,14 +65,9 @@ pub fn assert_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle:
 /// Assert that `haystack` does not contain the regex pattern `needle`.
 #[track_caller]
 pub fn assert_not_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
-    let haystack = haystack.as_ref();
-    let needle = needle.as_ref();
+    let (haystack, needle) = print("assert_not_contains_regex", &haystack, &needle);
     let re = regex::Regex::new(needle).unwrap();
     if re.is_match(haystack) {
-        eprintln!("=== HAYSTACK ===");
-        eprintln!("{}", haystack);
-        eprintln!("=== NEEDLE ===");
-        eprintln!("{}", needle);
         panic!("needle was unexpectedly found in haystack");
     }
 }
@@ -80,13 +75,8 @@ pub fn assert_not_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, need
 /// Assert that `haystack` contains `needle` a `count` number of times.
 #[track_caller]
 pub fn assert_count_is<H: AsRef<str>, N: AsRef<str>>(count: usize, haystack: H, needle: N) {
-    let haystack = haystack.as_ref();
-    let needle = needle.as_ref();
+    let (haystack, needle) = print("assert_count_is", &haystack, &needle);
     if count != haystack.matches(needle).count() {
-        eprintln!("=== HAYSTACK ===");
-        eprintln!("{}", haystack);
-        eprintln!("=== NEEDLE ===");
-        eprintln!("{}", needle);
         panic!("needle did not appear {count} times in haystack");
     }
 }
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index ffe10092cc2..8894ea7fb20 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -325,6 +325,12 @@ impl Rustc {
         self
     }
 
+    /// Pass the `--verbose` flag.
+    pub fn verbose(&mut self) -> &mut Self {
+        self.cmd.arg("--verbose");
+        self
+    }
+
     /// `EXTRARSCXXFLAGS`
     pub fn extra_rs_cxx_flags(&mut self) -> &mut Self {
         // Adapted from tools.mk (trimmed):
diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml
index d82e46016dc..46bae20054c 100644
--- a/src/tools/rust-analyzer/.github/workflows/ci.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml
@@ -220,7 +220,7 @@ jobs:
     timeout-minutes: 10
     env:
       FORCE_COLOR: 1
-      TYPOS_VERSION: v1.18.0
+      TYPOS_VERSION: v1.28.3
     steps:
       - name: download typos
         run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin
diff --git a/src/tools/rust-analyzer/.typos.toml b/src/tools/rust-analyzer/.typos.toml
index febfb233bd9..0f2f9b1b275 100644
--- a/src/tools/rust-analyzer/.typos.toml
+++ b/src/tools/rust-analyzer/.typos.toml
@@ -16,7 +16,8 @@ extend-ignore-re = [
     "raison d'être",
     "inout",
     "INOUT",
-    "optin"
+    "optin",
+    "=Pn",
 ]
 
 [default.extend-words]
@@ -26,8 +27,12 @@ fo = "fo"
 ket = "ket"
 makro = "makro"
 trivias = "trivias"
+thir = "thir"
+jod = "jod"
 
 [default.extend-identifiers]
+anc = "anc"
 datas = "datas"
 impl_froms = "impl_froms"
 selfs = "selfs"
+taits = "taits"
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 8c1d82de1da..ab6580a97a7 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -390,6 +390,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1"
 
 [[package]]
+name = "edition"
+version = "0.0.0"
+
+[[package]]
 name = "either"
 version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1266,6 +1270,7 @@ name = "parser"
 version = "0.0.0"
 dependencies = [
  "drop_bomb",
+ "edition",
  "expect-test",
  "limit",
  "ra-ap-rustc_lexer",
@@ -2662,6 +2667,7 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "directories",
+ "edition",
  "either",
  "flate2",
  "itertools",
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index f7074f91354..8086569a781 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -83,6 +83,7 @@ toolchain = { path = "./crates/toolchain", version = "0.0.0" }
 tt = { path = "./crates/tt", version = "0.0.0" }
 vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
 vfs = { path = "./crates/vfs", version = "0.0.0" }
+edition = { path = "./crates/edition", version = "0.0.0" }
 
 ra-ap-rustc_lexer = { version = "0.85", default-features = false }
 ra-ap-rustc_parse_format = { version = "0.85", default-features = false }
diff --git a/src/tools/rust-analyzer/crates/edition/Cargo.toml b/src/tools/rust-analyzer/crates/edition/Cargo.toml
new file mode 100644
index 00000000000..926b1e1cd41
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/edition/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "edition"
+version = "0.0.0"
+rust-version.workspace = true
+edition.workspace = true
+license.workspace = true
+authors.workspace = true
+repository.workspace = true
+
+[dependencies]
+
+[lints]
+workspace = true
diff --git a/src/tools/rust-analyzer/crates/parser/src/edition.rs b/src/tools/rust-analyzer/crates/edition/src/lib.rs
index 702b16252d4..c25d5b9557b 100644
--- a/src/tools/rust-analyzer/crates/parser/src/edition.rs
+++ b/src/tools/rust-analyzer/crates/edition/src/lib.rs
@@ -1,6 +1,5 @@
 //! The edition of the Rust language used in a crate.
-// Ideally this would be defined in the span crate, but the dependency chain is all over the place
-// wrt to span, parser and syntax.
+// This should live in a separate crate because we use it in both actual code and codegen.
 use std::fmt;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
index 4894c7a9311..b76db2e0052 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
@@ -74,7 +74,7 @@ impl BuiltinFnLikeExpander {
     }
 
     pub fn is_asm(&self) -> bool {
-        matches!(self, Self::Asm | Self::GlobalAsm)
+        matches!(self, Self::Asm | Self::GlobalAsm | Self::NakedAsm)
     }
 }
 
@@ -122,6 +122,7 @@ register_builtin! {
     (stringify, Stringify) => stringify_expand,
     (asm, Asm) => asm_expand,
     (global_asm, GlobalAsm) => asm_expand,
+    (naked_asm, NakedAsm) => asm_expand,
     (cfg, Cfg) => cfg_expand,
     (core_panic, CorePanic) => panic_expand,
     (std_panic, StdPanic) => panic_expand,
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index 2ee598dfbfd..5aafe6db527 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -28,6 +28,7 @@ use rustc_hash::FxHashMap;
 use stdx::TupleExt;
 use triomphe::Arc;
 
+use core::fmt;
 use std::hash::Hash;
 
 use base_db::{ra_salsa::InternValueTrivial, CrateId};
@@ -147,6 +148,10 @@ impl ExpandError {
     pub fn span(&self) -> Span {
         self.inner.1
     }
+
+    pub fn render_to_string(&self, db: &dyn ExpandDatabase) -> RenderedExpandError {
+        self.inner.0.render_to_string(db)
+    }
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Hash)]
@@ -164,18 +169,18 @@ pub enum ExpandErrorKind {
     ProcMacroPanic(Box<str>),
 }
 
-impl ExpandError {
-    pub fn render_to_string(&self, db: &dyn ExpandDatabase) -> RenderedExpandError {
-        self.inner.0.render_to_string(db)
-    }
-}
-
 pub struct RenderedExpandError {
     pub message: String,
     pub error: bool,
     pub kind: &'static str,
 }
 
+impl fmt::Display for RenderedExpandError {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.message)
+    }
+}
+
 impl RenderedExpandError {
     const GENERAL_KIND: &str = "macro-error";
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 3dfa0e97cec..de8ce56df64 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -1053,8 +1053,21 @@ impl HirDisplay for Ty {
                             generic_args_sans_defaults(f, Some(generic_def_id), parameters);
                         assert!(params_len >= parameters.len());
                         let defaults = params_len - parameters.len();
-                        let without_impl =
-                            self_param as usize + type_ + const_ + lifetime - defaults;
+
+                        // Normally, functions cannot have default parameters, but they can,
+                        // for function-like things such as struct names or enum variants.
+                        // The former cannot have defaults but parents, and the later cannot have
+                        // parents but defaults.
+                        // So, if `parent_len` > 0, it have a parent and thus it doesn't have any
+                        // default. Therefore, we shouldn't subtract defaults because those defaults
+                        // are from their parents.
+                        // And if `parent_len` == 0, either parents don't exists or they don't have
+                        // any defaults. Thus, we can - and should - subtract defaults.
+                        let without_impl = if parent_len > 0 {
+                            params_len - parent_len - impl_
+                        } else {
+                            params_len - parent_len - impl_ - defaults
+                        };
                         // parent's params (those from enclosing impl or trait, if any).
                         let (fn_params, parent_params) = parameters.split_at(without_impl + impl_);
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs
index 3dbefc5cec8..804c3aea3a5 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs
@@ -55,7 +55,7 @@ impl chalk_ir::interner::Interner for Interner {
     type InternedConst = Interned<InternedWrapper<ConstData>>;
     type InternedConcreteConst = ConstScalar;
     type InternedGenericArg = GenericArgData;
-    // We could do the following, but that saves "only" 20mb on self while increasing inferecene
+    // We could do the following, but that saves "only" 20mb on self while increasing inference
     // time by ~2.5%
     // type InternedGoal = Interned<InternedWrapper<GoalData>>;
     type InternedGoal = Arc<GoalData>;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
index e15d44bd6de..dda7bfb2baf 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
@@ -4380,7 +4380,7 @@ fn test() {
 fn associated_type_in_struct_expr_path() {
     // FIXME: All annotation should be resolvable.
     // For lines marked as unstable, see rust-lang/rust#86935.
-    // FIXME: Remove the comments once stablized.
+    // FIXME: Remove the comments once stabilized.
     check_types(
         r#"
 trait Trait {
@@ -4416,7 +4416,7 @@ impl Trait for () {
 fn associated_type_in_struct_expr_path_enum() {
     // FIXME: All annotation should be resolvable.
     // For lines marked as unstable, see rust-lang/rust#86935.
-    // FIXME: Remove the comments once stablized.
+    // FIXME: Remove the comments once stabilized.
     check_types(
         r#"
 trait Trait {
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 83d72dfcf14..3bc2eee1e7c 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -2649,24 +2649,31 @@ impl Const {
         Type::from_value_def(db, self.id)
     }
 
-    /// Evaluate the constant and return the result as a string.
-    ///
-    /// This function is intended for IDE assistance, different from [`Const::render_eval`].
-    pub fn eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> {
-        let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
-        Ok(format!("{}", c.display(db, self.krate(db).edition(db))))
+    /// Evaluate the constant.
+    pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> {
+        db.const_eval(self.id.into(), Substitution::empty(Interner), None)
+            .map(|it| EvaluatedConst { const_: it, def: self.id.into() })
     }
+}
 
-    /// Evaluate the constant and return the result as a string, with more detailed information.
-    ///
-    /// This function is intended for user-facing display.
-    pub fn render_eval(
-        self,
-        db: &dyn HirDatabase,
-        edition: Edition,
-    ) -> Result<String, ConstEvalError> {
-        let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
-        let data = &c.data(Interner);
+impl HasVisibility for Const {
+    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+        db.const_visibility(self.id)
+    }
+}
+
+pub struct EvaluatedConst {
+    def: DefWithBodyId,
+    const_: hir_ty::Const,
+}
+
+impl EvaluatedConst {
+    pub fn render(&self, db: &dyn HirDatabase, edition: Edition) -> String {
+        format!("{}", self.const_.display(db, edition))
+    }
+
+    pub fn render_debug(&self, db: &dyn HirDatabase) -> Result<String, MirEvalError> {
+        let data = self.const_.data(Interner);
         if let TyKind::Scalar(s) = data.ty.kind(Interner) {
             if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) {
                 if let hir_ty::ConstValue::Concrete(c) = &data.value {
@@ -2689,17 +2696,7 @@ impl Const {
                 }
             }
         }
-        if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) {
-            Ok(s)
-        } else {
-            Ok(format!("{}", c.display(db, edition)))
-        }
-    }
-}
-
-impl HasVisibility for Const {
-    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
-        db.const_visibility(self.id)
+        mir::render_const_using_debug_impl(db, self.def, &self.const_)
     }
 }
 
@@ -2729,51 +2726,10 @@ impl Static {
         Type::from_value_def(db, self.id)
     }
 
-    /// Evaluate the static and return the result as a string.
-    ///
-    /// This function is intended for IDE assistance, different from [`Static::render_eval`].
-    pub fn eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> {
-        let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
-        Ok(format!("{}", c.display(db, self.krate(db).edition(db))))
-    }
-
-    /// Evaluate the static and return the result as a string, with more detailed information.
-    ///
-    /// This function is intended for user-facing display.
-    pub fn render_eval(
-        self,
-        db: &dyn HirDatabase,
-        edition: Edition,
-    ) -> Result<String, ConstEvalError> {
-        let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
-        let data = &c.data(Interner);
-        if let TyKind::Scalar(s) = data.ty.kind(Interner) {
-            if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) {
-                if let hir_ty::ConstValue::Concrete(c) = &data.value {
-                    if let hir_ty::ConstScalar::Bytes(b, _) = &c.interned {
-                        let value = u128::from_le_bytes(mir::pad16(b, false));
-                        let value_signed =
-                            i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_))));
-                        let mut result = if let Scalar::Int(_) = s {
-                            value_signed.to_string()
-                        } else {
-                            value.to_string()
-                        };
-                        if value >= 10 {
-                            format_to!(result, " ({value:#X})");
-                            return Ok(result);
-                        } else {
-                            return Ok(result);
-                        }
-                    }
-                }
-            }
-        }
-        if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) {
-            Ok(s)
-        } else {
-            Ok(format!("{}", c.display(db, edition)))
-        }
+    /// Evaluate the static initializer.
+    pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> {
+        db.const_eval(self.id.into(), Substitution::empty(Interner), None)
+            .map(|it| EvaluatedConst { const_: it, def: self.id.into() })
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index f9d3f9d07e6..b896cda9ddf 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -28,7 +28,7 @@ use hir_expand::{
     hygiene::SyntaxContextExt as _,
     inert_attr_macro::find_builtin_attr_idx,
     name::AsName,
-    FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt,
+    ExpandResult, FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt,
 };
 use intern::Symbol;
 use itertools::Itertools;
@@ -381,7 +381,13 @@ impl<'db> SemanticsImpl<'db> {
         node
     }
 
-    pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
+    pub fn expand(&self, file_id: MacroFileId) -> ExpandResult<SyntaxNode> {
+        let res = self.db.parse_macro_expansion(file_id).map(|it| it.0.syntax_node());
+        self.cache(res.value.clone(), file_id.into());
+        res
+    }
+
+    pub fn expand_macro_call(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
         let sa = self.analyze_no_infer(macro_call.syntax())?;
 
         let macro_call = InFile::new(sa.file_id, macro_call);
@@ -412,7 +418,10 @@ impl<'db> SemanticsImpl<'db> {
 
     /// Expands the macro if it isn't one of the built-in ones that expand to custom syntax or dummy
     /// expansions.
-    pub fn expand_allowed_builtins(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
+    pub fn expand_allowed_builtins(
+        &self,
+        macro_call: &ast::MacroCall,
+    ) -> Option<ExpandResult<SyntaxNode>> {
         let sa = self.analyze_no_infer(macro_call.syntax())?;
 
         let macro_call = InFile::new(sa.file_id, macro_call);
@@ -434,6 +443,7 @@ impl<'db> SemanticsImpl<'db> {
                     | BuiltinFnLikeExpander::ModulePath
                     | BuiltinFnLikeExpander::Asm
                     | BuiltinFnLikeExpander::GlobalAsm
+                    | BuiltinFnLikeExpander::NakedAsm
                     | BuiltinFnLikeExpander::LogSyntax
                     | BuiltinFnLikeExpander::TraceMacros
                     | BuiltinFnLikeExpander::FormatArgs
@@ -447,15 +457,15 @@ impl<'db> SemanticsImpl<'db> {
             return None;
         }
 
-        let node = self.parse_or_expand(file_id.into());
+        let node = self.expand(file_id);
         Some(node)
     }
 
     /// If `item` has an attribute macro attached to it, expands it.
-    pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
+    pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<ExpandResult<SyntaxNode>> {
         let src = self.wrap_node_infile(item.clone());
         let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(src.as_ref()))?;
-        Some(self.parse_or_expand(macro_call_id.as_file()))
+        Some(self.expand(macro_call_id.as_macro_file()))
     }
 
     pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Attr) -> Option<SyntaxNode> {
@@ -479,15 +489,16 @@ impl<'db> SemanticsImpl<'db> {
         })
     }
 
-    pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<SyntaxNode>> {
+    pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<ExpandResult<SyntaxNode>>> {
         let res: Vec<_> = self
             .derive_macro_calls(attr)?
             .into_iter()
             .flat_map(|call| {
-                let file_id = call?.as_file();
-                let node = self.db.parse_or_expand(file_id);
-                self.cache(node.clone(), file_id);
-                Some(node)
+                let file_id = call?.as_macro_file();
+                let ExpandResult { value, err } = self.db.parse_macro_expansion(file_id);
+                let root_node = value.0.syntax_node();
+                self.cache(root_node.clone(), file_id.into());
+                Some(ExpandResult { value: root_node, err })
             })
             .collect();
         Some(res)
@@ -555,7 +566,7 @@ impl<'db> SemanticsImpl<'db> {
 
     /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the
     /// expansion. `token_to_map` should be a token from the `speculative args` node.
-    pub fn speculative_expand(
+    pub fn speculative_expand_macro_call(
         &self,
         actual_macro_call: &ast::MacroCall,
         speculative_args: &ast::TokenTree,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index 6937d33ebc1..438769a0a87 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -7,6 +7,7 @@ use hir::{
     TypeInfo, TypeParam,
 };
 use ide_db::{
+    assists::GroupLabel,
     defs::{Definition, NameRefClass},
     famous_defs::FamousDefs,
     helpers::mod_path_to_ast,
@@ -104,7 +105,8 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
 
     let scope = ImportScope::find_insert_use_container(&node, &ctx.sema)?;
 
-    acc.add(
+    acc.add_group(
+        &GroupLabel("Extract into...".to_owned()),
         AssistId("extract_function", crate::AssistKind::RefactorExtract),
         "Extract into function",
         target_range,
@@ -5009,7 +5011,7 @@ fn $0fun_name(bar: &str) {
     }
 
     #[test]
-    fn unresolveable_types_default_to_placeholder() {
+    fn unresolvable_types_default_to_placeholder() {
         check_assist(
             extract_function,
             r#"
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
index 61dc72e0b33..a8d71ed7f4d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
@@ -1,17 +1,15 @@
-use hir::TypeInfo;
-use ide_db::syntax_helpers::suggest_name;
+use hir::{HirDisplay, TypeInfo};
+use ide_db::{assists::GroupLabel, syntax_helpers::suggest_name};
 use syntax::{
     ast::{
         self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory,
         AstNode,
     },
     syntax_editor::Position,
-    NodeOrToken,
-    SyntaxKind::{BLOCK_EXPR, BREAK_EXPR, COMMENT, LOOP_EXPR, MATCH_GUARD, PATH_EXPR, RETURN_EXPR},
-    SyntaxNode, T,
+    NodeOrToken, SyntaxKind, SyntaxNode, T,
 };
 
-use crate::{AssistContext, AssistId, AssistKind, Assists};
+use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: extract_variable
 //
@@ -29,6 +27,40 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 //     var_name * 4;
 // }
 // ```
+
+// Assist: extract_constant
+//
+// Extracts subexpression into a constant.
+//
+// ```
+// fn main() {
+//     $0(1 + 2)$0 * 4;
+// }
+// ```
+// ->
+// ```
+// fn main() {
+//     const $0VAR_NAME: i32 = 1 + 2;
+//     VAR_NAME * 4;
+// }
+// ```
+
+// Assist: extract_static
+//
+// Extracts subexpression into a static.
+//
+// ```
+// fn main() {
+//     $0(1 + 2)$0 * 4;
+// }
+// ```
+// ->
+// ```
+// fn main() {
+//     static $0VAR_NAME: i32 = 1 + 2;
+//     VAR_NAME * 4;
+// }
+// ```
 pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let node = if ctx.has_empty_selection() {
         if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) {
@@ -41,7 +73,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
     } else {
         match ctx.covering_element() {
             NodeOrToken::Node(it) => it,
-            NodeOrToken::Token(it) if it.kind() == COMMENT => {
+            NodeOrToken::Token(it) if it.kind() == SyntaxKind::COMMENT => {
                 cov_mark::hit!(extract_var_in_comment_is_not_applicable);
                 return None;
             }
@@ -87,116 +119,150 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
             }
             _ => false,
         };
-
-    let anchor = Anchor::from(&to_extract)?;
+    let module = ctx.sema.scope(to_extract.syntax())?.module();
     let target = to_extract.syntax().text_range();
-    acc.add(
-        AssistId("extract_variable", AssistKind::RefactorExtract),
-        "Extract into variable",
-        target,
-        move |edit| {
-            let field_shorthand = to_extract
-                .syntax()
-                .parent()
-                .and_then(ast::RecordExprField::cast)
-                .filter(|field| field.name_ref().is_some());
-
-            let (var_name, expr_replace) = match field_shorthand {
-                Some(field) => (field.to_string(), field.syntax().clone()),
-                None => (
-                    suggest_name::for_variable(&to_extract, &ctx.sema),
-                    to_extract.syntax().clone(),
-                ),
-            };
-
-            let make = SyntaxFactory::new();
-            let mut editor = edit.make_editor(&expr_replace);
-
-            let pat_name = make.name(&var_name);
-            let name_expr = make.expr_path(make::ext::ident_path(&var_name));
-
-            if let Some(cap) = ctx.config.snippet_cap {
-                let tabstop = edit.make_tabstop_before(cap);
-                editor.add_annotation(pat_name.syntax().clone(), tabstop);
-            }
+    let needs_mut = match &parent {
+        Some(ast::Expr::RefExpr(expr)) => expr.mut_token().is_some(),
+        _ => needs_adjust && !needs_ref && ty.as_ref().is_some_and(|ty| ty.is_mutable_reference()),
+    };
+    for kind in ExtractionKind::ALL {
+        let Some(anchor) = Anchor::from(&to_extract, kind) else {
+            continue;
+        };
 
-            let ident_pat = match parent {
-                Some(ast::Expr::RefExpr(expr)) if expr.mut_token().is_some() => {
-                    make.ident_pat(false, true, pat_name)
-                }
-                _ if needs_adjust
-                    && !needs_ref
-                    && ty.as_ref().is_some_and(|ty| ty.is_mutable_reference()) =>
+        let ty_string = match kind {
+            ExtractionKind::Constant | ExtractionKind::Static => {
+                let Some(ty) = ty.clone() else {
+                    continue;
+                };
+
+                // We can't mutably reference a const, nor can we define
+                // one using a non-const expression or one of unknown type
+                if needs_mut
+                    || !is_body_const(&ctx.sema, &to_extract_no_ref)
+                    || ty.is_unknown()
+                    || ty.is_mutable_reference()
                 {
-                    make.ident_pat(false, true, pat_name)
+                    continue;
                 }
-                _ => make.ident_pat(false, false, pat_name),
-            };
 
-            let to_extract_no_ref = match ty.as_ref().filter(|_| needs_ref) {
-                Some(receiver_type) if receiver_type.is_mutable_reference() => {
-                    make.expr_ref(to_extract_no_ref, true)
-                }
-                Some(receiver_type) if receiver_type.is_reference() => {
-                    make.expr_ref(to_extract_no_ref, false)
-                }
-                _ => to_extract_no_ref,
-            };
-
-            let let_stmt = make.let_stmt(ident_pat.into(), None, Some(to_extract_no_ref));
-
-            match anchor {
-                Anchor::Before(place) => {
-                    let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token());
-                    let indent_to = IndentLevel::from_node(&place);
-
-                    // Adjust ws to insert depending on if this is all inline or on separate lines
-                    let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) {
-                        format!("\n{indent_to}")
-                    } else {
-                        " ".to_owned()
-                    };
-
-                    editor.insert_all(
-                        Position::before(place),
-                        vec![
-                            let_stmt.syntax().clone().into(),
-                            make::tokens::whitespace(&trailing_ws).into(),
-                        ],
-                    );
-
-                    editor.replace(expr_replace, name_expr.syntax());
-                }
-                Anchor::Replace(stmt) => {
-                    cov_mark::hit!(test_extract_var_expr_stmt);
+                let Ok(type_string) = ty.display_source_code(ctx.db(), module.into(), false) else {
+                    continue;
+                };
+
+                type_string
+            }
+            _ => "".to_owned(),
+        };
+
+        acc.add_group(
+            &GroupLabel("Extract into...".to_owned()),
+            kind.assist_id(),
+            kind.label(),
+            target,
+            |edit| {
+                let (var_name, expr_replace) = kind.get_name_and_expr(ctx, &to_extract);
+
+                let make = SyntaxFactory::new();
+                let mut editor = edit.make_editor(&expr_replace);
 
-                    editor.replace(stmt.syntax(), let_stmt.syntax());
+                let pat_name = make.name(&var_name);
+                let name_expr = make.expr_path(make::ext::ident_path(&var_name));
+
+                if let Some(cap) = ctx.config.snippet_cap {
+                    let tabstop = edit.make_tabstop_before(cap);
+                    editor.add_annotation(pat_name.syntax().clone(), tabstop);
                 }
-                Anchor::WrapInBlock(to_wrap) => {
-                    let indent_to = to_wrap.indent_level();
-
-                    let block = if to_wrap.syntax() == &expr_replace {
-                        // Since `expr_replace` is the same that needs to be wrapped in a block,
-                        // we can just directly replace it with a block
-                        make.block_expr([let_stmt.into()], Some(name_expr))
-                    } else {
-                        // `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`.
+
+                let initializer = match ty.as_ref().filter(|_| needs_ref) {
+                    Some(receiver_type) if receiver_type.is_mutable_reference() => {
+                        make.expr_ref(to_extract_no_ref.clone(), true)
+                    }
+                    Some(receiver_type) if receiver_type.is_reference() => {
+                        make.expr_ref(to_extract_no_ref.clone(), false)
+                    }
+                    _ => to_extract_no_ref.clone(),
+                };
+
+                let new_stmt: ast::Stmt = match kind {
+                    ExtractionKind::Variable => {
+                        let ident_pat = make.ident_pat(false, needs_mut, pat_name);
+                        make.let_stmt(ident_pat.into(), None, Some(initializer)).into()
+                    }
+                    ExtractionKind::Constant => {
+                        let ast_ty = make.ty(&ty_string);
+                        ast::Item::Const(make.item_const(None, pat_name, ast_ty, initializer))
+                            .into()
+                    }
+                    ExtractionKind::Static => {
+                        let ast_ty = make.ty(&ty_string);
+                        ast::Item::Static(make.item_static(
+                            None,
+                            false,
+                            false,
+                            pat_name,
+                            ast_ty,
+                            Some(initializer),
+                        ))
+                        .into()
+                    }
+                };
+
+                match &anchor {
+                    Anchor::Before(place) => {
+                        let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token());
+                        let indent_to = IndentLevel::from_node(place);
+
+                        // Adjust ws to insert depending on if this is all inline or on separate lines
+                        let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) {
+                            format!("\n{indent_to}")
+                        } else {
+                            " ".to_owned()
+                        };
+
+                        editor.insert_all(
+                            Position::before(place),
+                            vec![
+                                new_stmt.syntax().clone().into(),
+                                make::tokens::whitespace(&trailing_ws).into(),
+                            ],
+                        );
+
                         editor.replace(expr_replace, name_expr.syntax());
-                        make.block_expr([let_stmt.into()], Some(to_wrap.clone()))
-                    };
+                    }
+                    Anchor::Replace(stmt) => {
+                        cov_mark::hit!(test_extract_var_expr_stmt);
+
+                        editor.replace(stmt.syntax(), new_stmt.syntax());
+                    }
+                    Anchor::WrapInBlock(to_wrap) => {
+                        let indent_to = to_wrap.indent_level();
+
+                        let block = if to_wrap.syntax() == &expr_replace {
+                            // Since `expr_replace` is the same that needs to be wrapped in a block,
+                            // we can just directly replace it with a block
+                            make.block_expr([new_stmt], Some(name_expr))
+                        } else {
+                            // `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`.
+                            editor.replace(expr_replace, name_expr.syntax());
+                            make.block_expr([new_stmt], Some(to_wrap.clone()))
+                        };
 
-                    editor.replace(to_wrap.syntax(), block.syntax());
+                        editor.replace(to_wrap.syntax(), block.syntax());
 
-                    // fixup indentation of block
-                    block.indent(indent_to);
+                        // fixup indentation of block
+                        block.indent(indent_to);
+                    }
                 }
-            }
 
-            editor.add_mappings(make.finish_with_mappings());
-            edit.add_file_edits(ctx.file_id(), editor);
-            edit.rename();
-        },
-    )
+                editor.add_mappings(make.finish_with_mappings());
+                edit.add_file_edits(ctx.file_id(), editor);
+                edit.rename();
+            },
+        );
+    }
+
+    Some(())
 }
 
 fn peel_parens(mut expr: ast::Expr) -> ast::Expr {
@@ -211,17 +277,71 @@ fn peel_parens(mut expr: ast::Expr) -> ast::Expr {
 /// In general that's true for any expression, but in some cases that would produce invalid code.
 fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> {
     match node.kind() {
-        PATH_EXPR | LOOP_EXPR => None,
-        BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()),
-        RETURN_EXPR => ast::ReturnExpr::cast(node).and_then(|e| e.expr()),
-        BLOCK_EXPR => {
+        SyntaxKind::PATH_EXPR | SyntaxKind::LOOP_EXPR => None,
+        SyntaxKind::BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()),
+        SyntaxKind::RETURN_EXPR => ast::ReturnExpr::cast(node).and_then(|e| e.expr()),
+        SyntaxKind::BLOCK_EXPR => {
             ast::BlockExpr::cast(node).filter(|it| it.is_standalone()).map(ast::Expr::from)
         }
         _ => ast::Expr::cast(node),
     }
 }
 
-#[derive(Debug)]
+enum ExtractionKind {
+    Variable,
+    Constant,
+    Static,
+}
+
+impl ExtractionKind {
+    const ALL: &'static [ExtractionKind] =
+        &[ExtractionKind::Variable, ExtractionKind::Constant, ExtractionKind::Static];
+
+    fn assist_id(&self) -> AssistId {
+        let s = match self {
+            ExtractionKind::Variable => "extract_variable",
+            ExtractionKind::Constant => "extract_constant",
+            ExtractionKind::Static => "extract_static",
+        };
+
+        AssistId(s, AssistKind::RefactorExtract)
+    }
+
+    fn label(&self) -> &'static str {
+        match self {
+            ExtractionKind::Variable => "Extract into variable",
+            ExtractionKind::Constant => "Extract into constant",
+            ExtractionKind::Static => "Extract into static",
+        }
+    }
+
+    fn get_name_and_expr(
+        &self,
+        ctx: &AssistContext<'_>,
+        to_extract: &ast::Expr,
+    ) -> (String, SyntaxNode) {
+        let field_shorthand = to_extract
+            .syntax()
+            .parent()
+            .and_then(ast::RecordExprField::cast)
+            .filter(|field| field.name_ref().is_some());
+        let (var_name, expr_replace) = match field_shorthand {
+            Some(field) => (field.to_string(), field.syntax().clone()),
+            None => {
+                (suggest_name::for_variable(to_extract, &ctx.sema), to_extract.syntax().clone())
+            }
+        };
+
+        let var_name = match self {
+            ExtractionKind::Variable => var_name,
+            ExtractionKind::Constant | ExtractionKind::Static => var_name.to_uppercase(),
+        };
+
+        (var_name, expr_replace)
+    }
+}
+
+#[derive(Debug, Clone)]
 enum Anchor {
     Before(SyntaxNode),
     Replace(ast::ExprStmt),
@@ -229,8 +349,8 @@ enum Anchor {
 }
 
 impl Anchor {
-    fn from(to_extract: &ast::Expr) -> Option<Anchor> {
-        to_extract
+    fn from(to_extract: &ast::Expr, kind: &ExtractionKind) -> Option<Anchor> {
+        let result = to_extract
             .syntax()
             .ancestors()
             .take_while(|it| !ast::Item::can_cast(it.kind()) || ast::MacroCall::can_cast(it.kind()))
@@ -253,7 +373,7 @@ impl Anchor {
                         return parent.body().map(Anchor::WrapInBlock);
                     }
                     if let Some(parent) = ast::MatchArm::cast(parent) {
-                        if node.kind() == MATCH_GUARD {
+                        if node.kind() == SyntaxKind::MATCH_GUARD {
                             cov_mark::hit!(test_extract_var_in_match_guard);
                         } else {
                             cov_mark::hit!(test_extract_var_in_match_arm_no_block);
@@ -271,19 +391,42 @@ impl Anchor {
                     return Some(Anchor::Before(node));
                 }
                 None
-            })
+            });
+
+        match kind {
+            ExtractionKind::Constant | ExtractionKind::Static if result.is_none() => {
+                to_extract.syntax().ancestors().find_map(|node| {
+                    let item = ast::Item::cast(node.clone())?;
+                    let parent = item.syntax().parent()?;
+                    match parent.kind() {
+                        SyntaxKind::ITEM_LIST
+                        | SyntaxKind::SOURCE_FILE
+                        | SyntaxKind::ASSOC_ITEM_LIST
+                        | SyntaxKind::STMT_LIST => Some(Anchor::Before(node)),
+                        _ => None,
+                    }
+                })
+            }
+            _ => result,
+        }
     }
 }
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
+    // NOTE: We use check_assist_by_label, but not check_assist_not_applicable_by_label
+    // because all of our not-applicable tests should behave that way for both assists
+    // extract_variable offers, and check_assist_not_applicable ensures neither is offered
+    use crate::tests::{
+        check_assist_by_label, check_assist_not_applicable, check_assist_not_applicable_by_label,
+        check_assist_target,
+    };
 
     use super::*;
 
     #[test]
-    fn test_extract_var_simple_without_select() {
-        check_assist(
+    fn extract_var_simple_without_select() {
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() -> i32 {
@@ -304,9 +447,10 @@ fn main() -> i32 {
     var_name
 }
 "#,
+            "Extract into variable",
         );
 
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn foo() -> i32 { 1 }
@@ -320,9 +464,10 @@ fn main() {
     let $0foo = foo();
 }
 "#,
+            "Extract into variable",
         );
 
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -336,9 +481,10 @@ fn main() {
     let $0is_some = a.is_some();
 }
 "#,
+            "Extract into variable",
         );
 
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -350,9 +496,10 @@ fn main() {
     let $0var_name = "hello";
 }
 "#,
+            "Extract into variable",
         );
 
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -364,9 +511,10 @@ fn main() {
     let $0var_name = 1  + 2;
 }
 "#,
+            "Extract into variable",
         );
 
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -384,11 +532,202 @@ fn main() {
     };
 }
 "#,
+            "Extract into variable",
+        );
+    }
+
+    #[test]
+    fn extract_const_simple_without_select() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() -> i32 {
+    if true {
+        1
+    } else {
+        2
+    }$0
+}
+"#,
+            r#"
+fn main() -> i32 {
+    const $0VAR_NAME: i32 = if true {
+        1
+    } else {
+        2
+    };
+    VAR_NAME
+}
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo() -> i32 { 1 }
+fn main() {
+    foo();$0
+}
+"#,
+            r#"
+const fn foo() -> i32 { 1 }
+fn main() {
+    const $0FOO: i32 = foo();
+}
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() {
+    "hello"$0;
+}
+"#,
+            r#"
+fn main() {
+    const $0VAR_NAME: &str = "hello";
+}
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() {
+    1  + 2$0;
+}
+"#,
+            r#"
+fn main() {
+    const $0VAR_NAME: i32 = 1  + 2;
+}
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() {
+    match () {
+        () if true => 1,
+        _ => 2,
+    };$0
+}
+"#,
+            r#"
+fn main() {
+    const $0VAR_NAME: i32 = match () {
+        () if true => 1,
+        _ => 2,
+    };
+}
+"#,
+            "Extract into constant",
+        );
+    }
+
+    #[test]
+    fn extract_static_simple_without_select() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() -> i32 {
+    if true {
+        1
+    } else {
+        2
+    }$0
+}
+"#,
+            r#"
+fn main() -> i32 {
+    static $0VAR_NAME: i32 = if true {
+        1
+    } else {
+        2
+    };
+    VAR_NAME
+}
+"#,
+            "Extract into static",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo() -> i32 { 1 }
+fn main() {
+    foo();$0
+}
+"#,
+            r#"
+const fn foo() -> i32 { 1 }
+fn main() {
+    static $0FOO: i32 = foo();
+}
+"#,
+            "Extract into static",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() {
+    "hello"$0;
+}
+"#,
+            r#"
+fn main() {
+    static $0VAR_NAME: &str = "hello";
+}
+"#,
+            "Extract into static",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() {
+    1  + 2$0;
+}
+"#,
+            r#"
+fn main() {
+    static $0VAR_NAME: i32 = 1  + 2;
+}
+"#,
+            "Extract into static",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn main() {
+    match () {
+        () if true => 1,
+        _ => 2,
+    };$0
+}
+"#,
+            r#"
+fn main() {
+    static $0VAR_NAME: i32 = match () {
+        () if true => 1,
+        _ => 2,
+    };
+}
+"#,
+            "Extract into static",
         );
     }
 
     #[test]
-    fn test_extract_var_unit_expr_without_select_not_applicable() {
+    fn dont_extract_unit_expr_without_select() {
         check_assist_not_applicable(
             extract_variable,
             r#"
@@ -414,8 +753,8 @@ fn foo() {
     }
 
     #[test]
-    fn test_extract_var_simple() {
-        check_assist(
+    fn extract_var_simple() {
+        check_assist_by_label(
             extract_variable,
             r#"
 fn foo() {
@@ -426,19 +765,54 @@ fn foo() {
     let $0var_name = 1 + 1;
     foo(var_name);
 }"#,
+            "Extract into variable",
+        );
+    }
+
+    #[test]
+    fn extract_const_simple() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    foo($01 + 1$0);
+}"#,
+            r#"
+fn foo() {
+    const $0VAR_NAME: i32 = 1 + 1;
+    foo(VAR_NAME);
+}"#,
+            "Extract into constant",
         );
     }
 
     #[test]
-    fn extract_var_in_comment_is_not_applicable() {
+    fn extract_static_simple() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    foo($01 + 1$0);
+}"#,
+            r#"
+fn foo() {
+    static $0VAR_NAME: i32 = 1 + 1;
+    foo(VAR_NAME);
+}"#,
+            "Extract into static",
+        );
+    }
+
+    #[test]
+    fn dont_extract_in_comment() {
         cov_mark::check!(extract_var_in_comment_is_not_applicable);
-        check_assist_not_applicable(extract_variable, "fn main() { 1 + /* $0comment$0 */ 1; }");
+        check_assist_not_applicable(extract_variable, r#"fn main() { 1 + /* $0comment$0 */ 1; }"#);
     }
 
     #[test]
-    fn test_extract_var_expr_stmt() {
+    fn extract_var_expr_stmt() {
         cov_mark::check!(test_extract_var_expr_stmt);
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn foo() {
@@ -448,42 +822,143 @@ fn foo() {
 fn foo() {
     let $0var_name = 1 + 1;
 }"#,
+            "Extract into variable",
         );
-        check_assist(
+        check_assist_by_label(
             extract_variable,
-            r"
+            r#"
 fn foo() {
     $0{ let x = 0; x }$0;
     something_else();
-}",
-            r"
+}"#,
+            r#"
 fn foo() {
     let $0var_name = { let x = 0; x };
     something_else();
-}",
+}"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_part_of_expr_stmt() {
-        check_assist(
+    fn extract_const_expr_stmt() {
+        cov_mark::check!(test_extract_var_expr_stmt);
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+  $0  1 + 1$0;
+}"#,
+            r#"
+fn foo() {
+    const $0VAR_NAME: i32 = 1 + 1;
+}"#,
+            "Extract into constant",
+        );
+        // This is hilarious but as far as I know, it's valid
+        check_assist_by_label(
             extract_variable,
-            r"
+            r#"
+fn foo() {
+    $0{ let x = 0; x }$0;
+    something_else();
+}"#,
+            r#"
+fn foo() {
+    const $0VAR_NAME: i32 = { let x = 0; x };
+    something_else();
+}"#,
+            "Extract into constant",
+        );
+    }
+
+    #[test]
+    fn extract_static_expr_stmt() {
+        cov_mark::check!(test_extract_var_expr_stmt);
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+  $0  1 + 1$0;
+}"#,
+            r#"
+fn foo() {
+    static $0VAR_NAME: i32 = 1 + 1;
+}"#,
+            "Extract into static",
+        );
+        // This is hilarious but as far as I know, it's valid
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    $0{ let x = 0; x }$0;
+    something_else();
+}"#,
+            r#"
+fn foo() {
+    static $0VAR_NAME: i32 = { let x = 0; x };
+    something_else();
+}"#,
+            "Extract into static",
+        );
+    }
+
+    #[test]
+    fn extract_var_part_of_expr_stmt() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
 fn foo() {
     $01$0 + 1;
-}",
-            r"
+}"#,
+            r#"
 fn foo() {
     let $0var_name = 1;
     var_name + 1;
-}",
+}"#,
+            "Extract into variable",
+        );
+    }
+
+    #[test]
+    fn extract_const_part_of_expr_stmt() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    $01$0 + 1;
+}"#,
+            r#"
+fn foo() {
+    const $0VAR_NAME: i32 = 1;
+    VAR_NAME + 1;
+}"#,
+            "Extract into constant",
         );
     }
 
     #[test]
-    fn test_extract_var_last_expr() {
+    fn extract_static_part_of_expr_stmt() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    $01$0 + 1;
+}"#,
+            r#"
+fn foo() {
+    static $0VAR_NAME: i32 = 1;
+    VAR_NAME + 1;
+}"#,
+            "Extract into static",
+        );
+    }
+
+    #[test]
+    fn extract_var_last_expr() {
         cov_mark::check!(test_extract_var_last_expr);
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn foo() {
@@ -496,8 +971,9 @@ fn foo() {
     bar(var_name)
 }
 "#,
+            "Extract into variable",
         );
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn foo() -> i32 {
@@ -518,13 +994,100 @@ fn bar(i: i32) -> i32 {
     i
 }
 "#,
+            "Extract into variable",
+        )
+    }
+
+    #[test]
+    fn extract_const_last_expr() {
+        cov_mark::check!(test_extract_var_last_expr);
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    bar($01 + 1$0)
+}
+"#,
+            r#"
+fn foo() {
+    const $0VAR_NAME: i32 = 1 + 1;
+    bar(VAR_NAME)
+}
+"#,
+            "Extract into constant",
+        );
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() -> i32 {
+    $0bar(1 + 1)$0
+}
+
+const fn bar(i: i32) -> i32 {
+    i
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    const $0BAR: i32 = bar(1 + 1);
+    BAR
+}
+
+const fn bar(i: i32) -> i32 {
+    i
+}
+"#,
+            "Extract into constant",
+        )
+    }
+
+    #[test]
+    fn extract_static_last_expr() {
+        cov_mark::check!(test_extract_var_last_expr);
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    bar($01 + 1$0)
+}
+"#,
+            r#"
+fn foo() {
+    static $0VAR_NAME: i32 = 1 + 1;
+    bar(VAR_NAME)
+}
+"#,
+            "Extract into static",
+        );
+        check_assist_by_label(
+            extract_variable,
+            r#"
+fn foo() -> i32 {
+    $0bar(1 + 1)$0
+}
+
+const fn bar(i: i32) -> i32 {
+    i
+}
+"#,
+            r#"
+fn foo() -> i32 {
+    static $0BAR: i32 = bar(1 + 1);
+    BAR
+}
+
+const fn bar(i: i32) -> i32 {
+    i
+}
+"#,
+            "Extract into static",
         )
     }
 
     #[test]
-    fn test_extract_var_in_match_arm_no_block() {
+    fn extract_var_in_match_arm_no_block() {
         cov_mark::check!(test_extract_var_in_match_arm_no_block);
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -547,12 +1110,13 @@ fn main() {
     };
 }
 "#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_in_match_arm_with_block() {
-        check_assist(
+    fn extract_var_in_match_arm_with_block() {
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -579,13 +1143,14 @@ fn main() {
     };
 }
 "#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_in_match_guard() {
+    fn extract_var_in_match_guard() {
         cov_mark::check!(test_extract_var_in_match_guard);
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -604,13 +1169,14 @@ fn main() {
     };
 }
 "#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_in_closure_no_block() {
+    fn extract_var_in_closure_no_block() {
         cov_mark::check!(test_extract_var_in_closure_no_block);
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -625,12 +1191,13 @@ fn main() {
     };
 }
 "#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_in_closure_with_block() {
-        check_assist(
+    fn extract_var_in_closure_with_block() {
+        check_assist_by_label(
             extract_variable,
             r#"
 fn main() {
@@ -642,104 +1209,110 @@ fn main() {
     let lambda = |x: u32| { let $0var_name = x * 2; var_name };
 }
 "#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_path_simple() {
-        check_assist(
+    fn extract_var_path_simple() {
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn main() {
     let o = $0Some(true)$0;
 }
-",
-            "
+"#,
+            r#"
 fn main() {
     let $0var_name = Some(true);
     let o = var_name;
 }
-",
+"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_path_method() {
-        check_assist(
+    fn extract_var_path_method() {
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn main() {
     let v = $0bar.foo()$0;
 }
-",
-            "
+"#,
+            r#"
 fn main() {
     let $0foo = bar.foo();
     let v = foo;
 }
-",
+"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_return() {
-        check_assist(
+    fn extract_var_return() {
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn foo() -> u32 {
     $0return 2 + 2$0;
 }
-",
-            "
+"#,
+            r#"
 fn foo() -> u32 {
     let $0var_name = 2 + 2;
     return var_name;
 }
-",
+"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_does_not_add_extra_whitespace() {
-        check_assist(
+    fn extract_var_does_not_add_extra_whitespace() {
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn foo() -> u32 {
 
 
     $0return 2 + 2$0;
 }
-",
-            "
+"#,
+            r#"
 fn foo() -> u32 {
 
 
     let $0var_name = 2 + 2;
     return var_name;
 }
-",
+"#,
+            "Extract into variable",
         );
 
-        check_assist(
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn foo() -> u32 {
 
         $0return 2 + 2$0;
 }
-",
-            "
+"#,
+            r#"
 fn foo() -> u32 {
 
         let $0var_name = 2 + 2;
         return var_name;
 }
-",
+"#,
+            "Extract into variable",
         );
 
-        check_assist(
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn foo() -> u32 {
     let foo = 1;
 
@@ -748,8 +1321,8 @@ fn foo() -> u32 {
 
     $0return 2 + 2$0;
 }
-",
-            "
+"#,
+            r#"
 fn foo() -> u32 {
     let foo = 1;
 
@@ -759,53 +1332,56 @@ fn foo() -> u32 {
     let $0var_name = 2 + 2;
     return var_name;
 }
-",
+"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_break() {
-        check_assist(
+    fn extract_var_break() {
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn main() {
     let result = loop {
         $0break 2 + 2$0;
     };
 }
-",
-            "
+"#,
+            r#"
 fn main() {
     let result = loop {
         let $0var_name = 2 + 2;
         break var_name;
     };
 }
-",
+"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_for_cast() {
-        check_assist(
+    fn extract_var_for_cast() {
+        check_assist_by_label(
             extract_variable,
-            "
+            r#"
 fn main() {
     let v = $00f32 as u32$0;
 }
-",
-            "
+"#,
+            r#"
 fn main() {
     let $0var_name = 0f32 as u32;
     let v = var_name;
 }
-",
+"#,
+            "Extract into variable",
         );
     }
 
     #[test]
     fn extract_var_field_shorthand() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct S {
@@ -826,12 +1402,13 @@ fn main() {
     S { foo }
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_name_from_type() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct Test(i32);
@@ -848,12 +1425,13 @@ fn foo() -> Test {
     test
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_name_from_parameter() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn bar(test: u32, size: u32)
@@ -870,12 +1448,13 @@ fn foo() {
     bar(1, size);
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_parameter_name_has_precedence_over_type() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct TextSize(u32);
@@ -894,12 +1473,13 @@ fn foo() {
     bar(1, size);
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_name_from_function() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn is_required(test: u32, size: u32) -> bool
@@ -916,12 +1496,13 @@ fn foo() -> bool {
     is_required
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_name_from_method() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct S;
@@ -944,12 +1525,13 @@ fn foo() -> u32 {
     bar
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_name_from_method_param() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct S;
@@ -972,12 +1554,13 @@ fn foo() {
     S.bar(n, 2)
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_name_from_ufcs_method_param() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct S;
@@ -1000,12 +1583,13 @@ fn foo() {
     S::bar(&S, n, 2)
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_var_parameter_name_has_precedence_over_function() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 fn bar(test: u32, size: u32)
@@ -1022,14 +1606,15 @@ fn foo() {
     bar(1, size);
 }
 "#,
+            "Extract into variable",
         )
     }
 
     #[test]
     fn extract_macro_call() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
-            r"
+            r#"
 struct Vec;
 macro_rules! vec {
     () => {Vec}
@@ -1037,8 +1622,8 @@ macro_rules! vec {
 fn main() {
     let _ = $0vec![]$0;
 }
-",
-            r"
+"#,
+            r#"
 struct Vec;
 macro_rules! vec {
     () => {Vec}
@@ -1047,22 +1632,71 @@ fn main() {
     let $0vec = vec![];
     let _ = vec;
 }
-",
+"#,
+            "Extract into variable",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+struct Vec;
+macro_rules! vec {
+    () => {Vec}
+}
+fn main() {
+    let _ = $0vec![]$0;
+}
+"#,
+            r#"
+struct Vec;
+macro_rules! vec {
+    () => {Vec}
+}
+fn main() {
+    const $0VEC: Vec = vec![];
+    let _ = VEC;
+}
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+struct Vec;
+macro_rules! vec {
+    () => {Vec}
+}
+fn main() {
+    let _ = $0vec![]$0;
+}
+"#,
+            r#"
+struct Vec;
+macro_rules! vec {
+    () => {Vec}
+}
+fn main() {
+    static $0VEC: Vec = vec![];
+    let _ = VEC;
+}
+"#,
+            "Extract into static",
         );
     }
 
     #[test]
-    fn test_extract_var_for_return_not_applicable() {
+    fn extract_var_for_return_not_applicable() {
         check_assist_not_applicable(extract_variable, "fn foo() { $0return$0; } ");
     }
 
     #[test]
-    fn test_extract_var_for_break_not_applicable() {
+    fn extract_var_for_break_not_applicable() {
         check_assist_not_applicable(extract_variable, "fn main() { loop { $0break$0; }; }");
     }
 
     #[test]
-    fn test_extract_var_unit_expr_not_applicable() {
+    fn extract_var_unit_expr_not_applicable() {
         check_assist_not_applicable(
             extract_variable,
             r#"
@@ -1080,11 +1714,11 @@ fn foo() {
     // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic
     #[test]
     fn extract_var_target() {
-        check_assist_target(extract_variable, "fn foo() -> u32 { $0return 2 + 2$0; }", "2 + 2");
+        check_assist_target(extract_variable, r#"fn foo() -> u32 { $0return 2 + 2$0; }"#, "2 + 2");
 
         check_assist_target(
             extract_variable,
-            "
+            r#"
 fn main() {
     let x = true;
     let tuple = match x {
@@ -1092,24 +1726,231 @@ fn main() {
         _ => (0, false)
     };
 }
-",
+"#,
             "2 + 2",
         );
     }
 
     #[test]
     fn extract_var_no_block_body() {
-        check_assist_not_applicable(
+        check_assist_not_applicable_by_label(
             extract_variable,
-            r"
+            r#"
 const X: usize = $0100$0;
-",
+"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_mutable_reference_parameter() {
-        check_assist(
+    fn extract_const_no_block_body() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+const FOO: i32 = foo($0100$0);
+"#,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+const $0X: i32 = 100;
+const FOO: i32 = foo(X);
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+mod foo {
+    enum Foo {
+        Bar,
+        Baz = $042$0,
+    }
+}
+"#,
+            r#"
+mod foo {
+    const $0VAR_NAME: isize = 42;
+    enum Foo {
+        Bar,
+        Baz = VAR_NAME,
+    }
+}
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+trait Hello {
+    const World: i32;
+}
+
+struct Bar;
+impl Hello for Bar {
+    const World = foo($042$0);
+}
+"#,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+trait Hello {
+    const World: i32;
+}
+
+struct Bar;
+impl Hello for Bar {
+    const $0X: i32 = 42;
+    const World = foo(X);
+}
+"#,
+            "Extract into constant",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+fn bar() {
+    const BAZ: i32 = foo($042$0);
+}
+"#,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+fn bar() {
+    const $0X: i32 = 42;
+    const BAZ: i32 = foo(X);
+}
+"#,
+            "Extract into constant",
+        );
+    }
+
+    #[test]
+    fn extract_static_no_block_body() {
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+const FOO: i32 = foo($0100$0);
+"#,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+static $0X: i32 = 100;
+const FOO: i32 = foo(X);
+"#,
+            "Extract into static",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+mod foo {
+    enum Foo {
+        Bar,
+        Baz = $042$0,
+    }
+}
+"#,
+            r#"
+mod foo {
+    static $0VAR_NAME: isize = 42;
+    enum Foo {
+        Bar,
+        Baz = VAR_NAME,
+    }
+}
+"#,
+            "Extract into static",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+trait Hello {
+    const World: i32;
+}
+
+struct Bar;
+impl Hello for Bar {
+    const World = foo($042$0);
+}
+"#,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+trait Hello {
+    const World: i32;
+}
+
+struct Bar;
+impl Hello for Bar {
+    static $0X: i32 = 42;
+    const World = foo(X);
+}
+"#,
+            "Extract into static",
+        );
+
+        check_assist_by_label(
+            extract_variable,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+fn bar() {
+    const BAZ: i32 = foo($042$0);
+}
+"#,
+            r#"
+const fn foo(x: i32) -> i32 {
+    x
+}
+
+fn bar() {
+    static $0X: i32 = 42;
+    const BAZ: i32 = foo(X);
+}
+"#,
+            "Extract into static",
+        );
+    }
+
+    #[test]
+    fn extract_var_mutable_reference_parameter() {
+        check_assist_by_label(
             extract_variable,
             r#"
 struct S {
@@ -1138,12 +1979,55 @@ fn foo(s: &mut S) {
     let $0vec = &mut s.vec;
     vec.push(0);
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_mutable_reference_parameter_deep_nesting() {
-        check_assist(
+    fn dont_extract_const_mutable_reference_parameter() {
+        check_assist_not_applicable_by_label(
+            extract_variable,
+            r#"
+struct S {
+    vec: Vec<u8>
+}
+
+struct Vec<T>;
+impl<T> Vec<T> {
+    fn push(&mut self, _:usize) {}
+}
+
+fn foo(s: &mut S) {
+    $0s.vec$0.push(0);
+}"#,
+            "Extract into constant",
+        );
+    }
+
+    #[test]
+    fn dont_extract_static_mutable_reference_parameter() {
+        check_assist_not_applicable_by_label(
+            extract_variable,
+            r#"
+struct S {
+    vec: Vec<u8>
+}
+
+struct Vec<T>;
+impl<T> Vec<T> {
+    fn push(&mut self, _:usize) {}
+}
+
+fn foo(s: &mut S) {
+    $0s.vec$0.push(0);
+}"#,
+            "Extract into static",
+        );
+    }
+
+    #[test]
+    fn extract_var_mutable_reference_parameter_deep_nesting() {
+        check_assist_by_label(
             extract_variable,
             r#"
 struct Y {
@@ -1182,12 +2066,13 @@ fn foo(f: &mut Y) {
     let $0vec = &mut f.field.field.vec;
     vec.push(0);
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_reference_parameter() {
-        check_assist(
+    fn extract_var_reference_parameter() {
+        check_assist_by_label(
             extract_variable,
             r#"
 struct X;
@@ -1222,12 +2107,13 @@ fn foo(s: &S) {
     let $0x = &s.sub;
     x.do_thing();
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_index_deref() {
-        check_assist(
+    fn extract_var_index_deref() {
+        check_assist_by_label(
             extract_variable,
             r#"
 //- minicore: index
@@ -1261,12 +2147,13 @@ fn foo(s: &S) {
     let $0sub = &s.sub;
     sub[0];
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_reference_parameter_deep_nesting() {
-        check_assist(
+    fn extract_var_reference_parameter_deep_nesting() {
+        check_assist_by_label(
             extract_variable,
             r#"
 struct Z;
@@ -1315,12 +2202,13 @@ fn foo(s: &S) {
     let $0z = &s.sub.field.field;
     z.do_thing();
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_regular_parameter() {
-        check_assist(
+    fn extract_var_regular_parameter() {
+        check_assist_by_label(
             extract_variable,
             r#"
 struct X;
@@ -1355,12 +2243,13 @@ fn foo(s: S) {
     let $0x = &s.sub;
     x.do_thing();
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_mutable_reference_local() {
-        check_assist(
+    fn extract_var_mutable_reference_local() {
+        check_assist_by_label(
             extract_variable,
             r#"
 struct X;
@@ -1421,12 +2310,13 @@ fn foo() {
     let $0x = &local.sub;
     x.do_thing();
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_reference_local() {
-        check_assist(
+    fn extract_var_reference_local() {
+        check_assist_by_label(
             extract_variable,
             r#"
 struct X;
@@ -1487,12 +2377,13 @@ fn foo() {
     let $0x = &local.sub;
     x.do_thing();
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
-    fn test_extract_var_for_mutable_borrow() {
-        check_assist(
+    fn extract_var_for_mutable_borrow() {
+        check_assist_by_label(
             extract_variable,
             r#"
 fn foo() {
@@ -1503,12 +2394,37 @@ fn foo() {
     let mut $0var_name = 0;
     let v = &mut var_name;
 }"#,
+            "Extract into variable",
+        );
+    }
+
+    #[test]
+    fn dont_extract_const_for_mutable_borrow() {
+        check_assist_not_applicable_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    let v = &mut $00$0;
+}"#,
+            "Extract into constant",
+        );
+    }
+
+    #[test]
+    fn dont_extract_static_for_mutable_borrow() {
+        check_assist_not_applicable_by_label(
+            extract_variable,
+            r#"
+fn foo() {
+    let v = &mut $00$0;
+}"#,
+            "Extract into static",
         );
     }
 
     #[test]
     fn generates_no_ref_on_calls() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct S;
@@ -1529,12 +2445,13 @@ fn foo() {
     let mut $0bar = bar();
     bar.do_work();
 }"#,
+            "Extract into variable",
         );
     }
 
     #[test]
     fn generates_no_ref_for_deref() {
-        check_assist(
+        check_assist_by_label(
             extract_variable,
             r#"
 struct S;
@@ -1559,6 +2476,7 @@ fn foo() {
     s.do_work();
 }
 "#,
+            "Extract into variable",
         );
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
index 76a647807cb..7b95c124e62 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -2055,7 +2055,7 @@ fn bar(closure: impl Fn(i64) -> i64) {
     }
 
     #[test]
-    fn unresolveable_types_default_to_placeholder() {
+    fn unresolvable_types_default_to_placeholder() {
         check_assist(
             generate_function,
             r"
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs
index 2bd4c4da1e2..c92c22378f8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs
@@ -1,3 +1,4 @@
+use hir::HasCrate;
 use syntax::{ast, AstNode};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -51,7 +52,10 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_>
             | ast::Expr::MatchExpr(_)
             | ast::Expr::MacroExpr(_)
             | ast::Expr::BinExpr(_)
-            | ast::Expr::CallExpr(_) => konst.eval(ctx.sema.db).ok()?,
+            | ast::Expr::CallExpr(_) => konst
+                .eval(ctx.sema.db)
+                .ok()?
+                .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)),
             _ => return None,
         };
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
index ec3281619cc..f0c96fe3cb8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
@@ -36,7 +36,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_>)
     let match_arm = ctx.find_node_at_offset::<MatchArm>()?;
     let guard = match_arm.guard()?;
     if ctx.offset() > guard.syntax().text_range().end() {
-        cov_mark::hit!(move_guard_unapplicable_in_arm_body);
+        cov_mark::hit!(move_guard_inapplicable_in_arm_body);
         return None;
     }
     let space_before_guard = guard.syntax().prev_sibling_or_token();
@@ -219,7 +219,7 @@ mod tests {
 
     #[test]
     fn move_guard_to_arm_body_range() {
-        cov_mark::check!(move_guard_unapplicable_in_arm_body);
+        cov_mark::check!(move_guard_inapplicable_in_arm_body);
         check_assist_not_applicable(
             move_guard_to_arm_body,
             r#"
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs
index 7c2dc0e0c10..0cc771ff397 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs
@@ -1,19 +1,17 @@
-use hir::{HirDisplay, ModuleDef, PathResolution, Semantics};
+use hir::HirDisplay;
 use ide_db::{
     assists::{AssistId, AssistKind},
     defs::Definition,
-    syntax_helpers::node_ext::preorder_expr,
-    RootDatabase,
 };
 use stdx::to_upper_snake_case;
 use syntax::{
     ast::{self, make, HasName},
-    ted, AstNode, WalkEvent,
+    ted, AstNode,
 };
 
 use crate::{
     assist_context::{AssistContext, Assists},
-    utils,
+    utils::{self},
 };
 
 // Assist: promote_local_to_const
@@ -63,7 +61,7 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>)
     };
 
     let initializer = let_stmt.initializer()?;
-    if !is_body_const(&ctx.sema, &initializer) {
+    if !utils::is_body_const(&ctx.sema, &initializer) {
         cov_mark::hit!(promote_local_non_const);
         return None;
     }
@@ -103,40 +101,6 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>)
     )
 }
 
-fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bool {
-    let mut is_const = true;
-    preorder_expr(expr, &mut |ev| {
-        let expr = match ev {
-            WalkEvent::Enter(_) if !is_const => return true,
-            WalkEvent::Enter(expr) => expr,
-            WalkEvent::Leave(_) => return false,
-        };
-        match expr {
-            ast::Expr::CallExpr(call) => {
-                if let Some(ast::Expr::PathExpr(path_expr)) = call.expr() {
-                    if let Some(PathResolution::Def(ModuleDef::Function(func))) =
-                        path_expr.path().and_then(|path| sema.resolve_path(&path))
-                    {
-                        is_const &= func.is_const(sema.db);
-                    }
-                }
-            }
-            ast::Expr::MethodCallExpr(call) => {
-                is_const &=
-                    sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true)
-            }
-            ast::Expr::ForExpr(_)
-            | ast::Expr::ReturnExpr(_)
-            | ast::Expr::TryExpr(_)
-            | ast::Expr::YieldExpr(_)
-            | ast::Expr::AwaitExpr(_) => is_const = false,
-            _ => (),
-        }
-        !is_const
-    });
-    is_const
-}
-
 #[cfg(test)]
 mod tests {
     use crate::tests::{check_assist, check_assist_not_applicable};
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index 248f18789ce..2dec876215c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -139,7 +139,7 @@ fn add_assist(
             let trait_path = make::ty_path(replace_trait_path.clone());
 
             match (ctx.config.snippet_cap, impl_def_with_items) {
-                (None, _) => {
+                (None, None) => {
                     let impl_def = generate_trait_impl(adt, trait_path);
 
                     ted::insert_all(
@@ -147,6 +147,12 @@ fn add_assist(
                         vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()],
                     );
                 }
+                (None, Some((impl_def, _))) => {
+                    ted::insert_all(
+                        insert_after,
+                        vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()],
+                    );
+                }
                 (Some(cap), None) => {
                     let impl_def = generate_trait_impl(adt, trait_path);
 
@@ -272,7 +278,7 @@ fn update_attribute(
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable};
+    use crate::tests::{check_assist, check_assist_no_snippet_cap, check_assist_not_applicable};
 
     use super::*;
 
@@ -301,6 +307,30 @@ impl core::fmt::Debug for Foo {
         )
     }
     #[test]
+    fn add_custom_impl_without_snippet() {
+        check_assist_no_snippet_cap(
+            replace_derive_with_manual_impl,
+            r#"
+//- minicore: fmt, derive
+#[derive(Debu$0g)]
+struct Foo {
+    bar: String,
+}
+"#,
+            r#"
+struct Foo {
+    bar: String,
+}
+
+impl core::fmt::Debug for Foo {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("Foo").field("bar", &self.bar).finish()
+    }
+}
+"#,
+        )
+    }
+    #[test]
     fn add_custom_impl_debug_tuple_struct() {
         check_assist(
             replace_derive_with_manual_impl,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
index f13b0b0713d..56dd6cf29ae 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
@@ -360,7 +360,7 @@ mod tests {
     use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
 
     #[test]
-    fn test_if_let_with_match_unapplicable_for_simple_ifs() {
+    fn test_if_let_with_match_inapplicable_for_simple_ifs() {
         check_assist_not_applicable(
             replace_if_let_with_match,
             r#"
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
index 9ab36bf7757..8f937a04122 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
@@ -127,7 +127,7 @@ pub(crate) fn desugar_async_into_impl_future(
 
     let rparen = function.param_list()?.r_paren_token()?;
     let return_type = match function.ret_type() {
-        // unable to get a `ty` makes the action unapplicable
+        // unable to get a `ty` makes the action inapplicable
         Some(ret_type) => Some(ret_type.ty()?),
         // No type means `-> ()`
         None => None,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
index 6469957fe16..0b1ff87c5c2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
@@ -362,8 +362,7 @@ pub fn test_some_range(a: int) -> bool {
 
     expect![[r#"
         Convert integer base
-        Extract into variable
-        Extract into function
+        Extract into...
         Replace if let with match
     "#]]
     .assert_eq(&expected);
@@ -391,8 +390,7 @@ pub fn test_some_range(a: int) -> bool {
 
         expect![[r#"
             Convert integer base
-            Extract into variable
-            Extract into function
+            Extract into...
             Replace if let with match
         "#]]
         .assert_eq(&expected);
@@ -405,8 +403,7 @@ pub fn test_some_range(a: int) -> bool {
         let expected = labels(&assists);
 
         expect![[r#"
-            Extract into variable
-            Extract into function
+            Extract into...
         "#]]
         .assert_eq(&expected);
     }
@@ -440,7 +437,7 @@ pub fn test_some_range(a: int) -> bool {
 
     {
         let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into());
-        assert_eq!(2, assists.len());
+        assert_eq!(4, assists.len());
         let mut assists = assists.into_iter();
 
         let extract_into_variable_assist = assists.next().unwrap();
@@ -451,7 +448,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into variable",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: None,
                 command: None,
@@ -459,6 +460,46 @@ pub fn test_some_range(a: int) -> bool {
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
 
+        let extract_into_constant_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_constant",
+                    RefactorExtract,
+                ),
+                label: "Extract into constant",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: None,
+                command: None,
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_constant_assist);
+
+        let extract_into_static_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_static",
+                    RefactorExtract,
+                ),
+                label: "Extract into static",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: None,
+                command: None,
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_static_assist);
+
         let extract_into_function_assist = assists.next().unwrap();
         expect![[r#"
             Assist {
@@ -467,7 +508,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into function",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: None,
                 command: None,
@@ -486,7 +531,7 @@ pub fn test_some_range(a: int) -> bool {
             }),
             frange.into(),
         );
-        assert_eq!(2, assists.len());
+        assert_eq!(4, assists.len());
         let mut assists = assists.into_iter();
 
         let extract_into_variable_assist = assists.next().unwrap();
@@ -497,7 +542,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into variable",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: None,
                 command: None,
@@ -505,6 +554,46 @@ pub fn test_some_range(a: int) -> bool {
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
 
+        let extract_into_constant_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_constant",
+                    RefactorExtract,
+                ),
+                label: "Extract into constant",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: None,
+                command: None,
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_constant_assist);
+
+        let extract_into_static_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_static",
+                    RefactorExtract,
+                ),
+                label: "Extract into static",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: None,
+                command: None,
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_static_assist);
+
         let extract_into_function_assist = assists.next().unwrap();
         expect![[r#"
             Assist {
@@ -513,7 +602,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into function",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: None,
                 command: None,
@@ -532,7 +625,7 @@ pub fn test_some_range(a: int) -> bool {
             }),
             frange.into(),
         );
-        assert_eq!(2, assists.len());
+        assert_eq!(4, assists.len());
         let mut assists = assists.into_iter();
 
         let extract_into_variable_assist = assists.next().unwrap();
@@ -543,7 +636,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into variable",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: Some(
                     SourceChange {
@@ -594,6 +691,46 @@ pub fn test_some_range(a: int) -> bool {
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
 
+        let extract_into_constant_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_constant",
+                    RefactorExtract,
+                ),
+                label: "Extract into constant",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: None,
+                command: None,
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_constant_assist);
+
+        let extract_into_static_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_static",
+                    RefactorExtract,
+                ),
+                label: "Extract into static",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: None,
+                command: None,
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_static_assist);
+
         let extract_into_function_assist = assists.next().unwrap();
         expect![[r#"
             Assist {
@@ -602,7 +739,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into function",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: None,
                 command: None,
@@ -613,7 +754,7 @@ pub fn test_some_range(a: int) -> bool {
 
     {
         let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange.into());
-        assert_eq!(2, assists.len());
+        assert_eq!(4, assists.len());
         let mut assists = assists.into_iter();
 
         let extract_into_variable_assist = assists.next().unwrap();
@@ -624,7 +765,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into variable",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: Some(
                     SourceChange {
@@ -675,6 +820,140 @@ pub fn test_some_range(a: int) -> bool {
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
 
+        let extract_into_constant_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_constant",
+                    RefactorExtract,
+                ),
+                label: "Extract into constant",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: Some(
+                    SourceChange {
+                        source_file_edits: {
+                            FileId(
+                                0,
+                            ): (
+                                TextEdit {
+                                    indels: [
+                                        Indel {
+                                            insert: "const",
+                                            delete: 45..47,
+                                        },
+                                        Indel {
+                                            insert: "VAR_NAME:",
+                                            delete: 48..60,
+                                        },
+                                        Indel {
+                                            insert: "i32",
+                                            delete: 61..81,
+                                        },
+                                        Indel {
+                                            insert: "=",
+                                            delete: 82..86,
+                                        },
+                                        Indel {
+                                            insert: "5;\n    if let 2..6 = VAR_NAME {\n        true\n    } else {\n        false\n    }",
+                                            delete: 87..108,
+                                        },
+                                    ],
+                                },
+                                Some(
+                                    SnippetEdit(
+                                        [
+                                            (
+                                                0,
+                                                51..51,
+                                            ),
+                                        ],
+                                    ),
+                                ),
+                            ),
+                        },
+                        file_system_edits: [],
+                        is_snippet: true,
+                    },
+                ),
+                command: Some(
+                    Rename,
+                ),
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_constant_assist);
+
+        let extract_into_static_assist = assists.next().unwrap();
+        expect![[r#"
+            Assist {
+                id: AssistId(
+                    "extract_static",
+                    RefactorExtract,
+                ),
+                label: "Extract into static",
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
+                target: 59..60,
+                source_change: Some(
+                    SourceChange {
+                        source_file_edits: {
+                            FileId(
+                                0,
+                            ): (
+                                TextEdit {
+                                    indels: [
+                                        Indel {
+                                            insert: "static",
+                                            delete: 45..47,
+                                        },
+                                        Indel {
+                                            insert: "VAR_NAME:",
+                                            delete: 48..60,
+                                        },
+                                        Indel {
+                                            insert: "i32",
+                                            delete: 61..81,
+                                        },
+                                        Indel {
+                                            insert: "=",
+                                            delete: 82..86,
+                                        },
+                                        Indel {
+                                            insert: "5;\n    if let 2..6 = VAR_NAME {\n        true\n    } else {\n        false\n    }",
+                                            delete: 87..108,
+                                        },
+                                    ],
+                                },
+                                Some(
+                                    SnippetEdit(
+                                        [
+                                            (
+                                                0,
+                                                52..52,
+                                            ),
+                                        ],
+                                    ),
+                                ),
+                            ),
+                        },
+                        file_system_edits: [],
+                        is_snippet: true,
+                    },
+                ),
+                command: Some(
+                    Rename,
+                ),
+            }
+        "#]]
+        .assert_debug_eq(&extract_into_static_assist);
+
         let extract_into_function_assist = assists.next().unwrap();
         expect![[r#"
             Assist {
@@ -683,7 +962,11 @@ pub fn test_some_range(a: int) -> bool {
                     RefactorExtract,
                 ),
                 label: "Extract into function",
-                group: None,
+                group: Some(
+                    GroupLabel(
+                        "Extract into...",
+                    ),
+                ),
                 target: 59..60,
                 source_change: Some(
                     SourceChange {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 69ea200db16..87c3d166ee6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -933,6 +933,24 @@ enum TheEnum {
 }
 
 #[test]
+fn doctest_extract_constant() {
+    check_doc_test(
+        "extract_constant",
+        r#####"
+fn main() {
+    $0(1 + 2)$0 * 4;
+}
+"#####,
+        r#####"
+fn main() {
+    const $0VAR_NAME: i32 = 1 + 2;
+    VAR_NAME * 4;
+}
+"#####,
+    )
+}
+
+#[test]
 fn doctest_extract_expressions_from_format_string() {
     check_doc_test(
         "extract_expressions_from_format_string",
@@ -1007,6 +1025,24 @@ fn bar(name: i32) -> i32 {
 }
 
 #[test]
+fn doctest_extract_static() {
+    check_doc_test(
+        "extract_static",
+        r#####"
+fn main() {
+    $0(1 + 2)$0 * 4;
+}
+"#####,
+        r#####"
+fn main() {
+    static $0VAR_NAME: i32 = 1 + 2;
+    VAR_NAME * 4;
+}
+"#####,
+    )
+}
+
+#[test]
 fn doctest_extract_struct_from_enum_variant() {
     check_doc_test(
         "extract_struct_from_enum_variant",
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index 0830017bd0f..3c26b043597 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -3,11 +3,13 @@
 pub(crate) use gen_trait_fn_body::gen_trait_fn_body;
 use hir::{
     db::{ExpandDatabase, HirDatabase},
-    HasAttrs as HirHasAttrs, HirDisplay, InFile, Semantics,
+    HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, Semantics,
 };
 use ide_db::{
-    famous_defs::FamousDefs, path_transform::PathTransform,
-    syntax_helpers::prettify_macro_expansion, RootDatabase,
+    famous_defs::FamousDefs,
+    path_transform::PathTransform,
+    syntax_helpers::{node_ext::preorder_expr, prettify_macro_expansion},
+    RootDatabase,
 };
 use stdx::format_to;
 use syntax::{
@@ -19,7 +21,7 @@ use syntax::{
     },
     ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile,
     SyntaxKind::*,
-    SyntaxNode, SyntaxToken, TextRange, TextSize, T,
+    SyntaxNode, SyntaxToken, TextRange, TextSize, WalkEvent, T,
 };
 
 use crate::assist_context::{AssistContext, SourceChangeBuilder};
@@ -966,3 +968,37 @@ pub(crate) fn tt_from_syntax(node: SyntaxNode) -> Vec<NodeOrToken<ast::TokenTree
 
     tt_stack.pop().expect("parent token tree was closed before it was completed").1
 }
+
+pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bool {
+    let mut is_const = true;
+    preorder_expr(expr, &mut |ev| {
+        let expr = match ev {
+            WalkEvent::Enter(_) if !is_const => return true,
+            WalkEvent::Enter(expr) => expr,
+            WalkEvent::Leave(_) => return false,
+        };
+        match expr {
+            ast::Expr::CallExpr(call) => {
+                if let Some(ast::Expr::PathExpr(path_expr)) = call.expr() {
+                    if let Some(PathResolution::Def(ModuleDef::Function(func))) =
+                        path_expr.path().and_then(|path| sema.resolve_path(&path))
+                    {
+                        is_const &= func.is_const(sema.db);
+                    }
+                }
+            }
+            ast::Expr::MethodCallExpr(call) => {
+                is_const &=
+                    sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true)
+            }
+            ast::Expr::ForExpr(_)
+            | ast::Expr::ReturnExpr(_)
+            | ast::Expr::TryExpr(_)
+            | ast::Expr::YieldExpr(_)
+            | ast::Expr::AwaitExpr(_) => is_const = false,
+            _ => (),
+        }
+        !is_const
+    });
+    is_const
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs
index d5f9cd5fc76..04f40e805ad 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs
@@ -11,7 +11,7 @@ pub(super) fn complete_lint(
     existing_lints: &[ast::Path],
     lints_completions: &[Lint],
 ) {
-    for &Lint { label, description } in lints_completions {
+    for &Lint { label, description, .. } in lints_completions {
         let (qual, name) = {
             // FIXME: change `Lint`'s label to not store a path in it but split the prefix off instead?
             let mut parts = label.split("::");
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index 4a678963b93..3b7898b9e86 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -1,7 +1,7 @@
 //! Module responsible for analyzing the code surrounding the cursor for completion.
 use std::iter;
 
-use hir::{Semantics, Type, TypeInfo, Variant};
+use hir::{ExpandResult, Semantics, Type, TypeInfo, Variant};
 use ide_db::{active_parameter::ActiveParameter, RootDatabase};
 use itertools::Either;
 use syntax::{
@@ -104,7 +104,10 @@ fn expand(
                 // maybe parent items have attributes, so continue walking the ancestors
                 (None, None) => continue 'ancestors,
                 // successful expansions
-                (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => {
+                (
+                    Some(ExpandResult { value: actual_expansion, err: _ }),
+                    Some((fake_expansion, fake_mapped_token)),
+                ) => {
                     let new_offset = fake_mapped_token.text_range().start();
                     if new_offset + relative_offset > actual_expansion.text_range().end() {
                         // offset outside of bounds from the original expansion,
@@ -239,8 +242,8 @@ fn expand(
             };
 
             match (
-                sema.expand(&actual_macro_call),
-                sema.speculative_expand(
+                sema.expand_macro_call(&actual_macro_call),
+                sema.speculative_expand_macro_call(
                     &actual_macro_call,
                     &speculative_args,
                     fake_ident_token.clone(),
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
index b97dfb3b8ef..14af22c3193 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
@@ -1,9 +1,16 @@
 //! Generated by `cargo codegen lint-definitions`, do not edit by hand.
 
+use span::Edition;
+
+use crate::Severity;
+
 #[derive(Clone)]
 pub struct Lint {
     pub label: &'static str,
     pub description: &'static str,
+    pub default_severity: Severity,
+    pub warn_since: Option<Edition>,
+    pub deny_since: Option<Edition>,
 }
 
 pub struct LintGroup {
@@ -13,802 +20,1631 @@ pub struct LintGroup {
 
 pub const DEFAULT_LINTS: &[Lint] = &[
     Lint {
+        label: "abi_unsupported_vector_types",
+        description: r##"this function call or definition uses a vector type which is not enabled"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
         label: "absolute_paths_not_starting_with_crate",
         description: r##"fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "ambiguous_associated_items",
+        description: r##"ambiguous associated items"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "ambiguous_associated_items", description: r##"ambiguous associated items"## },
     Lint {
         label: "ambiguous_glob_imports",
         description: r##"detects certain glob imports that require reporting an ambiguity error"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "ambiguous_glob_reexports",
+        description: r##"ambiguous glob re-exports"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "ambiguous_negative_literals",
+        description: r##"ambiguous negative literals operations"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "ambiguous_glob_reexports", description: r##"ambiguous glob re-exports"## },
     Lint {
         label: "ambiguous_wide_pointer_comparisons",
         description: r##"detects ambiguous wide pointer comparisons"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "anonymous_parameters",
+        description: r##"detects anonymous parameters"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "arithmetic_overflow",
+        description: r##"arithmetic operation overflows"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "anonymous_parameters", description: r##"detects anonymous parameters"## },
-    Lint { label: "arithmetic_overflow", description: r##"arithmetic operation overflows"## },
     Lint {
         label: "array_into_iter",
         description: r##"detects calling `into_iter` on arrays in Rust 2015 and 2018"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "asm_sub_register",
         description: r##"using only a subset of a register for inline asm inputs"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_fn_in_trait",
         description: r##"use of `async fn` in definition of a publicly-reachable trait"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "bad_asm_style",
+        description: r##"incorrect use of inline assembly"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "bad_asm_style", description: r##"incorrect use of inline assembly"## },
     Lint {
         label: "bare_trait_objects",
         description: r##"suggest using `dyn Trait` for trait objects"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "binary_asm_labels",
+        description: r##"labels in inline assembly containing only 0 or 1 digits"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "bindings_with_variant_name",
         description: r##"detects pattern bindings with the same name as one of the matched variants"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "boxed_slice_into_iter",
         description: r##"detects calling `into_iter` on boxed slices in Rust 2015, 2018, and 2021"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "break_with_label_and_loop",
         description: r##"`break` expression with label and unlabeled loop as value expression"##,
-    },
-    Lint {
-        label: "byte_slice_in_packed_struct_with_derive",
-        description: r##"`[u8]` or `str` used in a packed struct with `derive`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cenum_impl_drop_cast",
         description: r##"a C-like enum implementing Drop is cast"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clashing_extern_declarations",
         description: r##"detects when an extern fn has been declared with the same name but different types"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "closure_returning_async_block",
+        description: r##"closure that returns `async {}` could be rewritten as an async closure"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "coherence_leak_check",
         description: r##"distinct impls distinguished only by the leak-check code"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "conflicting_repr_hints",
         description: r##"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "confusable_idents",
         description: r##"detects visually confusable pairs between identifiers"##,
-    },
-    Lint {
-        label: "const_eval_mutable_ptr_in_final_value",
-        description: r##"detects a mutable pointer that has leaked into final value of a const expression"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_evaluatable_unchecked",
         description: r##"detects a generic constant is used in a type without a emitting a warning"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_item_mutation",
         description: r##"detects attempts to mutate a `const` item"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "dangling_pointers_from_temporaries",
+        description: r##"detects getting a pointer from a temporary"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "dead_code",
+        description: r##"detect unused, unexported items"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "dead_code", description: r##"detect unused, unexported items"## },
     Lint {
         label: "dependency_on_unit_never_type_fallback",
         description: r##"never type fallback affecting unsafe function calls"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "deprecated", description: r##"detects use of deprecated items"## },
     Lint {
-        label: "deprecated_cfg_attr_crate_type_name",
-        description: r##"detects usage of `#![cfg_attr(..., crate_type/crate_name = "...")]`"##,
+        label: "deprecated",
+        description: r##"detects use of deprecated items"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deprecated_in_future",
         description: r##"detects use of items that will be deprecated in a future version"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "deprecated_safe",
+        label: "deprecated_safe_2024",
         description: r##"detects unsafe functions being used as safe functions"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deprecated_where_clause_location",
         description: r##"deprecated where clause location"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deref_into_dyn_supertrait",
         description: r##"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deref_nullptr",
         description: r##"detects when an null pointer is dereferenced"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "drop_bounds",
         description: r##"bounds of the form `T: Drop` are most likely incorrect"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "dropping_copy_types",
         description: r##"calls to `std::mem::drop` with a value that implements Copy"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "dropping_references",
         description: r##"calls to `std::mem::drop` with a reference instead of an owned value"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "duplicate_macro_attributes",
+        description: r##"duplicated attribute"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "duplicate_macro_attributes", description: r##"duplicated attribute"## },
     Lint {
         label: "dyn_drop",
         description: r##"trait objects of the form `dyn Drop` are useless"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "edition_2024_expr_fragment_specifier",
+        description: r##"The `expr` fragment specifier will accept more expressions in the 2024 edition. To keep the existing behavior, use the `expr_2021` fragment specifier."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "elided_lifetimes_in_associated_constant",
         description: r##"elided lifetimes cannot be used in associated constants in impls"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "elided_lifetimes_in_paths",
         description: r##"hidden lifetime parameters in types are deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "elided_named_lifetimes",
+        description: r##"detects when an elided lifetime gets resolved to be `'static` or some named parameter"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ellipsis_inclusive_range_patterns",
         description: r##"`...` range patterns are deprecated"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "enum_intrinsics_non_enums",
         description: r##"detects calls to `core::mem::discriminant` and `core::mem::variant_count` with non-enum types"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "explicit_builtin_cfgs_in_flags",
+        description: r##"detects builtin cfgs set via the `--cfg`"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "explicit_outlives_requirements",
         description: r##"outlives requirements can be inferred"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "exported_private_dependencies",
         description: r##"public interface leaks type from a private dependency"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ffi_unwind_calls",
         description: r##"call to foreign functions or function pointers with FFI-unwind ABI"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "for_loops_over_fallibles",
         description: r##"for-looping over an `Option` or a `Result`, which is more clearly expressed as an `if let`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "forbidden_lint_groups",
+        description: r##"applying forbid to lint-groups"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "forbidden_lint_groups", description: r##"applying forbid to lint-groups"## },
     Lint {
         label: "forgetting_copy_types",
         description: r##"calls to `std::mem::forget` with a value that implements Copy"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "forgetting_references",
         description: r##"calls to `std::mem::forget` with a reference instead of an owned value"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "function_item_references",
         description: r##"suggest casting to a function pointer when attempting to take references to function items"##,
-    },
-    Lint {
-        label: "future_incompatible",
-        description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-eval-mutable-ptr-in-final-value, const-evaluatable-unchecked, dependency-on-unit-never-type-fallback, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, never-type-fallback-flowing-into-unsafe, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, wasm-c-abi, writes-through-immutable-pointer"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fuzzy_provenance_casts",
         description: r##"a fuzzy integer to pointer cast is used"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hidden_glob_reexports",
         description: r##"name introduced by a private item shadows a name introduced by a public glob re-export"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "if_let_rescope",
+        description: r##"`if let` assigns a shorter lifetime to temporary values being pattern-matched against in Edition 2024 and rewriting in `match` is an option to preserve the semantics up to Edition 2021"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ill_formed_attribute_input",
         description: r##"ill-formed attribute inputs that were previously accepted and used in practice"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "impl_trait_overcaptures",
         description: r##"`impl Trait` will capture more lifetimes than possibly intended in edition 2024"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "impl_trait_redundant_captures",
         description: r##"redundant precise-capturing `use<...>` syntax on an `impl Trait`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "improper_ctypes",
         description: r##"proper use of libc types in foreign modules"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "improper_ctypes_definitions",
         description: r##"proper use of libc types in foreign item definitions"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "incomplete_features",
         description: r##"incomplete features that may function improperly in some or all cases"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "incomplete_include",
+        description: r##"trailing content in included file"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "incomplete_include", description: r##"trailing content in included file"## },
     Lint {
         label: "ineffective_unstable_trait_impl",
         description: r##"detects `#[unstable]` on stable trait implementations for stable types"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "inline_no_sanitize",
         description: r##"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "internal_features",
         description: r##"internal features are not supposed to be used"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_atomic_ordering",
         description: r##"usage of invalid atomic ordering in atomic operations and memory fences"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_doc_attributes",
         description: r##"detects invalid `#[doc(...)]` attributes"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_from_utf8",
         description: r##"using a non UTF-8 literal in `std::str::from_utf8`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_from_utf8_unchecked",
         description: r##"using a non UTF-8 literal in `std::str::from_utf8_unchecked`"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_macro_export_arguments",
         description: r##""invalid_parameter" isn't a valid argument for `#[macro_export]`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_nan_comparisons",
         description: r##"detects invalid floating point NaN comparisons"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_reference_casting",
         description: r##"casts of `&T` to `&mut T` without interior mutability"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_type_param_default",
         description: r##"type parameter default erroneously allowed in invalid location"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "invalid_value",
         description: r##"an invalid value is being created (such as a null reference)"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "irrefutable_let_patterns",
         description: r##"detects irrefutable patterns in `if let` and `while let` statements"##,
-    },
-    Lint {
-        label: "keyword_idents",
-        description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "keyword_idents_2018",
         description: r##"detects edition keywords being used as an identifier"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "keyword_idents_2024",
         description: r##"detects edition keywords being used as an identifier"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "large_assignments",
+        description: r##"detects large moves or copies"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "large_assignments", description: r##"detects large moves or copies"## },
     Lint {
         label: "late_bound_lifetime_arguments",
         description: r##"detects generic lifetime arguments in path segments with late bound lifetime parameters"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "legacy_derive_helpers",
         description: r##"detects derive helper attributes that are used before they are introduced"##,
-    },
-    Lint {
-        label: "let_underscore",
-        description: r##"lint group for: let-underscore-drop, let-underscore-lock"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "let_underscore_drop",
-        description: r##"non-binding let on a type that implements `Drop`"##,
+        description: r##"non-binding let on a type that has a destructor"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "let_underscore_lock",
         description: r##"non-binding let on a synchronization lock"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "long_running_const_eval",
         description: r##"detects long const eval operations"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "lossy_provenance_casts",
         description: r##"a lossy pointer to integer cast is used"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "macro_expanded_macro_exports_accessed_by_absolute_paths",
         description: r##"macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "macro_use_extern_crate",
         description: r##"the `#[macro_use]` attribute is now deprecated in favor of using macros via the module system"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "map_unit_fn",
         description: r##"`Iterator::map` call that discard the iterator's values"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "meta_variable_misuse",
         description: r##"possible meta-variable misuse at macro definition"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "missing_abi",
+        description: r##"No declared ABI for extern declaration"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "missing_abi", description: r##"No declared ABI for extern declaration"## },
     Lint {
         label: "missing_copy_implementations",
         description: r##"detects potentially-forgotten implementations of `Copy`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "missing_debug_implementations",
         description: r##"detects missing implementations of Debug"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "missing_docs",
         description: r##"detects missing documentation for public members"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "missing_fragment_specifier",
         description: r##"detects missing fragment specifiers in unused `macro_rules!` patterns"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "missing_unsafe_on_extern",
         description: r##"detects missing unsafe keyword on extern declarations"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "mixed_script_confusables",
         description: r##"detects Unicode scripts whose mixed script confusables codepoints are solely used"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "multiple_supertrait_upcastable",
-        description: r##"detect when an object-safe trait has multiple supertraits"##,
+        description: r##"detect when a dyn-compatible trait has multiple supertraits"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "must_not_suspend",
         description: r##"use of a `#[must_not_suspend]` value across a yield point"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "mutable_transmutes",
         description: r##"transmuting &T to &mut T is undefined behavior, even if the reference is unused"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "named_arguments_used_positionally",
         description: r##"named arguments in format used positionally"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "named_asm_labels",
+        description: r##"named labels in inline assembly"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "named_asm_labels", description: r##"named labels in inline assembly"## },
     Lint {
         label: "never_type_fallback_flowing_into_unsafe",
         description: r##"never type fallback affecting unsafe function calls"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: Some(Edition::Edition2024),
     },
     Lint {
         label: "no_mangle_const_items",
         description: r##"const items will not have their symbols exported"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "no_mangle_generic_items",
+        description: r##"generic items must be mangled"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "non_ascii_idents",
+        description: r##"detects non-ASCII identifiers"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "no_mangle_generic_items", description: r##"generic items must be mangled"## },
-    Lint { label: "non_ascii_idents", description: r##"detects non-ASCII identifiers"## },
     Lint {
         label: "non_camel_case_types",
         description: r##"types, variants, traits and type parameters should have camel case names"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_contiguous_range_endpoints",
         description: r##"detects off-by-one errors with exclusive range patterns"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_exhaustive_omitted_patterns",
         description: r##"detect when patterns of types marked `non_exhaustive` are missed"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_fmt_panics",
         description: r##"detect single-argument panic!() invocations in which the argument is not a format string"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "non_local_definitions",
+        description: r##"checks for non-local definitions"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "non_local_definitions", description: r##"checks for non-local definitions"## },
     Lint {
         label: "non_shorthand_field_patterns",
         description: r##"using `Struct { x: x }` instead of `Struct { x }` in a pattern"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_snake_case",
         description: r##"variables, methods, functions, lifetime parameters and modules should have snake case names"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_upper_case_globals",
         description: r##"static constants should have uppercase identifiers"##,
-    },
-    Lint {
-        label: "nonstandard_style",
-        description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "noop_method_call",
         description: r##"detects the use of well-known noop methods"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "opaque_hidden_inferred_bound",
         description: r##"detects the use of nested `impl Trait` types in associated type bounds that are not general enough"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "order_dependent_trait_objects",
         description: r##"trait-object types were treated as different depending on marker-trait order"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "out_of_scope_macro_calls",
         description: r##"detects out of scope calls to `macro_rules` in key-value attributes"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "overflowing_literals",
+        description: r##"literal out of range for its type"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "overflowing_literals", description: r##"literal out of range for its type"## },
     Lint {
         label: "overlapping_range_endpoints",
         description: r##"detects range patterns with overlapping endpoints"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "path_statements",
+        description: r##"path statements with no effect"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "path_statements", description: r##"path statements with no effect"## },
     Lint {
         label: "patterns_in_fns_without_body",
         description: r##"patterns in functions without body were erroneously allowed"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "private_bounds",
         description: r##"private type in secondary interface of an item"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "private_interfaces",
         description: r##"private type in primary interface of an item"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_derive_resolution_fallback",
         description: r##"detects proc macro derives using inaccessible names from parent modules"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "ptr_cast_add_auto_to_object",
+        description: r##"detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "ptr_to_integer_transmute_in_consts",
+        description: r##"detects pointer to integer transmutes in const functions and associated constants"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "pub_use_of_private_extern_crate",
         description: r##"detect public re-exports of private extern crates"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "redundant_imports",
+        description: r##"imports that are redundant due to being imported already"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "redundant_lifetimes",
         description: r##"detects lifetime parameters that are redundant because they are equal to some other named lifetime"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "redundant_semicolons",
         description: r##"detects unnecessary trailing semicolons"##,
-    },
-    Lint {
-        label: "refining_impl_trait",
-        description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "refining_impl_trait_internal",
         description: r##"impl trait in impl method signature does not match trait method signature"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "refining_impl_trait_reachable",
         description: r##"impl trait in impl method signature does not match trait method signature"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "renamed_and_removed_lints",
         description: r##"lints that have been renamed or removed"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "repr_transparent_external_private_fields",
         description: r##"transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields"##,
-    },
-    Lint {
-        label: "rust_2018_compatibility",
-        description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##,
-    },
-    Lint {
-        label: "rust_2018_idioms",
-        description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##,
-    },
-    Lint {
-        label: "rust_2021_compatibility",
-        description: r##"lint group for: ellipsis-inclusive-range-patterns, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions, array-into-iter, non-fmt-panics"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rust_2021_incompatible_closure_captures",
         description: r##"detects closures affected by Rust 2021 changes"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rust_2021_incompatible_or_patterns",
         description: r##"detects usage of old versions of or-patterns"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rust_2021_prefixes_incompatible_syntax",
         description: r##"identifiers that will be parsed as a prefix in Rust 2021"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rust_2021_prelude_collisions",
         description: r##"detects the usage of trait methods which are ambiguous with traits added to the prelude in future editions"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "rust_2024_compatibility",
-        description: r##"lint group for: keyword-idents-2024, deprecated-safe, missing-unsafe-on-extern, static-mut-refs, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn, boxed-slice-into-iter"##,
+        label: "rust_2024_guarded_string_incompatible_syntax",
+        description: r##"will be parsed as a guarded string in Rust 2024"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rust_2024_incompatible_pat",
         description: r##"detects patterns whose meaning will change in Rust 2024"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "rust_2024_prelude_collisions",
+        description: r##"detects the usage of trait methods which are ambiguous with traits added to the prelude in future editions"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "self_constructor_from_outer_item",
         description: r##"detect unsupported use of `Self` from outer item"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "semicolon_in_expressions_from_macros",
         description: r##"trailing semicolon in macro body used as expression"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "single_use_lifetimes",
         description: r##"detects lifetime parameters that are only used once"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "soft_unstable",
         description: r##"a feature gate that doesn't break dependent crates"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "special_module_name",
         description: r##"module declarations for files with a special meaning"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "stable_features",
         description: r##"stable features found in `#[feature]` directive"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "static_mut_refs",
         description: r##"shared references or mutable references of mutable static is discouraged"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: Some(Edition::Edition2024),
     },
     Lint {
         label: "suspicious_double_ref_op",
         description: r##"suspicious call of trait method on `&&T`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "temporary_cstring_as_ptr",
-        description: r##"detects getting the inner pointer of a temporary `CString`"##,
+        label: "tail_expr_drop_order",
+        description: r##"Detect and warn on significant change in drop order in tail expression location"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "test_unstable_lint",
         description: r##"this unstable lint is only for testing"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "text_direction_codepoint_in_comment",
         description: r##"invisible directionality-changing codepoints in comment"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "text_direction_codepoint_in_literal",
         description: r##"detect special Unicode codepoints that affect the visual representation of text on screen, changing the direction in which text flows"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trivial_bounds",
         description: r##"these bounds don't depend on an type parameters"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trivial_casts",
         description: r##"detects trivial casts which could be removed"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trivial_numeric_casts",
         description: r##"detects trivial casts of numeric types which could be removed"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "type_alias_bounds",
         description: r##"bounds in type aliases are not enforced"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "tyvar_behind_raw_pointer",
         description: r##"raw pointer to an inference variable"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "uncommon_codepoints",
         description: r##"detects uncommon Unicode codepoints in identifiers"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unconditional_panic",
         description: r##"operation will cause a panic at runtime"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unconditional_recursion",
         description: r##"functions that cannot return without calling themselves"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "uncovered_param_in_projection",
         description: r##"impl contains type parameters that are not covered"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "undefined_naked_function_abi",
         description: r##"undefined naked function ABI"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "undropped_manually_drops",
         description: r##"calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of it's inner value"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unexpected_cfgs",
         description: r##"detects unexpected names and values in `#[cfg]` conditions"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unfulfilled_lint_expectations",
         description: r##"unfulfilled lint expectation"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ungated_async_fn_track_caller",
         description: r##"enabling track_caller on an async fn is a no-op unless the async_fn_track_caller feature is enabled"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "uninhabited_static",
+        description: r##"uninhabited static"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "uninhabited_static", description: r##"uninhabited static"## },
     Lint {
         label: "unit_bindings",
         description: r##"binding is useless because it has the unit `()` type"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unknown_crate_types",
         description: r##"unknown crate type found in `#[crate_type]` directive"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unknown_lints",
+        description: r##"unrecognized lint attribute"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unknown_lints", description: r##"unrecognized lint attribute"## },
     Lint {
         label: "unknown_or_malformed_diagnostic_attributes",
         description: r##"unrecognized or malformed diagnostic attribute"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unnameable_test_items",
         description: r##"detects an item that cannot be named being marked as `#[test_case]`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unnameable_types",
         description: r##"effective visibility of a type is larger than the area in which it can be named"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unqualified_local_imports",
+        description: r##"`use` of a local item without leading `self::`, `super::`, or `crate::`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unreachable_code",
+        description: r##"detects unreachable code paths"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unreachable_patterns",
+        description: r##"detects unreachable patterns"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unreachable_code", description: r##"detects unreachable code paths"## },
-    Lint { label: "unreachable_patterns", description: r##"detects unreachable patterns"## },
     Lint {
         label: "unreachable_pub",
         description: r##"`pub` items not reachable from crate root"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsafe_attr_outside_unsafe",
         description: r##"detects unsafe attributes outside of unsafe"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsafe_code",
         description: r##"usage of `unsafe` code and other potentially unsound constructs"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsafe_op_in_unsafe_fn",
         description: r##"unsafe operations in unsafe functions without an explicit unsafe block are deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: Some(Edition::Edition2024),
+        deny_since: None,
+    },
+    Lint {
+        label: "unstable_features",
+        description: r##"enabling unstable features"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unstable_features", description: r##"enabling unstable features"## },
     Lint {
         label: "unstable_name_collisions",
         description: r##"detects name collision with an existing but unstable method"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unstable_syntax_pre_expansion",
         description: r##"unstable syntax can change at any point in the future, causing a hard error!"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "unsupported_calling_conventions",
-        description: r##"use of unsupported calling convention"##,
-    },
-    Lint {
-        label: "unused",
-        description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##,
+        label: "unsupported_fn_ptr_calling_conventions",
+        description: r##"use of unsupported calling convention for function pointer"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_allocation",
         description: r##"detects unnecessary allocations that can be eliminated"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_assignments",
         description: r##"detect assignments that will never be read"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_associated_type_bounds",
         description: r##"detects unused `Foo = Bar` bounds in `dyn Trait<Foo = Bar>`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_attributes",
         description: r##"detects attributes that were not used by the compiler"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unused_braces",
+        description: r##"unnecessary braces around an expression"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unused_braces", description: r##"unnecessary braces around an expression"## },
     Lint {
         label: "unused_comparisons",
         description: r##"comparisons made useless by limits of the types involved"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_crate_dependencies",
         description: r##"crate dependencies that are never used"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_doc_comments",
         description: r##"detects doc comments that aren't used by rustdoc"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unused_extern_crates",
+        description: r##"extern crates that are never used"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unused_extern_crates", description: r##"extern crates that are never used"## },
     Lint {
         label: "unused_features",
         description: r##"unused features found in crate-level `#[feature]` directives"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_import_braces",
         description: r##"unnecessary braces around an imported item"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unused_imports",
+        description: r##"imports that are never used"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unused_labels",
+        description: r##"detects labels that are never used"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unused_imports", description: r##"imports that are never used"## },
-    Lint { label: "unused_labels", description: r##"detects labels that are never used"## },
     Lint {
         label: "unused_lifetimes",
         description: r##"detects lifetime parameters that are never used"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_macro_rules",
         description: r##"detects macro rules that were not used"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unused_macros",
+        description: r##"detects macros that were not used"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unused_macros", description: r##"detects macros that were not used"## },
     Lint {
         label: "unused_must_use",
         description: r##"unused result of a type flagged as `#[must_use]`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_mut",
         description: r##"detect mut variables which don't need to be mutable"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_parens",
         description: r##"`if`, `match`, `while` and `return` do not need parentheses"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_qualifications",
         description: r##"detects unnecessarily qualified names"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unused_results",
         description: r##"unused result of an expression in a statement"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unused_unsafe",
+        description: r##"unnecessary use of an `unsafe` block"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "unused_unsafe", description: r##"unnecessary use of an `unsafe` block"## },
     Lint {
         label: "unused_variables",
         description: r##"detect variables which are not used in any way"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "useless_deprecated",
         description: r##"detects deprecation attributes with no effect"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "useless_ptr_null_checks",
         description: r##"useless checking of non-null-typed pointer"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "variant_size_differences",
         description: r##"detects enums with widely varying variant sizes"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "warnings",
         description: r##"mass-change the level for lints which produce warnings"##,
-    },
-    Lint {
-        label: "warnings",
-        description: r##"lint group for: all lints that are set to issue warnings"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "wasm_c_abi",
         description: r##"detects dependencies that are incompatible with the Wasm C ABI"##,
+        default_severity: Severity::Error,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "while_true",
         description: r##"suggest using `loop { }` instead of `while true { }`"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "deprecated_safe",
+        description: r##"lint group for: deprecated-safe-2024"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "future_incompatible",
+        description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "keyword_idents",
+        description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "let_underscore",
+        description: r##"lint group for: let-underscore-drop, let-underscore-lock"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "nonstandard_style",
+        description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "writes_through_immutable_pointer",
-        description: r##"shared references are immutable, and pointers derived from them must not be written to"##,
+        label: "refining_impl_trait",
+        description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "rust_2018_compatibility",
+        description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "rust_2018_idioms",
+        description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "rust_2021_compatibility",
+        description: r##"lint group for: ellipsis-inclusive-range-patterns, array-into-iter, non-fmt-panics, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "rust_2024_compatibility",
+        description: r##"lint group for: keyword-idents-2024, edition-2024-expr-fragment-specifier, boxed-slice-into-iter, impl-trait-overcaptures, if-let-rescope, static-mut-refs, dependency-on-unit-never-type-fallback, deprecated-safe-2024, missing-unsafe-on-extern, never-type-fallback-flowing-into-unsafe, rust-2024-guarded-string-incompatible-syntax, rust-2024-incompatible-pat, rust-2024-prelude-collisions, tail-expr-drop-order, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unused",
+        description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "warnings",
+        description: r##"lint group for: all lints that are set to issue warnings"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
 ];
 
 pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
+            label: "deprecated_safe",
+            description: r##"lint group for: deprecated-safe-2024"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
+        },
+        children: &["deprecated_safe_2024"],
+    },
+    LintGroup {
+        lint: Lint {
             label: "future_incompatible",
-            description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-eval-mutable-ptr-in-final-value, const-evaluatable-unchecked, dependency-on-unit-never-type-fallback, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, never-type-fallback-flowing-into-unsafe, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, wasm-c-abi, writes-through-immutable-pointer"##,
+            description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "deref_into_dyn_supertrait",
+            "abi_unsupported_vector_types",
             "ambiguous_associated_items",
             "ambiguous_glob_imports",
-            "byte_slice_in_packed_struct_with_derive",
             "cenum_impl_drop_cast",
             "coherence_leak_check",
             "conflicting_repr_hints",
-            "const_eval_mutable_ptr_in_final_value",
             "const_evaluatable_unchecked",
-            "dependency_on_unit_never_type_fallback",
-            "deprecated_cfg_attr_crate_type_name",
             "elided_lifetimes_in_associated_constant",
             "forbidden_lint_groups",
             "ill_formed_attribute_input",
@@ -817,11 +1653,11 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
             "legacy_derive_helpers",
             "macro_expanded_macro_exports_accessed_by_absolute_paths",
             "missing_fragment_specifier",
-            "never_type_fallback_flowing_into_unsafe",
             "order_dependent_trait_objects",
             "out_of_scope_macro_calls",
             "patterns_in_fns_without_body",
             "proc_macro_derive_resolution_fallback",
+            "ptr_cast_add_auto_to_object",
             "pub_use_of_private_extern_crate",
             "repr_transparent_external_private_fields",
             "self_constructor_from_outer_item",
@@ -831,15 +1667,17 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
             "uninhabited_static",
             "unstable_name_collisions",
             "unstable_syntax_pre_expansion",
-            "unsupported_calling_conventions",
+            "unsupported_fn_ptr_calling_conventions",
             "wasm_c_abi",
-            "writes_through_immutable_pointer",
         ],
     },
     LintGroup {
         lint: Lint {
             label: "keyword_idents",
             description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &["keyword_idents_2018", "keyword_idents_2024"],
     },
@@ -847,6 +1685,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
         lint: Lint {
             label: "let_underscore",
             description: r##"lint group for: let-underscore-drop, let-underscore-lock"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &["let_underscore_drop", "let_underscore_lock"],
     },
@@ -854,6 +1695,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
         lint: Lint {
             label: "nonstandard_style",
             description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &["non_camel_case_types", "non_snake_case", "non_upper_case_globals"],
     },
@@ -861,6 +1705,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
         lint: Lint {
             label: "refining_impl_trait",
             description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &["refining_impl_trait_reachable", "refining_impl_trait_internal"],
     },
@@ -868,6 +1715,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
         lint: Lint {
             label: "rust_2018_compatibility",
             description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "keyword_idents_2018",
@@ -880,6 +1730,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
         lint: Lint {
             label: "rust_2018_idioms",
             description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "bare_trait_objects",
@@ -892,38 +1745,56 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "rust_2021_compatibility",
-            description: r##"lint group for: ellipsis-inclusive-range-patterns, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions, array-into-iter, non-fmt-panics"##,
+            description: r##"lint group for: ellipsis-inclusive-range-patterns, array-into-iter, non-fmt-panics, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "ellipsis_inclusive_range_patterns",
+            "array_into_iter",
+            "non_fmt_panics",
             "bare_trait_objects",
             "rust_2021_incompatible_closure_captures",
             "rust_2021_incompatible_or_patterns",
             "rust_2021_prefixes_incompatible_syntax",
             "rust_2021_prelude_collisions",
-            "array_into_iter",
-            "non_fmt_panics",
         ],
     },
     LintGroup {
         lint: Lint {
             label: "rust_2024_compatibility",
-            description: r##"lint group for: keyword-idents-2024, deprecated-safe, missing-unsafe-on-extern, static-mut-refs, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn, boxed-slice-into-iter"##,
+            description: r##"lint group for: keyword-idents-2024, edition-2024-expr-fragment-specifier, boxed-slice-into-iter, impl-trait-overcaptures, if-let-rescope, static-mut-refs, dependency-on-unit-never-type-fallback, deprecated-safe-2024, missing-unsafe-on-extern, never-type-fallback-flowing-into-unsafe, rust-2024-guarded-string-incompatible-syntax, rust-2024-incompatible-pat, rust-2024-prelude-collisions, tail-expr-drop-order, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "keyword_idents_2024",
-            "deprecated_safe",
-            "missing_unsafe_on_extern",
+            "edition_2024_expr_fragment_specifier",
+            "boxed_slice_into_iter",
+            "impl_trait_overcaptures",
+            "if_let_rescope",
             "static_mut_refs",
+            "dependency_on_unit_never_type_fallback",
+            "deprecated_safe_2024",
+            "missing_unsafe_on_extern",
+            "never_type_fallback_flowing_into_unsafe",
+            "rust_2024_guarded_string_incompatible_syntax",
+            "rust_2024_incompatible_pat",
+            "rust_2024_prelude_collisions",
+            "tail_expr_drop_order",
             "unsafe_attr_outside_unsafe",
             "unsafe_op_in_unsafe_fn",
-            "boxed_slice_into_iter",
         ],
     },
     LintGroup {
         lint: Lint {
             label: "unused",
             description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "unused_imports",
@@ -950,64 +1821,99 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
             "map_unit_fn",
         ],
     },
-    LintGroup {
-        lint: Lint {
-            label: "warnings",
-            description: r##"lint group for: all lints that are set to issue warnings"##,
-        },
-        children: &[],
-    },
 ];
 
 pub const RUSTDOC_LINTS: &[Lint] = &[
     Lint {
-        label: "rustdoc::all",
-        description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##,
+        label: "rustdoc::bare_urls",
+        description: r##"detects URLs that are not hyperlinks"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "rustdoc::bare_urls", description: r##"detects URLs that are not hyperlinks"## },
     Lint {
         label: "rustdoc::broken_intra_doc_links",
         description: r##"failures in resolving intra-doc link targets"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::invalid_codeblock_attributes",
         description: r##"codeblock attribute looks a lot like a known one"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::invalid_html_tags",
         description: r##"detects invalid HTML tags in doc comments"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::invalid_rust_codeblocks",
         description: r##"codeblock could not be parsed as valid Rust or is empty"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::missing_crate_level_docs",
         description: r##"detects crates with no crate-level documentation"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::missing_doc_code_examples",
         description: r##"detects publicly-exported items without code samples in their documentation"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::private_doc_tests",
         description: r##"detects code samples in docs of private items not documented by rustdoc"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::private_intra_doc_links",
         description: r##"linking from a public item to a private one"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::redundant_explicit_links",
         description: r##"detects redundant explicit links in doc comments"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::unescaped_backticks",
         description: r##"detects unescaped backticks in doc comments"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc::unportable_markdown",
         description: r##"detects markdown that is interpreted differently in different parser"##,
+        default_severity: Severity::Warning,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "rustdoc::all",
+        description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
 ];
 
@@ -1015,6 +1921,9 @@ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup {
     lint: Lint {
         label: "rustdoc::all",
         description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     children: &[
         "rustdoc::broken_intra_doc_links",
@@ -1033,6 +1942,20 @@ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup {
 
 pub const FEATURES: &[Lint] = &[
     Lint {
+        label: "aarch64_unstable_target_feature",
+        description: r##"# `aarch64_unstable_target_feature`
+
+The tracking issue for this feature is: [#44839]
+
+[#44839]: https://github.com/rust-lang/rust/issues/44839
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
         label: "aarch64_ver_target_feature",
         description: r##"# `aarch64_ver_target_feature`
 
@@ -1042,6 +1965,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_avr_interrupt",
@@ -1053,6 +1979,9 @@ The tracking issue for this feature is: [#69664]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_c_cmse_nonsecure_call",
@@ -1145,6 +2074,9 @@ call_nonsecure_function:
         pop     {r7, pc}
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_msp430_interrupt",
@@ -1191,6 +2123,9 @@ Disassembly of section .text:
     c000:       00 13           reti
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_ptx",
@@ -1255,6 +2190,9 @@ $ cat $(find -name '*.s')
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_riscv_interrupt",
@@ -1266,6 +2204,9 @@ The tracking issue for this feature is: [#111889]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_unadjusted",
@@ -1275,6 +2216,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_vectorcall",
@@ -1298,6 +2242,9 @@ fn main() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "abi_x86_interrupt",
@@ -1309,6 +2256,23 @@ The tracking issue for this feature is: [#40180]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "abort_unwind",
+        description: r##"# `abort_unwind`
+
+The tracking issue for this feature is: [#130338]
+
+[#130338]: https://github.com/rust-lang/rust/issues/130338
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "acceptfilter",
@@ -1320,6 +2284,9 @@ The tracking issue for this feature is: [#121891]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "addr_parse_ascii",
@@ -1331,6 +2298,9 @@ The tracking issue for this feature is: [#101035]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "adt_const_params",
@@ -1370,6 +2340,9 @@ fn is_foo_a_and_bar_true<const F: Foo, const B: Bar>() -> bool {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "alloc_error_handler",
@@ -1381,6 +2354,9 @@ The tracking issue for this feature is: [#51540]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "alloc_error_hook",
@@ -1392,6 +2368,9 @@ The tracking issue for this feature is: [#51245]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "alloc_internals",
@@ -1401,6 +2380,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "alloc_layout_extra",
@@ -1412,6 +2394,9 @@ The tracking issue for this feature is: [#55724]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "allocator_api",
@@ -1431,6 +2416,9 @@ for which you want a custom allocator.
 
 TBD
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "allocator_internals",
@@ -1442,6 +2430,9 @@ compiler.
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "allow_internal_unsafe",
@@ -1451,6 +2442,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "allow_internal_unstable",
@@ -1460,6 +2454,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "anonymous_lifetime_in_impl_trait",
@@ -1469,6 +2466,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "anonymous_pipe",
+        description: r##"# `anonymous_pipe`
+
+The tracking issue for this feature is: [#127154]
+
+[#127154]: https://github.com/rust-lang/rust/issues/127154
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "arbitrary_self_types",
@@ -1480,6 +2494,23 @@ The tracking issue for this feature is: [#44874]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "arbitrary_self_types_pointers",
+        description: r##"# `arbitrary_self_types_pointers`
+
+The tracking issue for this feature is: [#44874]
+
+[#44874]: https://github.com/rust-lang/rust/issues/44874
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "arm_target_feature",
@@ -1491,6 +2522,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "array_chunks",
@@ -1502,6 +2536,9 @@ The tracking issue for this feature is: [#74985]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "array_into_iter_constructors",
@@ -1513,6 +2550,9 @@ The tracking issue for this feature is: [#91583]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "array_ptr_get",
@@ -1524,6 +2564,9 @@ The tracking issue for this feature is: [#119834]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "array_repeat",
@@ -1535,6 +2578,9 @@ The tracking issue for this feature is: [#126695]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "array_try_from_fn",
@@ -1546,6 +2592,9 @@ The tracking issue for this feature is: [#89379]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "array_try_map",
@@ -1557,6 +2606,9 @@ The tracking issue for this feature is: [#79711]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "array_windows",
@@ -1568,6 +2620,9 @@ The tracking issue for this feature is: [#75027]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "as_array_of_cells",
@@ -1579,6 +2634,9 @@ The tracking issue for this feature is: [#88248]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ascii_char",
@@ -1590,6 +2648,9 @@ The tracking issue for this feature is: [#110998]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ascii_char_variants",
@@ -1601,21 +2662,9 @@ The tracking issue for this feature is: [#110998]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "asm_const",
-        description: r##"# `asm_const`
-
-The tracking issue for this feature is: [#93332]
-
-[#93332]: https://github.com/rust-lang/rust/issues/93332
-
-------------------------
-
-This feature adds a `const <expr>` operand type to `asm!` and `global_asm!`.
-- `<expr>` must be an integer constant expression.
-- The value of the expression is formatted as a string and substituted directly into the asm template string.
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "asm_experimental_arch",
@@ -1639,8 +2688,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 - MSP430
 - M68k
 - CSKY
-- s390x
-- Arm64EC
+- SPARC
 
 ## Register classes
 
@@ -1652,9 +2700,11 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | NVPTX        | `reg32`        | None\*                             | `r`                  |
 | NVPTX        | `reg64`        | None\*                             | `l`                  |
 | Hexagon      | `reg`          | `r[0-28]`                          | `r`                  |
-| PowerPC      | `reg`          | `r[0-31]`                          | `r`                  |
-| PowerPC      | `reg_nonzero`  | `r[1-31]`                          | `b`                  |
+| Hexagon      | `preg`         | `p[0-3]`                           | Only clobbers        |
+| PowerPC      | `reg`          | `r0`, `r[3-12]`, `r[14-28]`        | `r`                  |
+| PowerPC      | `reg_nonzero`  | `r[3-12]`, `r[14-28]`              | `b`                  |
 | PowerPC      | `freg`         | `f[0-31]`                          | `f`                  |
+| PowerPC      | `vreg`         | `v[0-31]`                          | `v`                  |
 | PowerPC      | `cr`           | `cr[0-7]`, `cr`                    | Only clobbers        |
 | PowerPC      | `xer`          | `xer`                              | Only clobbers        |
 | wasm32       | `local`        | None\*                             | `r`                  |
@@ -1671,11 +2721,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | M68k         | `reg_addr`     | `a[0-3]`                           | `a`                  |
 | CSKY         | `reg`          | `r[0-31]`                          | `r`                  |
 | CSKY         | `freg`         | `f[0-31]`                          | `f`                  |
-| s390x        | `reg`          | `r[0-10]`, `r[12-14]`              | `r`                  |
-| s390x        | `freg`         | `f[0-15]`                          | `f`                  |
-| Arm64EC      | `reg`          | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r`            |
-| Arm64EC      | `vreg`         | `v[0-15]`                          | `w`                  |
-| Arm64EC      | `vreg_low16`   | `v[0-15]`                          | `x`                  |
+| SPARC        | `reg`          | `r[2-29]`                          | `r`                  |
+| SPARC        | `yreg`         | `y`                                | Only clobbers        |
 
 > **Notes**:
 > - NVPTX doesn't have a fixed register set, so named registers are not supported.
@@ -1694,9 +2741,12 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | NVPTX        | `reg32`                         | None           | `i8`, `i16`, `i32`, `f32`               |
 | NVPTX        | `reg64`                         | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
 | Hexagon      | `reg`                           | None           | `i8`, `i16`, `i32`, `f32`               |
-| PowerPC      | `reg`                           | None           | `i8`, `i16`, `i32`                      |
-| PowerPC      | `reg_nonzero`                   | None           | `i8`, `i16`, `i32`                      |
+| Hexagon      | `preg`                          | N/A            | Only clobbers                           |
+| PowerPC      | `reg`                           | None           | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
+| PowerPC      | `reg_nonzero`                   | None           | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
 | PowerPC      | `freg`                          | None           | `f32`, `f64`                            |
+| PowerPC      | `vreg`                          | `altivec`      | `i8x16`, `i16x8`, `i32x4`, `f32x4`      |
+| PowerPC      | `vreg`                          | `vsx`          | `f32`, `f64`, `i64x2`, `f64x2`          |
 | PowerPC      | `cr`                            | N/A            | Only clobbers                           |
 | PowerPC      | `xer`                           | N/A            | Only clobbers                           |
 | wasm32       | `local`                         | None           | `i8` `i16` `i32` `i64` `f32` `f64`      |
@@ -1709,10 +2759,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | M68k         | `reg_data`                      | None           | `i8`, `i16`, `i32`                      |
 | CSKY         | `reg`                           | None           | `i8`, `i16`, `i32`                      |
 | CSKY         | `freg`                          | None           | `f32`,                                  |
-| s390x        | `reg`, `reg_addr`               | None           | `i8`, `i16`, `i32`, `i64`               |
-| s390x        | `freg`                          | None           | `f32`, `f64`                            |
-| Arm64EC      | `reg`                           | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
-| Arm64EC      | `vreg`                          | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
+| SPARC        | `reg`                           | None           | `i8`, `i16`, `i32`, `i64` (SPARC64 only) |
+| SPARC        | `yreg`                          | N/A            | Only clobbers                           |
 
 ## Register aliases
 
@@ -1721,6 +2769,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | Hexagon      | `r29`         | `sp`      |
 | Hexagon      | `r30`         | `fr`      |
 | Hexagon      | `r31`         | `lr`      |
+| PowerPC      | `r1`          | `sp`      |
+| PowerPC      | `r31`         | `fp`      |
+| PowerPC      | `r[0-31]`     | `[0-31]`  |
+| PowerPC      | `f[0-31]`     | `fr[0-31]`|
 | BPF          | `r[0-10]`     | `w[0-10]` |
 | AVR          | `XH`          | `r27`     |
 | AVR          | `XL`          | `r26`     |
@@ -1745,12 +2797,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `r29`         | `rtb`     |
 | CSKY         | `r30`         | `svbr`    |
 | CSKY         | `r31`         | `tls`     |
-| Arm64EC      | `x[0-30]`     | `w[0-30]` |
-| Arm64EC      | `x29`         | `fp`      |
-| Arm64EC      | `x30`         | `lr`      |
-| Arm64EC      | `sp`          | `wsp`     |
-| Arm64EC      | `xzr`         | `wzr`     |
-| Arm64EC      | `v[0-15]`     | `b[0-15]`, `h[0-15]`, `s[0-15]`, `d[0-15]`, `q[0-15]` |
+| SPARC        | `r[0-7]`      | `g[0-7]`  |
+| SPARC        | `r[8-15]`     | `o[0-7]`  |
+| SPARC        | `r[16-23]`    | `l[0-7]`  |
+| SPARC        | `r[24-31]`    | `i[0-7]`  |
 
 > **Notes**:
 > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed
@@ -1760,15 +2810,19 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 
 | Architecture | Unsupported register                    | Reason                                                                                                                                                                              |
 | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| All          | `sp`, `r15` (s390x)                     | The stack pointer must be restored to its original value at the end of an asm code block.                                                                                           |
-| All          | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r11` (s390x), `x29` (Arm64EC) | The frame pointer cannot be used as an input or output.                                                                                                                             |
-| All          | `r19` (Hexagon), `x19` (Arm64EC)        | This is used internally by LLVM as a "base pointer" for functions with complex stack frames.                                                                                        |
+| All          | `sp`, `r14`/`o6` (SPARC)                | The stack pointer must be restored to its original value at the end of an asm code block.                                                                                           |
+| All          | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output.                                                             |
+| All          | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames.                                                                              |
 | MIPS         | `$0` or `$zero`                         | This is a constant zero register which can't be modified.                                                                                                                           |
 | MIPS         | `$1` or `$at`                           | Reserved for assembler.                                                                                                                                                             |
 | MIPS         | `$26`/`$k0`, `$27`/`$k1`                | OS-reserved registers.                                                                                                                                                              |
 | MIPS         | `$28`/`$gp`                             | Global pointer cannot be used as inputs or outputs.                                                                                                                                 |
 | MIPS         | `$ra`                                   | Return address cannot be used as inputs or outputs.                                                                                                                                 |
 | Hexagon      | `lr`                                    | This is the link register which cannot be used as an input or output.                                                                                                               |
+| PowerPC      | `r2`, `r13`                             | These are system reserved registers.                                                                                                                                                |
+| PowerPC      | `lr`                                    | The link register cannot be used as an input or output.                                                                                                                             |
+| PowerPC      | `ctr`                                   | The counter register cannot be used as an input or output.                                                                                                                          |
+| PowerPC      | `vrsave`                                | The vrsave register cannot be used as an input or output.                                                                                                                           |
 | AVR          | `r0`, `r1`, `r1r0`                      | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs.  If modified, they must be restored to their original values before the end of the block. |
 |MSP430        | `r0`, `r2`, `r3`                        | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to.                          |
 | M68k         | `a4`, `a5`                              | Used internally by LLVM for the base pointer and global base pointer. |
@@ -1778,9 +2832,11 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `r15`                                   | This is the link register. |
 | CSKY         | `r[26-30]`                              | Reserved by its ABI.       |
 | CSKY         | `r31`                                   | This is the TLS register.  |
-| Arm64EC      | `xzr`                                   | This is a constant zero register which can't be modified. |
-| Arm64EC      | `x18`                                   | This is an OS-reserved register. |
-| Arm64EC      | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. |
+| SPARC        | `r0`/`g0`                               | This is always zero and cannot be used as inputs or outputs. |
+| SPARC        | `r1`/`g1`                               | Used internally by LLVM. |
+| SPARC        | `r5`/`g5`                               | Reserved for system. (SPARC32 only) |
+| SPARC        | `r6`/`g6`, `r7`/`g7`                    | Reserved for system. |
+| SPARC        | `r31`/`i7`                              | Return address cannot be used as inputs or outputs. |
 
 
 ## Template modifiers
@@ -1796,21 +2852,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | PowerPC      | `reg`          | None     | `0`            | None          |
 | PowerPC      | `reg_nonzero`  | None     | `3`            | None          |
 | PowerPC      | `freg`         | None     | `0`            | None          |
-| s390x        | `reg`          | None     | `%r0`          | None          |
-| s390x        | `reg_addr`     | None     | `%r1`          | None          |
-| s390x        | `freg`         | None     | `%f0`          | None          |
+| PowerPC      | `vreg`         | None     | `0`            | None          |
+| SPARC        | `reg`          | None     | `%o0`          | None          |
 | CSKY         | `reg`          | None     | `r0`           | None          |
 | CSKY         | `freg`         | None     | `f0`           | None          |
-| Arm64EC      | `reg`          | None     | `x0`           | `x`           |
-| Arm64EC      | `reg`          | `w`      | `w0`           | `w`           |
-| Arm64EC      | `reg`          | `x`      | `x0`           | `x`           |
-| Arm64EC      | `vreg`         | None     | `v0`           | None          |
-| Arm64EC      | `vreg`         | `v`      | `v0`           | None          |
-| Arm64EC      | `vreg`         | `b`      | `b0`           | `b`           |
-| Arm64EC      | `vreg`         | `h`      | `h0`           | `h`           |
-| Arm64EC      | `vreg`         | `s`      | `s0`           | `s`           |
-| Arm64EC      | `vreg`         | `d`      | `d0`           | `d`           |
-| Arm64EC      | `vreg`         | `q`      | `q0`           | `q`           |
 
 # Flags covered by `preserves_flags`
 
@@ -1821,12 +2866,60 @@ These flags registers must be restored upon exiting the asm block if the `preser
   - The status register `r2`.
 - M68k
   - The condition code register `ccr`.
-- s390x
-  - The condition code register `cc`.
-- Arm64EC
-  - Condition flags (`NZCV` register).
-  - Floating-point status (`FPSR` register).
+- SPARC
+  - Integer condition codes (`icc` and `xcc`)
+  - Floating-point condition codes (`fcc[0-3]`)
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "asm_experimental_reg",
+        description: r##"# `asm_experimental_arch`
+
+The tracking issue for this feature is: [#133416]
+
+[#133416]: https://github.com/rust-lang/rust/issues/133416
+
+------------------------
+
+This tracks support for additional registers in architectures where inline assembly is already stable.
+
+## Register classes
+
+| Architecture | Register class | Registers | LLVM constraint code |
+| ------------ | -------------- | --------- | -------------------- |
+| s390x | `vreg` | `v[0-31]` | `v` |
+
+> **Notes**:
+> - s390x `vreg` is clobber-only in stable.
+
+## Register class supported types
+
+| Architecture | Register class | Target feature | Allowed types |
+| ------------ | -------------- | -------------- | ------------- |
+| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
+
+## Register aliases
+
+| Architecture | Base register | Aliases |
+| ------------ | ------------- | ------- |
+
+## Unsupported registers
+
+| Architecture | Unsupported register | Reason |
+| ------------ | -------------------- | ------ |
+
+## Template modifiers
+
+| Architecture | Register class | Modifier | Example output | LLVM modifier |
+| ------------ | -------------- | -------- | -------------- | ------------- |
+| s390x | `vreg` | None | `%v0` | None |
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "asm_goto",
@@ -1853,7 +2946,9 @@ unsafe {
 }
 ```
 
-The block must have unit type or diverge.
+The block must have unit type or diverge. The block starts a new safety context,
+so despite outer `unsafe`, you need extra unsafe to perform unsafe operations
+within `label <block>`.
 
 When `label <block>` is used together with `noreturn` option, it means that the
 assembly will not fallthrough. It's allowed to jump to a label within the
@@ -1861,6 +2956,23 @@ assembly. In this case, the entire `asm!` expression will have an unit type as
 opposed to diverging, if not all label blocks diverge. The `asm!` expression
 still diverges if `noreturn` option is used and all label blocks diverge.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "asm_goto_with_outputs",
+        description: r##"# `asm_goto_with_outputs`
+
+The tracking issue for this feature is: [#119364]
+
+[#119364]: https://github.com/rust-lang/rust/issues/119364
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "asm_unwind",
@@ -1874,6 +2986,9 @@ The tracking issue for this feature is: [#93334]
 
 This feature adds a `may_unwind` option to `asm!` which allows an `asm` block to unwind stack and be part of the stack unwinding process. This option is only supported by the LLVM backend right now.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "assert_matches",
@@ -1885,6 +3000,9 @@ The tracking issue for this feature is: [#82775]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "associated_const_equality",
@@ -1896,6 +3014,9 @@ The tracking issue for this feature is: [#92827]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "associated_type_defaults",
@@ -1907,6 +3028,9 @@ The tracking issue for this feature is: [#29661]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_closure",
@@ -1918,6 +3042,9 @@ The tracking issue for this feature is: [#62290]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_drop",
@@ -1929,6 +3056,9 @@ The tracking issue for this feature is: [#126482]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_fn_track_caller",
@@ -1940,6 +3070,9 @@ The tracking issue for this feature is: [#110011]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_fn_traits",
@@ -1957,6 +3090,9 @@ for creating custom closure-like types that return futures.
 The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future
 that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFnMut::CallRefFuture` does).
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_for_loop",
@@ -1968,6 +3104,9 @@ The tracking issue for this feature is: [#118898]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_gen_internals",
@@ -1977,6 +3116,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_iter_from_iter",
@@ -1988,6 +3130,9 @@ The tracking issue for this feature is: [#81798]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "async_iterator",
@@ -1999,6 +3144,23 @@ The tracking issue for this feature is: [#79024]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "async_trait_bounds",
+        description: r##"# `async_trait_bounds`
+
+The tracking issue for this feature is: [#62290]
+
+[#62290]: https://github.com/rust-lang/rust/issues/62290
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "atomic_from_mut",
@@ -2010,6 +3172,9 @@ The tracking issue for this feature is: [#76314]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "auto_traits",
@@ -2120,6 +3285,23 @@ Auto traits cannot have any trait items, such as methods or associated types. Th
 
 Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "autodiff",
+        description: r##"# `autodiff`
+
+The tracking issue for this feature is: [#124509]
+
+[#124509]: https://github.com/rust-lang/rust/issues/124509
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "avx512_target_feature",
@@ -2131,6 +3313,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "backtrace_frames",
@@ -2142,6 +3327,9 @@ The tracking issue for this feature is: [#79676]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "bigint_helper_methods",
@@ -2153,6 +3341,9 @@ The tracking issue for this feature is: [#85532]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "binary_heap_drain_sorted",
@@ -2164,6 +3355,9 @@ The tracking issue for this feature is: [#59278]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "binary_heap_into_iter_sorted",
@@ -2175,6 +3369,9 @@ The tracking issue for this feature is: [#59278]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "bound_as_ref",
@@ -2186,6 +3383,23 @@ The tracking issue for this feature is: [#80996]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "box_as_ptr",
+        description: r##"# `box_as_ptr`
+
+The tracking issue for this feature is: [#129090]
+
+[#129090]: https://github.com/rust-lang/rust/issues/129090
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "box_into_boxed_slice",
@@ -2197,6 +3411,9 @@ The tracking issue for this feature is: [#71582]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "box_into_inner",
@@ -2208,6 +3425,9 @@ The tracking issue for this feature is: [#80437]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "box_patterns",
@@ -2242,6 +3462,37 @@ fn main() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "box_uninit_write",
+        description: r##"# `box_uninit_write`
+
+The tracking issue for this feature is: [#129397]
+
+[#129397]: https://github.com/rust-lang/rust/issues/129397
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "box_vec_non_null",
+        description: r##"# `box_vec_non_null`
+
+The tracking issue for this feature is: [#130364]
+
+[#130364]: https://github.com/rust-lang/rust/issues/130364
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "bpf_target_feature",
@@ -2253,6 +3504,23 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "breakpoint",
+        description: r##"# `breakpoint`
+
+The tracking issue for this feature is: [#133724]
+
+[#133724]: https://github.com/rust-lang/rust/issues/133724
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "btree_cursors",
@@ -2264,6 +3532,23 @@ The tracking issue for this feature is: [#107540]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "btree_entry_insert",
+        description: r##"# `btree_entry_insert`
+
+The tracking issue for this feature is: [#65225]
+
+[#65225]: https://github.com/rust-lang/rust/issues/65225
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "btree_extract_if",
@@ -2275,6 +3560,23 @@ The tracking issue for this feature is: [#70530]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "btree_set_entry",
+        description: r##"# `btree_set_entry`
+
+The tracking issue for this feature is: [#133549]
+
+[#133549]: https://github.com/rust-lang/rust/issues/133549
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "btreemap_alloc",
@@ -2286,6 +3588,9 @@ The tracking issue for this feature is: [#32838]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "buf_read_has_data_left",
@@ -2297,28 +3602,23 @@ The tracking issue for this feature is: [#86423]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "bufread_skip_until",
-        description: r##"# `bufread_skip_until`
+        label: "bufreader_peek",
+        description: r##"# `bufreader_peek`
 
-The tracking issue for this feature is: [#111735]
+The tracking issue for this feature is: [#128405]
 
-[#111735]: https://github.com/rust-lang/rust/issues/111735
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "build_hasher_default_const_new",
-        description: r##"# `build_hasher_default_const_new`
-
-The tracking issue for this feature is: [#123197]
-
-[#123197]: https://github.com/rust-lang/rust/issues/123197
+[#128405]: https://github.com/rust-lang/rust/issues/128405
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "builtin_syntax",
@@ -2330,6 +3630,9 @@ The tracking issue for this feature is: [#110680]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "c_size_t",
@@ -2341,6 +3644,9 @@ The tracking issue for this feature is: [#88345]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "c_str_module",
@@ -2352,6 +3658,9 @@ The tracking issue for this feature is: [#112134]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "c_variadic",
@@ -2380,6 +3689,9 @@ pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "c_variadic",
@@ -2410,6 +3722,9 @@ pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "c_void_variant",
@@ -2419,6 +3734,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "can_vector",
@@ -2430,6 +3748,9 @@ The tracking issue for this feature is: [#69941]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cell_leak",
@@ -2441,6 +3762,9 @@ The tracking issue for this feature is: [#69099]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cell_update",
@@ -2452,6 +3776,9 @@ The tracking issue for this feature is: [#50186]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_accessible",
@@ -2463,6 +3790,38 @@ The tracking issue for this feature is: [#64797]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "cfg_boolean_literals",
+        description: r##"# `cfg_boolean_literals`
+
+The tracking issue for this feature is: [#131204]
+
+[#131204]: https://github.com/rust-lang/rust/issues/131204
+
+------------------------
+
+The `cfg_boolean_literals` feature makes it possible to use the `true`/`false`
+literal as cfg predicate. They always evaluate to true/false respectively.
+
+## Examples
+
+```rust
+#![feature(cfg_boolean_literals)]
+
+#[cfg(true)]
+const A: i32 = 5;
+
+#[cfg(all(false))]
+const A: i32 = 58 * 89;
+```
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_eval",
@@ -2474,6 +3833,9 @@ The tracking issue for this feature is: [#82679]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_match",
@@ -2485,6 +3847,9 @@ The tracking issue for this feature is: [#115585]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_overflow_checks",
@@ -2496,6 +3861,9 @@ The tracking issue for this feature is: [#111466]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_relocation_model",
@@ -2507,6 +3875,9 @@ The tracking issue for this feature is: [#114929]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_sanitize",
@@ -2545,6 +3916,9 @@ fn b() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_sanitizer_cfi",
@@ -2556,6 +3930,9 @@ The tracking issue for this feature is: [#89653]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_target_compact",
@@ -2567,6 +3944,9 @@ The tracking issue for this feature is: [#96901]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_target_has_atomic",
@@ -2578,6 +3958,9 @@ The tracking issue for this feature is: [#94039]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_target_has_atomic_equal_alignment",
@@ -2589,6 +3972,9 @@ The tracking issue for this feature is: [#93822]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_target_thread_local",
@@ -2600,6 +3986,9 @@ The tracking issue for this feature is: [#29594]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_ub_checks",
@@ -2611,6 +4000,9 @@ The tracking issue for this feature is: [#123499]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfg_version",
@@ -2650,6 +4042,9 @@ fn b() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cfi_encoding",
@@ -2679,17 +4074,9 @@ extern {
 }
 ```
 "##,
-    },
-    Lint {
-        label: "char_indices_offset",
-        description: r##"# `char_indices_offset`
-
-The tracking issue for this feature is: [#83871]
-
-[#83871]: https://github.com/rust-lang/rust/issues/83871
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "char_internals",
@@ -2699,17 +4086,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "char_min",
-        description: r##"# `char_min`
-
-The tracking issue for this feature is: [#114298]
-
-[#114298]: https://github.com/rust-lang/rust/issues/114298
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clone_to_uninit",
@@ -2721,6 +4100,9 @@ The tracking issue for this feature is: [#126799]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "closure_lifetime_binder",
@@ -2732,6 +4114,9 @@ The tracking issue for this feature is: [#97362]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "closure_track_caller",
@@ -2748,6 +4133,9 @@ Calls made to the closure or coroutine will have caller information
 available through `std::panic::Location::caller()`, just like using
 `#[track_caller]` on a function.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cmp_minmax",
@@ -2759,6 +4147,9 @@ The tracking issue for this feature is: [#115939]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cmse_nonsecure_entry",
@@ -2779,10 +4170,10 @@ LLVM, the Rust compiler and the linker are providing
 TrustZone-M feature.
 
 One of the things provided, with this unstable feature, is the
-`cmse_nonsecure_entry` attribute.  This attribute marks a Secure function as an
+`C-cmse-nonsecure-entry` ABI. This ABI marks a Secure function as an
 entry function (see [section
 5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
-With this attribute, the compiler will do the following:
+With this ABI, the compiler will do the following:
 * add a special symbol on the function which is the `__acle_se_` prefix and the
   standard function name
 * constrain the number of parameters to avoid using the Non-Secure stack
@@ -2802,11 +4193,11 @@ gateway veneer.
 <!-- NOTE(ignore) this example is specific to thumbv8m targets -->
 
 ``` rust,ignore
+#![no_std]
 #![feature(cmse_nonsecure_entry)]
 
 #[no_mangle]
-#[cmse_nonsecure_entry]
-pub extern "C" fn entry_function(input: u32) -> u32 {
+pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
     input + 6
 }
 ```
@@ -2844,6 +4235,9 @@ $ arm-none-eabi-objdump -D function.o
   40:   defe            udf     #254    ; 0xfe
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "coerce_unsized",
@@ -2855,6 +4249,9 @@ The tracking issue for this feature is: [#18598]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "compiler_builtins",
@@ -2864,6 +4261,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "concat_bytes",
@@ -2875,6 +4275,9 @@ The tracking issue for this feature is: [#87555]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "concat_idents",
@@ -2901,39 +4304,9 @@ fn main() {
 }
 ```
 "##,
-    },
-    Lint {
-        label: "const_align_of_val",
-        description: r##"# `const_align_of_val`
-
-The tracking issue for this feature is: [#46571]
-
-[#46571]: https://github.com/rust-lang/rust/issues/46571
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_align_of_val_raw",
-        description: r##"# `const_align_of_val_raw`
-
-The tracking issue for this feature is: [#46571]
-
-[#46571]: https://github.com/rust-lang/rust/issues/46571
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_align_offset",
-        description: r##"# `const_align_offset`
-
-The tracking issue for this feature is: [#90962]
-
-[#90962]: https://github.com/rust-lang/rust/issues/90962
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_alloc_error",
@@ -2945,6 +4318,9 @@ The tracking issue for this feature is: [#92523]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_alloc_layout",
@@ -2956,39 +4332,37 @@ The tracking issue for this feature is: [#67521]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_arguments_as_str",
-        description: r##"# `const_arguments_as_str`
-
-The tracking issue for this feature is: [#103900]
-
-[#103900]: https://github.com/rust-lang/rust/issues/103900
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_array_from_ref",
-        description: r##"# `const_array_from_ref`
+        label: "const_array_as_mut_slice",
+        description: r##"# `const_array_as_mut_slice`
 
-The tracking issue for this feature is: [#90206]
+The tracking issue for this feature is: [#133333]
 
-[#90206]: https://github.com/rust-lang/rust/issues/90206
+[#133333]: https://github.com/rust-lang/rust/issues/133333
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_array_into_iter_constructors",
-        description: r##"# `const_array_into_iter_constructors`
+        label: "const_array_each_ref",
+        description: r##"# `const_array_each_ref`
 
-The tracking issue for this feature is: [#91583]
+The tracking issue for this feature is: [#133289]
 
-[#91583]: https://github.com/rust-lang/rust/issues/91583
+[#133289]: https://github.com/rust-lang/rust/issues/133289
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_async_blocks",
@@ -3000,39 +4374,9 @@ The tracking issue for this feature is: [#85368]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "const_atomic_from_ptr",
-        description: r##"# `const_atomic_from_ptr`
-
-The tracking issue for this feature is: [#108652]
-
-[#108652]: https://github.com/rust-lang/rust/issues/108652
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_bigint_helper_methods",
-        description: r##"# `const_bigint_helper_methods`
-
-The tracking issue for this feature is: [#85532]
-
-[#85532]: https://github.com/rust-lang/rust/issues/85532
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_binary_heap_new_in",
-        description: r##"# `const_binary_heap_new_in`
-
-The tracking issue for this feature is: [#112353]
-
-[#112353]: https://github.com/rust-lang/rust/issues/112353
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_black_box",
@@ -3042,6 +4386,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_box",
@@ -3053,6 +4400,9 @@ The tracking issue for this feature is: [#92521]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_btree_len",
@@ -3062,123 +4412,107 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_cell_into_inner",
-        description: r##"# `const_cell_into_inner`
-
-The tracking issue for this feature is: [#78729]
-
-[#78729]: https://github.com/rust-lang/rust/issues/78729
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_closures",
-        description: r##"# `const_closures`
-
-The tracking issue for this feature is: [#106003]
-
-[#106003]: https://github.com/rust-lang/rust/issues/106003
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_collections_with_hasher",
-        description: r##"# `const_collections_with_hasher`
+        label: "const_cell",
+        description: r##"# `const_cell`
 
-The tracking issue for this feature is: [#102575]
+The tracking issue for this feature is: [#131283]
 
-[#102575]: https://github.com/rust-lang/rust/issues/102575
+[#131283]: https://github.com/rust-lang/rust/issues/131283
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_cow_is_borrowed",
-        description: r##"# `const_cow_is_borrowed`
+        label: "const_char_classify",
+        description: r##"# `const_char_classify`
 
-The tracking issue for this feature is: [#65143]
+The tracking issue for this feature is: [#132241]
 
-[#65143]: https://github.com/rust-lang/rust/issues/65143
+[#132241]: https://github.com/rust-lang/rust/issues/132241
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_eval_select",
-        description: r##"# `const_eval_select`
-
-The tracking issue for this feature is: [#124625]
-
-[#124625]: https://github.com/rust-lang/rust/issues/124625
+        label: "const_closures",
+        description: r##"# `const_closures`
 
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_exact_div",
-        description: r##"# `const_exact_div`
+The tracking issue for this feature is: [#106003]
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+[#106003]: https://github.com/rust-lang/rust/issues/106003
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_extern_fn",
-        description: r##"# `const_extern_fn`
+        label: "const_copy_from_slice",
+        description: r##"# `const_copy_from_slice`
 
-The tracking issue for this feature is: [#64926]
+The tracking issue for this feature is: [#131415]
 
-[#64926]: https://github.com/rust-lang/rust/issues/64926
+[#131415]: https://github.com/rust-lang/rust/issues/131415
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_float_bits_conv",
-        description: r##"# `const_float_bits_conv`
+        label: "const_destruct",
+        description: r##"# `const_destruct`
 
-The tracking issue for this feature is: [#72447]
+The tracking issue for this feature is: [#133214]
 
-[#72447]: https://github.com/rust-lang/rust/issues/72447
+[#133214]: https://github.com/rust-lang/rust/issues/133214
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_float_classify",
-        description: r##"# `const_float_classify`
-
-The tracking issue for this feature is: [#72505]
-
-[#72505]: https://github.com/rust-lang/rust/issues/72505
+        label: "const_eq_ignore_ascii_case",
+        description: r##"# `const_eq_ignore_ascii_case`
 
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_fmt_arguments_new",
-        description: r##"# `const_fmt_arguments_new`
+The tracking issue for this feature is: [#131719]
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+[#131719]: https://github.com/rust-lang/rust/issues/131719
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_fn_floating_point_arithmetic",
-        description: r##"# `const_fn_floating_point_arithmetic`
+        label: "const_eval_select",
+        description: r##"# `const_eval_select`
 
-The tracking issue for this feature is: [#57241]
+The tracking issue for this feature is: [#124625]
 
-[#57241]: https://github.com/rust-lang/rust/issues/57241
+[#124625]: https://github.com/rust-lang/rust/issues/124625
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_for",
@@ -3190,6 +4524,9 @@ The tracking issue for this feature is: [#87575]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_format_args",
@@ -3199,17 +4536,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "const_hash",
-        description: r##"# `const_hash`
-
-The tracking issue for this feature is: [#104061]
-
-[#104061]: https://github.com/rust-lang/rust/issues/104061
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_heap",
@@ -3221,247 +4550,37 @@ The tracking issue for this feature is: [#79597]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_index_range_slice_index",
-        description: r##"# `const_index_range_slice_index`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_int_from_str",
-        description: r##"# `const_int_from_str`
-
-The tracking issue for this feature is: [#59133]
-
-[#59133]: https://github.com/rust-lang/rust/issues/59133
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_intoiterator_identity",
-        description: r##"# `const_intoiterator_identity`
-
-The tracking issue for this feature is: [#90603]
-
-[#90603]: https://github.com/rust-lang/rust/issues/90603
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_intrinsic_compare_bytes",
-        description: r##"# `const_intrinsic_compare_bytes`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_intrinsic_copy",
-        description: r##"# `const_intrinsic_copy`
-
-The tracking issue for this feature is: [#80697]
-
-[#80697]: https://github.com/rust-lang/rust/issues/80697
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_intrinsic_forget",
-        description: r##"# `const_intrinsic_forget`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_intrinsic_raw_eq",
-        description: r##"# `const_intrinsic_raw_eq`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_ip",
-        description: r##"# `const_ip`
-
-The tracking issue for this feature is: [#76205]
-
-[#76205]: https://github.com/rust-lang/rust/issues/76205
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_ipv4",
-        description: r##"# `const_ipv4`
-
-The tracking issue for this feature is: [#76205]
-
-[#76205]: https://github.com/rust-lang/rust/issues/76205
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_ipv6",
-        description: r##"# `const_ipv6`
-
-The tracking issue for this feature is: [#76205]
-
-[#76205]: https://github.com/rust-lang/rust/issues/76205
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_likely",
-        description: r##"# `const_likely`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_maybe_uninit_array_assume_init",
-        description: r##"# `const_maybe_uninit_array_assume_init`
-
-The tracking issue for this feature is: [#96097]
-
-[#96097]: https://github.com/rust-lang/rust/issues/96097
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_maybe_uninit_as_mut_ptr",
-        description: r##"# `const_maybe_uninit_as_mut_ptr`
-
-The tracking issue for this feature is: [#75251]
-
-[#75251]: https://github.com/rust-lang/rust/issues/75251
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_maybe_uninit_assume_init",
-        description: r##"# `const_maybe_uninit_assume_init`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_maybe_uninit_uninit_array",
-        description: r##"# `const_maybe_uninit_uninit_array`
-
-The tracking issue for this feature is: [#96097]
-
-[#96097]: https://github.com/rust-lang/rust/issues/96097
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_maybe_uninit_write",
-        description: r##"# `const_maybe_uninit_write`
-
-The tracking issue for this feature is: [#63567]
-
-[#63567]: https://github.com/rust-lang/rust/issues/63567
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_mut_refs",
-        description: r##"# `const_mut_refs`
-
-The tracking issue for this feature is: [#57349]
-
-[#57349]: https://github.com/rust-lang/rust/issues/57349
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_nonnull_new",
-        description: r##"# `const_nonnull_new`
-
-The tracking issue for this feature is: [#93235]
-
-[#93235]: https://github.com/rust-lang/rust/issues/93235
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_num_midpoint",
-        description: r##"# `const_num_midpoint`
-
-The tracking issue for this feature is: [#110840]
-
-[#110840]: https://github.com/rust-lang/rust/issues/110840
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_option",
-        description: r##"# `const_option`
-
-The tracking issue for this feature is: [#67441]
-
-[#67441]: https://github.com/rust-lang/rust/issues/67441
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_option_ext",
-        description: r##"# `const_option_ext`
-
-The tracking issue for this feature is: [#91930]
-
-[#91930]: https://github.com/rust-lang/rust/issues/91930
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_pin",
-        description: r##"# `const_pin`
+        label: "const_is_char_boundary",
+        description: r##"# `const_is_char_boundary`
 
-The tracking issue for this feature is: [#76654]
+The tracking issue for this feature is: [#131516]
 
-[#76654]: https://github.com/rust-lang/rust/issues/76654
+[#131516]: https://github.com/rust-lang/rust/issues/131516
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_pointer_is_aligned",
-        description: r##"# `const_pointer_is_aligned`
+        label: "const_mut_cursor",
+        description: r##"# `const_mut_cursor`
 
-The tracking issue for this feature is: [#104203]
+The tracking issue for this feature is: [#130801]
 
-[#104203]: https://github.com/rust-lang/rust/issues/104203
+[#130801]: https://github.com/rust-lang/rust/issues/130801
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_precise_live_drops",
@@ -3473,39 +4592,9 @@ The tracking issue for this feature is: [#73255]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "const_pref_align_of",
-        description: r##"# `const_pref_align_of`
-
-The tracking issue for this feature is: [#91971]
-
-[#91971]: https://github.com/rust-lang/rust/issues/91971
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_ptr_as_ref",
-        description: r##"# `const_ptr_as_ref`
-
-The tracking issue for this feature is: [#91822]
-
-[#91822]: https://github.com/rust-lang/rust/issues/91822
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_ptr_is_null",
-        description: r##"# `const_ptr_is_null`
-
-The tracking issue for this feature is: [#74939]
-
-[#74939]: https://github.com/rust-lang/rust/issues/74939
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_ptr_sub_ptr",
@@ -3517,17 +4606,9 @@ The tracking issue for this feature is: [#95892]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "const_ptr_write",
-        description: r##"# `const_ptr_write`
-
-The tracking issue for this feature is: [#86302]
-
-[#86302]: https://github.com/rust-lang/rust/issues/86302
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_range_bounds",
@@ -3539,6 +4620,9 @@ The tracking issue for this feature is: [#108082]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_raw_ptr_comparison",
@@ -3550,94 +4634,9 @@ The tracking issue for this feature is: [#53020]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "const_refs_to_cell",
-        description: r##"# `const_refs_to_cell`
-
-The tracking issue for this feature is: [#80384]
-
-[#80384]: https://github.com/rust-lang/rust/issues/80384
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_refs_to_static",
-        description: r##"# `const_refs_to_static`
-
-The tracking issue for this feature is: [#119618]
-
-[#119618]: https://github.com/rust-lang/rust/issues/119618
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_replace",
-        description: r##"# `const_replace`
-
-The tracking issue for this feature is: [#83164]
-
-[#83164]: https://github.com/rust-lang/rust/issues/83164
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_result",
-        description: r##"# `const_result`
-
-The tracking issue for this feature is: [#82814]
-
-[#82814]: https://github.com/rust-lang/rust/issues/82814
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_size_of_val",
-        description: r##"# `const_size_of_val`
-
-The tracking issue for this feature is: [#46571]
-
-[#46571]: https://github.com/rust-lang/rust/issues/46571
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_size_of_val_raw",
-        description: r##"# `const_size_of_val_raw`
-
-The tracking issue for this feature is: [#46571]
-
-[#46571]: https://github.com/rust-lang/rust/issues/46571
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_slice_first_last",
-        description: r##"# `const_slice_first_last`
-
-The tracking issue for this feature is: [#83570]
-
-[#83570]: https://github.com/rust-lang/rust/issues/83570
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_slice_first_last_chunk",
-        description: r##"# `const_slice_first_last_chunk`
-
-The tracking issue for this feature is: [#111774]
-
-[#111774]: https://github.com/rust-lang/rust/issues/111774
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_slice_flatten",
@@ -3649,6 +4648,9 @@ The tracking issue for this feature is: [#95629]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_slice_from_mut_ptr_range",
@@ -3660,6 +4662,9 @@ The tracking issue for this feature is: [#89792]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_slice_from_ptr_range",
@@ -3671,59 +4676,23 @@ The tracking issue for this feature is: [#89792]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_slice_from_raw_parts_mut",
-        description: r##"# `const_slice_from_raw_parts_mut`
+        label: "const_sockaddr_setters",
+        description: r##"# `const_sockaddr_setters`
 
-The tracking issue for this feature is: [#67456]
+The tracking issue for this feature is: [#131714]
 
-[#67456]: https://github.com/rust-lang/rust/issues/67456
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_slice_from_ref",
-        description: r##"# `const_slice_from_ref`
-
-The tracking issue for this feature is: [#90206]
-
-[#90206]: https://github.com/rust-lang/rust/issues/90206
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_slice_index",
-        description: r##"# `const_slice_index`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_slice_split_at_mut",
-        description: r##"# `const_slice_split_at_mut`
-
-The tracking issue for this feature is: [#101804]
-
-[#101804]: https://github.com/rust-lang/rust/issues/101804
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_str_from_raw_parts_mut",
-        description: r##"# `const_str_from_raw_parts_mut`
-
-The tracking issue for this feature is: [#119206]
-
-[#119206]: https://github.com/rust-lang/rust/issues/119206
+[#131714]: https://github.com/rust-lang/rust/issues/131714
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_str_from_utf8",
@@ -3735,28 +4704,23 @@ The tracking issue for this feature is: [#91006]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_str_from_utf8_unchecked_mut",
-        description: r##"# `const_str_from_utf8_unchecked_mut`
+        label: "const_str_split_at",
+        description: r##"# `const_str_split_at`
 
-The tracking issue for this feature is: [#91005]
+The tracking issue for this feature is: [#131518]
 
-[#91005]: https://github.com/rust-lang/rust/issues/91005
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_strict_overflow_ops",
-        description: r##"# `const_strict_overflow_ops`
-
-The tracking issue for this feature is: [#118260]
-
-[#118260]: https://github.com/rust-lang/rust/issues/118260
+[#131518]: https://github.com/rust-lang/rust/issues/131518
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_swap",
@@ -3768,15 +4732,23 @@ The tracking issue for this feature is: [#83163]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_three_way_compare",
-        description: r##"# `const_three_way_compare`
+        label: "const_swap_nonoverlapping",
+        description: r##"# `const_swap_nonoverlapping`
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+The tracking issue for this feature is: [#133668]
+
+[#133668]: https://github.com/rust-lang/rust/issues/133668
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_trait_impl",
@@ -3788,6 +4760,9 @@ The tracking issue for this feature is: [#67792]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_try",
@@ -3799,6 +4774,9 @@ The tracking issue for this feature is: [#74935]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_type_id",
@@ -3810,6 +4788,9 @@ The tracking issue for this feature is: [#77125]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_type_name",
@@ -3821,6 +4802,9 @@ The tracking issue for this feature is: [#63084]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "const_typed_swap",
@@ -3830,48 +4814,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "const_ub_checks",
-        description: r##"# `const_ub_checks`
+        label: "const_vec_string_slice",
+        description: r##"# `const_vec_string_slice`
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+The tracking issue for this feature is: [#129041]
 
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_unicode_case_lookup",
-        description: r##"# `const_unicode_case_lookup`
-
-The tracking issue for this feature is: [#101400]
-
-[#101400]: https://github.com/rust-lang/rust/issues/101400
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_unsafecell_get_mut",
-        description: r##"# `const_unsafecell_get_mut`
-
-The tracking issue for this feature is: [#88836]
-
-[#88836]: https://github.com/rust-lang/rust/issues/88836
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "const_waker",
-        description: r##"# `const_waker`
-
-The tracking issue for this feature is: [#102012]
-
-[#102012]: https://github.com/rust-lang/rust/issues/102012
+[#129041]: https://github.com/rust-lang/rust/issues/129041
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "container_error_extra",
@@ -3881,6 +4840,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "context_ext",
@@ -3892,17 +4854,9 @@ The tracking issue for this feature is: [#123392]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "control_flow_enum",
-        description: r##"# `control_flow_enum`
-
-The tracking issue for this feature is: [#75744]
-
-[#75744]: https://github.com/rust-lang/rust/issues/75744
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "convert_float_to_int",
@@ -3914,6 +4868,9 @@ The tracking issue for this feature is: [#67057]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "core_intrinsics",
@@ -3923,6 +4880,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "core_io_borrowed_buf",
@@ -3934,15 +4894,9 @@ The tracking issue for this feature is: [#117693]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "pattern_type_macro",
-        description: r##"# `pattern_type_macro`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "core_private_bignum",
@@ -3952,6 +4906,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "core_private_diy_float",
@@ -3961,6 +4918,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "coroutine_clone",
@@ -3972,6 +4932,9 @@ The tracking issue for this feature is: [#95360]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "coroutine_trait",
@@ -3983,6 +4946,9 @@ The tracking issue for this feature is: [#43122]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "coroutines",
@@ -4234,6 +5200,9 @@ it's invalid to resume a completed coroutine. It's also worth noting that this
 is just a rough desugaring, not a normative specification for what the compiler
 does.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "coverage_attribute",
@@ -4268,6 +5237,9 @@ fn bar() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cow_is_borrowed",
@@ -4279,6 +5251,9 @@ The tracking issue for this feature is: [#65143]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "csky_target_feature",
@@ -4290,6 +5265,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cstr_bytes",
@@ -4301,6 +5279,9 @@ The tracking issue for this feature is: [#112115]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "cstr_internals",
@@ -4310,10 +5291,13 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "cursor_remaining",
-        description: r##"# `cursor_remaining`
+        label: "cursor_split",
+        description: r##"# `cursor_split`
 
 The tracking issue for this feature is: [#86369]
 
@@ -4321,6 +5305,9 @@ The tracking issue for this feature is: [#86369]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "custom_inner_attributes",
@@ -4332,6 +5319,9 @@ The tracking issue for this feature is: [#54726]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "custom_mir",
@@ -4341,6 +5331,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "custom_test_frameworks",
@@ -4377,6 +5370,9 @@ const WILL_PASS: i32 = 0;
 const WILL_FAIL: i32 = 4;
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deadline_api",
@@ -4388,6 +5384,9 @@ The tracking issue for this feature is: [#46316]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "debug_closure_helpers",
@@ -4399,6 +5398,9 @@ The tracking issue for this feature is: [#117729]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "dec2flt",
@@ -4408,6 +5410,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "decl_macro",
@@ -4419,17 +5424,23 @@ The tracking issue for this feature is: [#39412]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "default_type_parameter_fallback",
-        description: r##"# `default_type_parameter_fallback`
+        label: "default_field_values",
+        description: r##"# `default_field_values`
 
-The tracking issue for this feature is: [#27336]
+The tracking issue for this feature is: [#132162]
 
-[#27336]: https://github.com/rust-lang/rust/issues/27336
+[#132162]: https://github.com/rust-lang/rust/issues/132162
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deprecated_safe",
@@ -4441,6 +5452,9 @@ The tracking issue for this feature is: [#94978]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deprecated_suggestion",
@@ -4452,6 +5466,9 @@ The tracking issue for this feature is: [#94785]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deref_patterns",
@@ -4463,6 +5480,9 @@ The tracking issue for this feature is: [#87121]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "deref_pure_trait",
@@ -4474,6 +5494,9 @@ The tracking issue for this feature is: [#87121]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "derive_clone_copy",
@@ -4483,35 +5506,47 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "derive_const",
-        description: r##"# `derive_const`
+        label: "derive_coerce_pointee",
+        description: r##"# `derive_coerce_pointee`
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+The tracking issue for this feature is: [#123430]
+
+[#123430]: https://github.com/rust-lang/rust/issues/123430
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "derive_eq",
-        description: r##"# `derive_eq`
+        label: "derive_const",
+        description: r##"# `derive_const`
 
-This feature is internal to the Rust compiler and is not intended for general use.
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "derive_smart_pointer",
-        description: r##"# `derive_smart_pointer`
-
-The tracking issue for this feature is: [#123430]
+        label: "derive_eq",
+        description: r##"# `derive_eq`
 
-[#123430]: https://github.com/rust-lang/rust/issues/123430
+This feature is internal to the Rust compiler and is not intended for general use.
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "dir_entry_ext2",
@@ -4523,6 +5558,9 @@ The tracking issue for this feature is: [#85573]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "discriminant_kind",
@@ -4532,6 +5570,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "dispatch_from_dyn",
@@ -4541,6 +5582,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "do_not_recommend",
@@ -4552,6 +5596,9 @@ The tracking issue for this feature is: [#51992]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "doc_auto_cfg",
@@ -4563,6 +5610,9 @@ The tracking issue for this feature is: [#43781]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "doc_cfg",
@@ -4613,6 +5663,9 @@ pub struct Icon {
 [#43781]: https://github.com/rust-lang/rust/issues/43781
 [#43348]: https://github.com/rust-lang/rust/issues/43348
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "doc_cfg_hide",
@@ -4624,6 +5677,9 @@ The tracking issue for this feature is: [#43781]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "doc_masked",
@@ -4652,6 +5708,9 @@ Such types would introduce broken links into the documentation.
 [#44026]: https://github.com/rust-lang/rust/pull/44026
 [#44027]: https://github.com/rust-lang/rust/pull/44027
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "doc_notable_trait",
@@ -4689,6 +5748,9 @@ See also its documentation in [the rustdoc book][rustdoc-book-notable_trait].
 [#45039]: https://github.com/rust-lang/rust/pull/45039
 [rustdoc-book-notable_trait]: ../../rustdoc/unstable-features.html#adding-your-trait-to-the-notable-traits-dialog
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "downcast_unchecked",
@@ -4700,6 +5762,9 @@ The tracking issue for this feature is: [#90850]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "drain_keep_rest",
@@ -4711,6 +5776,9 @@ The tracking issue for this feature is: [#101122]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "dropck_eyepatch",
@@ -4722,6 +5790,9 @@ The tracking issue for this feature is: [#34761]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "duration_constants",
@@ -4733,6 +5804,9 @@ The tracking issue for this feature is: [#57391]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "duration_constructors",
@@ -4746,17 +5820,9 @@ The tracking issue for this feature is: [#120301]
 
 Add the methods `from_mins`, `from_hours` and `from_days` to `Duration`.
 "##,
-    },
-    Lint {
-        label: "duration_consts_float",
-        description: r##"# `duration_consts_float`
-
-The tracking issue for this feature is: [#72440]
-
-[#72440]: https://github.com/rust-lang/rust/issues/72440
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "duration_millis_float",
@@ -4768,6 +5834,9 @@ The tracking issue for this feature is: [#122451]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "duration_units",
@@ -4779,57 +5848,49 @@ The tracking issue for this feature is: [#120301]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "dyn_star",
-        description: r##"# `dyn_star`
-
-The tracking issue for this feature is: [#102425]
-
-[#102425]: https://github.com/rust-lang/rust/issues/102425
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "edition_panic",
-        description: r##"# `edition_panic`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+        label: "dyn_compatible_for_dispatch",
+        description: r##"# `dyn_compatible_for_dispatch`
 
-------------------------
-"##,
-    },
-    Lint {
-        label: "effect_types",
-        description: r##"# `effect_types`
+The tracking issue for this feature is: [#43561]
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+[#43561]: https://github.com/rust-lang/rust/issues/43561
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "effects",
-        description: r##"# `effects`
+        label: "dyn_star",
+        description: r##"# `dyn_star`
 
-The tracking issue for this feature is: [#102090]
+The tracking issue for this feature is: [#102425]
 
-[#102090]: https://github.com/rust-lang/rust/issues/102090
+[#102425]: https://github.com/rust-lang/rust/issues/102425
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "entry_insert",
-        description: r##"# `entry_insert`
-
-The tracking issue for this feature is: [#65225]
+        label: "edition_panic",
+        description: r##"# `edition_panic`
 
-[#65225]: https://github.com/rust-lang/rust/issues/65225
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ermsb_target_feature",
@@ -4841,6 +5902,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "error_generic_member_access",
@@ -4852,6 +5916,9 @@ The tracking issue for this feature is: [#99301]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "error_iter",
@@ -4863,6 +5930,9 @@ The tracking issue for this feature is: [#58520]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "error_reporter",
@@ -4874,6 +5944,9 @@ The tracking issue for this feature is: [#90172]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "error_type_id",
@@ -4885,6 +5958,9 @@ The tracking issue for this feature is: [#60784]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "exact_size_is_empty",
@@ -4896,6 +5972,9 @@ The tracking issue for this feature is: [#35428]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "exclusive_wrapper",
@@ -4907,6 +5986,9 @@ The tracking issue for this feature is: [#98407]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "exhaustive_patterns",
@@ -4918,6 +6000,9 @@ The tracking issue for this feature is: [#51085]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "exit_status_error",
@@ -4929,6 +6014,9 @@ The tracking issue for this feature is: [#84908]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "exitcode_exit_method",
@@ -4940,6 +6028,9 @@ The tracking issue for this feature is: [#97100]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "explicit_tail_calls",
@@ -4951,28 +6042,9 @@ The tracking issue for this feature is: [#112788]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "exposed_provenance",
-        description: r##"# `exposed_provenance`
-
-The tracking issue for this feature is: [#95228]
-
-[#95228]: https://github.com/rust-lang/rust/issues/95228
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "expr_fragment_specifier_2024",
-        description: r##"# `expr_fragment_specifier_2024`
-
-The tracking issue for this feature is: [#123742]
-
-[#123742]: https://github.com/rust-lang/rust/issues/123742
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "extend_one",
@@ -4984,6 +6056,9 @@ The tracking issue for this feature is: [#72631]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "extend_one_unchecked",
@@ -4993,20 +6068,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "extended_varargs_abi_support",
-        description: r##"# `extended_varargs_abi_support`
-
-The tracking issue for this feature is: [#100189]
-
-[#100189]: https://github.com/rust-lang/rust/issues/100189
-
-------------------------
-
-This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling
-conventions on functions with varargs.
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "extern_types",
@@ -5018,6 +6082,9 @@ The tracking issue for this feature is: [#43467]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "extract_if",
@@ -5029,6 +6096,9 @@ The tracking issue for this feature is: [#43244]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "f128",
@@ -5042,6 +6112,9 @@ The tracking issue for this feature is: [#116909]
 
 Enable the `f128` type for  IEEE 128-bit floating numbers (quad precision).
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "f16",
@@ -5055,6 +6128,9 @@ The tracking issue for this feature is: [#116909]
 
 Enable the `f16` type for  IEEE 16-bit floating numbers (half precision).
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fd",
@@ -5064,6 +6140,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fd_read",
@@ -5073,6 +6152,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ffi_const",
@@ -5129,6 +6211,9 @@ against are compatible with those of the `#[ffi_const]`.
 [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
 [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ffi_pure",
@@ -5189,6 +6274,37 @@ against are compatible with those of the `#[ffi_pure]`.
 [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
 [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "file_buffered",
+        description: r##"# `file_buffered`
+
+The tracking issue for this feature is: [#130804]
+
+[#130804]: https://github.com/rust-lang/rust/issues/130804
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "file_lock",
+        description: r##"# `file_lock`
+
+The tracking issue for this feature is: [#130994]
+
+[#130994]: https://github.com/rust-lang/rust/issues/130994
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "float_gamma",
@@ -5200,6 +6316,9 @@ The tracking issue for this feature is: [#99842]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "float_minimum_maximum",
@@ -5211,6 +6330,9 @@ The tracking issue for this feature is: [#91079]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "float_next_up_down",
@@ -5222,6 +6344,9 @@ The tracking issue for this feature is: [#91399]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "flt2dec",
@@ -5231,6 +6356,23 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "fmt_debug",
+        description: r##"# `fmt_debug`
+
+The tracking issue for this feature is: [#129709]
+
+[#129709]: https://github.com/rust-lang/rust/issues/129709
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fmt_helpers_for_derive",
@@ -5240,6 +6382,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fmt_internals",
@@ -5249,6 +6394,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fn_align",
@@ -5260,6 +6408,9 @@ The tracking issue for this feature is: [#82232]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fn_delegation",
@@ -5271,6 +6422,9 @@ The tracking issue for this feature is: [#118212]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fn_ptr_trait",
@@ -5280,6 +6434,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fn_traits",
@@ -5319,6 +6476,9 @@ fn main() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "forget_unsized",
@@ -5328,6 +6488,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "format_args_nl",
@@ -5337,6 +6500,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "formatting_options",
+        description: r##"# `formatting_options`
+
+The tracking issue for this feature is: [#118117]
+
+[#118117]: https://github.com/rust-lang/rust/issues/118117
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "freeze",
@@ -5348,6 +6528,9 @@ The tracking issue for this feature is: [#121675]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "freeze_impls",
@@ -5359,6 +6542,9 @@ The tracking issue for this feature is: [#121675]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "fundamental",
@@ -5370,6 +6556,9 @@ The tracking issue for this feature is: [#29635]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "future_join",
@@ -5381,6 +6570,9 @@ The tracking issue for this feature is: [#91642]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "gen_blocks",
@@ -5392,6 +6584,9 @@ The tracking issue for this feature is: [#117078]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "gen_future",
@@ -5403,6 +6598,9 @@ The tracking issue for this feature is: [#50547]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "generic_arg_infer",
@@ -5414,6 +6612,9 @@ The tracking issue for this feature is: [#85077]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "generic_assert",
@@ -5423,6 +6624,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "generic_assert_internals",
@@ -5434,17 +6638,9 @@ The tracking issue for this feature is: [#44838]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "generic_associated_types_extended",
-        description: r##"# `generic_associated_types_extended`
-
-The tracking issue for this feature is: [#95451]
-
-[#95451]: https://github.com/rust-lang/rust/issues/95451
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "generic_const_exprs",
@@ -5456,6 +6652,9 @@ The tracking issue for this feature is: [#76560]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "generic_const_items",
@@ -5467,6 +6666,9 @@ The tracking issue for this feature is: [#113521]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "get_many_mut",
@@ -5478,6 +6680,21 @@ The tracking issue for this feature is: [#104642]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "get_many_mut_helpers",
+        description: r##"# `get_many_mut_helpers`
+
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "get_mut_unchecked",
@@ -5489,6 +6706,9 @@ The tracking issue for this feature is: [#63292]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "global_registration",
@@ -5500,6 +6720,23 @@ The tracking issue for this feature is: [#125119]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "guard_patterns",
+        description: r##"# `guard_patterns`
+
+The tracking issue for this feature is: [#129967]
+
+[#129967]: https://github.com/rust-lang/rust/issues/129967
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "half_open_range_patterns_in_slices",
@@ -5533,6 +6770,9 @@ fn main() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hash_extract_if",
@@ -5544,6 +6784,9 @@ The tracking issue for this feature is: [#59618]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hash_raw_entry",
@@ -5555,6 +6798,9 @@ The tracking issue for this feature is: [#56167]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hash_set_entry",
@@ -5566,6 +6812,9 @@ The tracking issue for this feature is: [#60896]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hasher_prefixfree_extras",
@@ -5577,6 +6826,9 @@ The tracking issue for this feature is: [#96762]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hashmap_internals",
@@ -5586,6 +6838,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hexagon_target_feature",
@@ -5597,6 +6852,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "hint_must_use",
@@ -5608,6 +6866,9 @@ The tracking issue for this feature is: [#94745]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "if_let_guard",
@@ -5619,6 +6880,9 @@ The tracking issue for this feature is: [#51114]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "impl_trait_in_assoc_type",
@@ -5630,6 +6894,9 @@ The tracking issue for this feature is: [#63063]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "impl_trait_in_fn_trait_return",
@@ -5641,6 +6908,9 @@ The tracking issue for this feature is: [#99697]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "inherent_associated_types",
@@ -5652,6 +6922,9 @@ The tracking issue for this feature is: [#8995]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "inline_const_pat",
@@ -5678,6 +6951,9 @@ match some_int {
 
 [#76001]: https://github.com/rust-lang/rust/issues/76001
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "inplace_iteration",
@@ -5687,6 +6963,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "int_roundings",
@@ -5698,6 +6977,9 @@ The tracking issue for this feature is: [#88581]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "integer_atomics",
@@ -5709,6 +6991,9 @@ The tracking issue for this feature is: [#99069]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "integer_sign_cast",
@@ -5720,6 +7005,9 @@ The tracking issue for this feature is: [#125882]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "internal_impls_macro",
@@ -5729,6 +7017,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "internal_output_capture",
@@ -5738,6 +7029,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "intra_doc_pointers",
@@ -5757,6 +7051,9 @@ raw pointers in intra-doc links are unstable until it does.
 //! [pointer::add]
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "intrinsics",
@@ -5780,7 +7077,7 @@ All intrinsic fallback bodies are automatically made cross-crate inlineable (lik
 by the codegen backend, but not the MIR inliner.
 
 ```rust
-#![feature(rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
 #[rustc_intrinsic]
@@ -5790,7 +7087,7 @@ const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
 Since these are just regular functions, it is perfectly ok to create the intrinsic twice:
 
 ```rust
-#![feature(rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
 #[rustc_intrinsic]
@@ -5852,105 +7149,159 @@ extern "rust-intrinsic" {
 As with any other FFI functions, these are by default always `unsafe` to call.
 You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "io_error_more",
-        description: r##"# `io_error_more`
+        label: "io_const_error",
+        description: r##"# `io_const_error`
 
-The tracking issue for this feature is: [#86442]
+The tracking issue for this feature is: [#133448]
 
-[#86442]: https://github.com/rust-lang/rust/issues/86442
+[#133448]: https://github.com/rust-lang/rust/issues/133448
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "io_error_uncategorized",
-        description: r##"# `io_error_uncategorized`
+        label: "io_const_error_internals",
+        description: r##"# `io_const_error_internals`
 
 This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "ip",
-        description: r##"# `ip`
+        label: "io_error_inprogress",
+        description: r##"# `io_error_inprogress`
 
-The tracking issue for this feature is: [#27709]
+The tracking issue for this feature is: [#130840]
 
-[#27709]: https://github.com/rust-lang/rust/issues/27709
+[#130840]: https://github.com/rust-lang/rust/issues/130840
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "is_ascii_octdigit",
-        description: r##"# `is_ascii_octdigit`
+        label: "io_error_more",
+        description: r##"# `io_error_more`
 
-The tracking issue for this feature is: [#101288]
+The tracking issue for this feature is: [#86442]
 
-[#101288]: https://github.com/rust-lang/rust/issues/101288
+[#86442]: https://github.com/rust-lang/rust/issues/86442
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "is_none_or",
-        description: r##"# `is_none_or`
+        label: "io_error_uncategorized",
+        description: r##"# `io_error_uncategorized`
 
-The tracking issue for this feature is: [#126383]
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
 
-[#126383]: https://github.com/rust-lang/rust/issues/126383
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "io_slice_as_bytes",
+        description: r##"# `io_slice_as_bytes`
+
+The tracking issue for this feature is: [#132818]
+
+[#132818]: https://github.com/rust-lang/rust/issues/132818
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "is_riscv_feature_detected",
-        description: r##"# `is_riscv_feature_detected`
+        label: "ip",
+        description: r##"# `ip`
 
-The tracking issue for this feature is: [#111192]
+The tracking issue for this feature is: [#27709]
 
-[#111192]: https://github.com/rust-lang/rust/issues/111192
+[#27709]: https://github.com/rust-lang/rust/issues/27709
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "is_sorted",
-        description: r##"# `is_sorted`
+        label: "ip_from",
+        description: r##"# `ip_from`
 
-The tracking issue for this feature is: [#53485]
+The tracking issue for this feature is: [#131360]
 
-[#53485]: https://github.com/rust-lang/rust/issues/53485
+[#131360]: https://github.com/rust-lang/rust/issues/131360
 
 ------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "is_ascii_octdigit",
+        description: r##"# `is_ascii_octdigit`
+
+The tracking issue for this feature is: [#101288]
+
+[#101288]: https://github.com/rust-lang/rust/issues/101288
 
-Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`;
-add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to
-`Iterator`.
+------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "is_val_statically_known",
-        description: r##"# `is_val_statically_known`
+        label: "is_loongarch_feature_detected",
+        description: r##"# `is_loongarch_feature_detected`
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+The tracking issue for this feature is: [#117425]
+
+[#117425]: https://github.com/rust-lang/rust/issues/117425
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "isqrt",
-        description: r##"# `isqrt`
+        label: "is_riscv_feature_detected",
+        description: r##"# `is_riscv_feature_detected`
 
-The tracking issue for this feature is: [#116226]
+The tracking issue for this feature is: [#111192]
 
-[#116226]: https://github.com/rust-lang/rust/issues/116226
+[#111192]: https://github.com/rust-lang/rust/issues/111192
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_advance_by",
@@ -5962,6 +7313,9 @@ The tracking issue for this feature is: [#77404]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_array_chunks",
@@ -5973,6 +7327,9 @@ The tracking issue for this feature is: [#100450]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_chain",
@@ -5984,6 +7341,9 @@ The tracking issue for this feature is: [#125964]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_collect_into",
@@ -5995,6 +7355,9 @@ The tracking issue for this feature is: [#94780]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_from_coroutine",
@@ -6006,6 +7369,9 @@ The tracking issue for this feature is: [#43122]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_intersperse",
@@ -6017,6 +7383,9 @@ The tracking issue for this feature is: [#79524]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_is_partitioned",
@@ -6028,6 +7397,9 @@ The tracking issue for this feature is: [#62544]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_map_windows",
@@ -6039,6 +7411,9 @@ The tracking issue for this feature is: [#87155]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_next_chunk",
@@ -6050,6 +7425,9 @@ The tracking issue for this feature is: [#98326]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_order_by",
@@ -6061,6 +7439,9 @@ The tracking issue for this feature is: [#64295]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iter_partition_in_place",
@@ -6072,17 +7453,9 @@ The tracking issue for this feature is: [#62543]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "iter_repeat_n",
-        description: r##"# `iter_repeat_n`
-
-The tracking issue for this feature is: [#104434]
-
-[#104434]: https://github.com/rust-lang/rust/issues/104434
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iterator_try_collect",
@@ -6094,6 +7467,9 @@ The tracking issue for this feature is: [#94047]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "iterator_try_reduce",
@@ -6105,6 +7481,9 @@ The tracking issue for this feature is: [#87053]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "junction_point",
@@ -6116,6 +7495,9 @@ The tracking issue for this feature is: [#121709]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "lahfsahf_target_feature",
@@ -6127,6 +7509,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "lang_items",
@@ -6246,6 +7631,9 @@ An up-to-date list of all language items can be found [here] in the compiler cod
 
 [here]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "large_assignments",
@@ -6257,6 +7645,9 @@ The tracking issue for this feature is: [#83518]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "layout_for_ptr",
@@ -6268,6 +7659,9 @@ The tracking issue for this feature is: [#69835]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "lazy_cell_into_inner",
@@ -6279,6 +7673,23 @@ The tracking issue for this feature is: [#125623]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "lazy_get",
+        description: r##"# `lazy_get`
+
+The tracking issue for this feature is: [#129333]
+
+[#129333]: https://github.com/rust-lang/rust/issues/129333
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "lazy_type_alias",
@@ -6290,6 +7701,21 @@ The tracking issue for this feature is: [#112792]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "legacy_receiver_trait",
+        description: r##"# `legacy_receiver_trait`
+
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "let_chains",
@@ -6301,6 +7727,9 @@ The tracking issue for this feature is: [#53667]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "liballoc_internals",
@@ -6310,6 +7739,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "libstd_sys_internals",
@@ -6319,6 +7751,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "lifetime_capture_rules_2024",
@@ -6328,6 +7763,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "link_arg_attribute",
@@ -6353,6 +7791,9 @@ extern "C" {}
 
 [#99427]: https://github.com/rust-lang/rust/issues/99427
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "link_cfg",
@@ -6362,6 +7803,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "link_llvm_intrinsics",
@@ -6373,6 +7817,9 @@ The tracking issue for this feature is: [#29602]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "linkage",
@@ -6384,6 +7831,9 @@ The tracking issue for this feature is: [#29603]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "linked_list_cursors",
@@ -6395,6 +7845,9 @@ The tracking issue for this feature is: [#58533]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "linked_list_remove",
@@ -6406,6 +7859,9 @@ The tracking issue for this feature is: [#69210]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "linked_list_retain",
@@ -6417,6 +7873,9 @@ The tracking issue for this feature is: [#114135]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "linux_pidfd",
@@ -6428,6 +7887,9 @@ The tracking issue for this feature is: [#82971]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "local_waker",
@@ -6439,6 +7901,9 @@ The tracking issue for this feature is: [#118959]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "log_syntax",
@@ -6450,6 +7915,9 @@ The tracking issue for this feature is: [#29598]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "loongarch_target_feature",
@@ -6461,6 +7929,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "macro_metavar_expr",
@@ -6472,6 +7943,9 @@ The tracking issue for this feature is: [#83527]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "macro_metavar_expr_concat",
@@ -6483,17 +7957,9 @@ The tracking issue for this feature is: [#124225]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "map_entry_replace",
-        description: r##"# `map_entry_replace`
-
-The tracking issue for this feature is: [#44286]
-
-[#44286]: https://github.com/rust-lang/rust/issues/44286
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "map_many_mut",
@@ -6505,6 +7971,9 @@ The tracking issue for this feature is: [#97601]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "map_try_insert",
@@ -6516,6 +7985,9 @@ The tracking issue for this feature is: [#82766]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "mapped_lock_guards",
@@ -6527,6 +7999,9 @@ The tracking issue for this feature is: [#117108]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "marker_trait_attr",
@@ -6566,6 +8041,9 @@ fn cheap_clone<T: CheapToClone>(t: T) -> T {
 This is expected to replace the unstable `overlapping_marker_traits`
 feature, which applied to all empty traits (without needing an opt-in).
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "maybe_uninit_array_assume_init",
@@ -6577,6 +8055,9 @@ The tracking issue for this feature is: [#96097]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "maybe_uninit_as_bytes",
@@ -6588,6 +8069,9 @@ The tracking issue for this feature is: [#93092]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "maybe_uninit_fill",
@@ -6599,6 +8083,9 @@ The tracking issue for this feature is: [#117428]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "maybe_uninit_slice",
@@ -6610,6 +8097,9 @@ The tracking issue for this feature is: [#63569]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "maybe_uninit_uninit_array",
@@ -6621,6 +8111,9 @@ The tracking issue for this feature is: [#96097]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "maybe_uninit_uninit_array_transpose",
@@ -6632,6 +8125,9 @@ The tracking issue for this feature is: [#96097]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "maybe_uninit_write_slice",
@@ -6643,6 +8139,9 @@ The tracking issue for this feature is: [#79995]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "mem_copy_fn",
@@ -6654,17 +8153,23 @@ The tracking issue for this feature is: [#98262]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "min_exhaustive_patterns",
-        description: r##"# `min_exhaustive_patterns`
+        label: "min_generic_const_args",
+        description: r##"# `min_generic_const_args`
 
-The tracking issue for this feature is: [#119612]
+The tracking issue for this feature is: [#132980]
 
-[#119612]: https://github.com/rust-lang/rust/issues/119612
+[#132980]: https://github.com/rust-lang/rust/issues/132980
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "min_specialization",
@@ -6676,6 +8181,9 @@ The tracking issue for this feature is: [#31844]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "mips_target_feature",
@@ -6687,6 +8195,23 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "mixed_integer_ops_unsigned_sub",
+        description: r##"# `mixed_integer_ops_unsigned_sub`
+
+The tracking issue for this feature is: [#126043]
+
+[#126043]: https://github.com/rust-lang/rust/issues/126043
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "more_float_constants",
@@ -6698,6 +8223,21 @@ The tracking issue for this feature is: [#103883]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "more_maybe_bounds",
+        description: r##"# `more_maybe_bounds`
+
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "more_qualified_paths",
@@ -6706,6 +8246,10 @@ The tracking issue for this feature is: [#103883]
 The `more_qualified_paths` feature can be used in order to enable the
 use of qualified paths in patterns.
 
+The tracking issue for this feature is: [#86935](https://github.com/rust-lang/rust/issues/86935).
+
+------------------------
+
 ## Example
 
 ```rust
@@ -6731,6 +8275,23 @@ impl A for Foo {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "mpmc_channel",
+        description: r##"# `mpmc_channel`
+
+The tracking issue for this feature is: [#126840]
+
+[#126840]: https://github.com/rust-lang/rust/issues/126840
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "multiple_supertrait_upcastable",
@@ -6740,6 +8301,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "must_not_suspend",
@@ -6751,6 +8315,9 @@ The tracking issue for this feature is: [#83310]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "mut_ref",
@@ -6762,6 +8329,9 @@ The tracking issue for this feature is: [#123076]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "naked_functions",
@@ -6773,6 +8343,9 @@ The tracking issue for this feature is: [#90957]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "native_link_modifiers_as_needed",
@@ -6795,6 +8368,9 @@ The modifier does nothing for linkers that don't support it (e.g. `link.exe`).
 
 The default for this modifier is unclear, some targets currently specify it as `+as-needed`, some do not. We may want to try making `+as-needed` a default for all targets.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "needs_panic_runtime",
@@ -6806,6 +8382,9 @@ The tracking issue for this feature is: [#32837]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "negative_bounds",
@@ -6815,6 +8394,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "negative_impls",
@@ -6876,6 +8458,9 @@ This serves two purposes:
 * For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
 * It prevents downstream crates from creating such impls.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "never_patterns",
@@ -6887,6 +8472,9 @@ The tracking issue for this feature is: [#118155]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "never_type",
@@ -6898,6 +8486,9 @@ The tracking issue for this feature is: [#35121]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "never_type_fallback",
@@ -6909,6 +8500,9 @@ The tracking issue for this feature is: [#65992]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "new_range_api",
@@ -6920,17 +8514,23 @@ The tracking issue for this feature is: [#125687]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "new_uninit",
-        description: r##"# `new_uninit`
+        label: "new_zeroed_alloc",
+        description: r##"# `new_zeroed_alloc`
 
-The tracking issue for this feature is: [#63291]
+The tracking issue for this feature is: [#129396]
 
-[#63291]: https://github.com/rust-lang/rust/issues/63291
+[#129396]: https://github.com/rust-lang/rust/issues/129396
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "no_core",
@@ -6942,6 +8542,9 @@ The tracking issue for this feature is: [#29639]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "no_sanitize",
@@ -6975,6 +8578,9 @@ fn foo() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_exhaustive_omitted_patterns_lint",
@@ -6986,6 +8592,9 @@ The tracking issue for this feature is: [#89554]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_lifetime_binders",
@@ -6997,6 +8606,23 @@ The tracking issue for this feature is: [#108185]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "non_null_from_ref",
+        description: r##"# `non_null_from_ref`
+
+The tracking issue for this feature is: [#130823]
+
+[#130823]: https://github.com/rust-lang/rust/issues/130823
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "non_zero_count_ones",
@@ -7008,6 +8634,23 @@ The tracking issue for this feature is: [#120287]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "nonzero_bitwise",
+        description: r##"# `nonzero_bitwise`
+
+The tracking issue for this feature is: [#128281]
+
+[#128281]: https://github.com/rust-lang/rust/issues/128281
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "nonzero_from_mut",
@@ -7019,6 +8662,9 @@ The tracking issue for this feature is: [#106290]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "nonzero_internals",
@@ -7028,6 +8674,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "nonzero_ops",
@@ -7039,21 +8688,13 @@ The tracking issue for this feature is: [#84186]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "noop_waker",
-        description: r##"# `noop_waker`
-
-The tracking issue for this feature is: [#98286]
-
-[#98286]: https://github.com/rust-lang/rust/issues/98286
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "num_midpoint",
-        description: r##"# `num_midpoint`
+        label: "num_midpoint_signed",
+        description: r##"# `num_midpoint_signed`
 
 The tracking issue for this feature is: [#110840]
 
@@ -7061,6 +8702,9 @@ The tracking issue for this feature is: [#110840]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "numfmt",
@@ -7070,17 +8714,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "dyn_compatible_for_dispatch",
-        description: r##"# `dyn_compatible_for_dispatch`
-
-The tracking issue for this feature is: [#43561]
-
-[#43561]: https://github.com/rust-lang/rust/issues/43561
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "offset_of_enum",
@@ -7092,17 +8728,9 @@ The tracking issue for this feature is: [#120141]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "offset_of_nested",
-        description: r##"# `offset_of_nested`
-
-The tracking issue for this feature is: [#120140]
-
-[#120140]: https://github.com/rust-lang/rust/issues/120140
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "offset_of_slice",
@@ -7114,6 +8742,9 @@ The tracking issue for this feature is: [#126151]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "omit_gdb_pretty_printer_section",
@@ -7123,6 +8754,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "once_cell_get_mut",
@@ -7134,6 +8768,9 @@ The tracking issue for this feature is: [#121641]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "once_cell_try",
@@ -7145,6 +8782,9 @@ The tracking issue for this feature is: [#109737]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "once_cell_try_insert",
@@ -7156,6 +8796,23 @@ The tracking issue for this feature is: [#116693]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "once_wait",
+        description: r##"# `once_wait`
+
+The tracking issue for this feature is: [#127527]
+
+[#127527]: https://github.com/rust-lang/rust/issues/127527
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "one_sided_range",
@@ -7167,6 +8824,9 @@ The tracking issue for this feature is: [#69780]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "optimize_attribute",
@@ -7178,17 +8838,23 @@ The tracking issue for this feature is: [#54882]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "option_get_or_insert_default",
-        description: r##"# `option_get_or_insert_default`
+        label: "option_array_transpose",
+        description: r##"# `option_array_transpose`
 
-The tracking issue for this feature is: [#82901]
+The tracking issue for this feature is: [#130828]
 
-[#82901]: https://github.com/rust-lang/rust/issues/82901
+[#130828]: https://github.com/rust-lang/rust/issues/130828
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "option_zip",
@@ -7200,6 +8866,9 @@ The tracking issue for this feature is: [#70086]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "os_str_display",
@@ -7211,6 +8880,9 @@ The tracking issue for this feature is: [#120048]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "os_str_slice",
@@ -7222,6 +8894,9 @@ The tracking issue for this feature is: [#118485]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "os_string_pathbuf_leak",
@@ -7233,6 +8908,23 @@ The tracking issue for this feature is: [#125965]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "os_string_truncate",
+        description: r##"# `os_string_truncate`
+
+The tracking issue for this feature is: [#133262]
+
+[#133262]: https://github.com/rust-lang/rust/issues/133262
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_abort",
@@ -7244,6 +8936,9 @@ The tracking issue for this feature is: [#32837]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_always_abort",
@@ -7255,6 +8950,9 @@ The tracking issue for this feature is: [#84438]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_backtrace_config",
@@ -7266,6 +8964,9 @@ The tracking issue for this feature is: [#93346]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_can_unwind",
@@ -7277,6 +8978,9 @@ The tracking issue for this feature is: [#92988]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_internals",
@@ -7286,6 +8990,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_payload_as_str",
@@ -7297,6 +9004,9 @@ The tracking issue for this feature is: [#125175]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_runtime",
@@ -7308,6 +9018,9 @@ The tracking issue for this feature is: [#32837]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_unwind",
@@ -7319,6 +9032,9 @@ The tracking issue for this feature is: [#32837]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "panic_update_hook",
@@ -7330,6 +9046,9 @@ The tracking issue for this feature is: [#92649]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "patchable_function_entry",
@@ -7341,6 +9060,9 @@ The tracking issue for this feature is: [#123115]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "path_add_extension",
@@ -7352,6 +9074,9 @@ The tracking issue for this feature is: [#127292]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "path_file_prefix",
@@ -7363,6 +9088,9 @@ The tracking issue for this feature is: [#86319]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "pattern",
@@ -7374,6 +9102,9 @@ The tracking issue for this feature is: [#27721]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "pattern_complexity",
@@ -7383,6 +9114,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "pattern_type_macro",
+        description: r##"# `pattern_type_macro`
+
+The tracking issue for this feature is: [#123646]
+
+[#123646]: https://github.com/rust-lang/rust/issues/123646
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "pattern_types",
@@ -7394,6 +9142,9 @@ The tracking issue for this feature is: [#123646]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "peer_credentials_unix_socket",
@@ -7405,17 +9156,37 @@ The tracking issue for this feature is: [#42839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "pin_deref_mut",
-        description: r##"# `pin_deref_mut`
+        label: "pin_coerce_unsized_trait",
+        description: r##"# `pin_coerce_unsized_trait`
 
-The tracking issue for this feature is: [#86918]
+The tracking issue for this feature is: [#123430]
 
-[#86918]: https://github.com/rust-lang/rust/issues/86918
+[#123430]: https://github.com/rust-lang/rust/issues/123430
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "pin_ergonomics",
+        description: r##"# `pin_ergonomics`
+
+The tracking issue for this feature is: [#130494]
+
+[#130494]: https://github.com/rust-lang/rust/issues/130494
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "pointer_is_aligned_to",
@@ -7427,6 +9198,9 @@ The tracking issue for this feature is: [#96284]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "pointer_like_trait",
@@ -7436,6 +9210,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "portable_simd",
@@ -7447,6 +9224,9 @@ The tracking issue for this feature is: [#86656]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "postfix_match",
@@ -7455,6 +9235,10 @@ The tracking issue for this feature is: [#86656]
 `postfix-match` adds the feature for matching upon values postfix
 the expressions that generate the values.
 
+The tracking issue for this feature is: [#121618](https://github.com/rust-lang/rust/issues/121618).
+
+------------------------
+
 ```rust,edition2021
 #![feature(postfix_match)]
 
@@ -7473,6 +9257,9 @@ get_foo().match {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "powerpc_target_feature",
@@ -7484,17 +9271,23 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "precise_capturing",
-        description: r##"# `precise_capturing`
+        label: "precise_capturing_in_traits",
+        description: r##"# `precise_capturing_in_traits`
 
-The tracking issue for this feature is: [#123432]
+The tracking issue for this feature is: [#130044]
 
-[#123432]: https://github.com/rust-lang/rust/issues/123432
+[#130044]: https://github.com/rust-lang/rust/issues/130044
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "prelude_2024",
@@ -7506,6 +9299,9 @@ The tracking issue for this feature is: [#121042]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "prelude_import",
@@ -7515,6 +9311,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "prfchw_target_feature",
@@ -7526,6 +9325,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "print_internals",
@@ -7535,6 +9337,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_def_site",
@@ -7546,6 +9351,9 @@ The tracking issue for this feature is: [#54724]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_diagnostic",
@@ -7557,6 +9365,9 @@ The tracking issue for this feature is: [#54140]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_expand",
@@ -7568,6 +9379,9 @@ The tracking issue for this feature is: [#90765]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_hygiene",
@@ -7579,6 +9393,9 @@ The tracking issue for this feature is: [#54727]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_internals",
@@ -7590,6 +9407,9 @@ The tracking issue for this feature is: [#27812]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_quote",
@@ -7601,6 +9421,9 @@ The tracking issue for this feature is: [#54722]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_span",
@@ -7612,6 +9435,23 @@ The tracking issue for this feature is: [#54725]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "proc_macro_totokens",
+        description: r##"# `proc_macro_totokens`
+
+The tracking issue for this feature is: [#130977]
+
+[#130977]: https://github.com/rust-lang/rust/issues/130977
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "proc_macro_tracked_env",
@@ -7623,6 +9463,9 @@ The tracking issue for this feature is: [#99515]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "process_exitcode_internals",
@@ -7632,6 +9475,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "process_internals",
@@ -7641,6 +9487,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "profiler_runtime",
@@ -7650,6 +9499,9 @@ The tracking issue for this feature is: [#42524](https://github.com/rust-lang/ru
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "profiler_runtime_lib",
@@ -7659,6 +9511,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ptr_alignment_type",
@@ -7670,6 +9525,9 @@ The tracking issue for this feature is: [#102070]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ptr_as_ref_unchecked",
@@ -7681,6 +9539,9 @@ The tracking issue for this feature is: [#122034]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ptr_as_uninit",
@@ -7692,6 +9553,9 @@ The tracking issue for this feature is: [#75402]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ptr_internals",
@@ -7701,6 +9565,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ptr_mask",
@@ -7712,6 +9579,9 @@ The tracking issue for this feature is: [#98290]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ptr_metadata",
@@ -7723,6 +9593,9 @@ The tracking issue for this feature is: [#81513]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ptr_sub_ptr",
@@ -7734,6 +9607,9 @@ The tracking issue for this feature is: [#95892]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "pub_crate_should_not_need_unstable_attr",
@@ -7743,28 +9619,37 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "raw_os_error_ty",
-        description: r##"# `raw_os_error_ty`
+        label: "random",
+        description: r##"# `random`
 
-The tracking issue for this feature is: [#107792]
+The tracking issue for this feature is: [#130703]
 
-[#107792]: https://github.com/rust-lang/rust/issues/107792
+[#130703]: https://github.com/rust-lang/rust/issues/130703
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "raw_ref_op",
-        description: r##"# `raw_ref_op`
+        label: "raw_os_error_ty",
+        description: r##"# `raw_os_error_ty`
 
-The tracking issue for this feature is: [#64490]
+The tracking issue for this feature is: [#107792]
 
-[#64490]: https://github.com/rust-lang/rust/issues/64490
+[#107792]: https://github.com/rust-lang/rust/issues/107792
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "raw_slice_split",
@@ -7776,6 +9661,9 @@ The tracking issue for this feature is: [#95595]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "raw_vec_internals",
@@ -7785,6 +9673,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "read_buf",
@@ -7796,26 +9687,9 @@ The tracking issue for this feature is: [#78485]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "ready_into_inner",
-        description: r##"# `ready_into_inner`
-
-The tracking issue for this feature is: [#101196]
-
-[#101196]: https://github.com/rust-lang/rust/issues/101196
-
-------------------------
-"##,
-    },
-    Lint {
-        label: "receiver_trait",
-        description: r##"# `receiver_trait`
-
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "reentrant_lock",
@@ -7827,6 +9701,9 @@ The tracking issue for this feature is: [#121440]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ref_pat_eat_one_layer_2024",
@@ -7838,6 +9715,9 @@ The tracking issue for this feature is: [#123076]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ref_pat_eat_one_layer_2024_structural",
@@ -7849,6 +9729,9 @@ The tracking issue for this feature is: [#123076]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "register_tool",
@@ -7860,6 +9743,9 @@ The tracking issue for this feature is: [#66079]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "repr128",
@@ -7882,6 +9768,9 @@ enum Foo {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "repr_simd",
@@ -7893,6 +9782,9 @@ The tracking issue for this feature is: [#27731]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "restricted_std",
@@ -7902,24 +9794,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "result_ffi_guarantees",
-        description: r##"# `result_ffi_guarantees`
-
-The tracking issue for this feature is: [#110503]
-
-[#110503]: https://github.com/rust-lang/rust/issues/110503
-
-------------------------
-
-This feature adds the possibility of using `Result<T, E>` in FFI if T's niche
-value can be used to describe E or vise-versa.
-
-See [RFC 3391] for more information.
-
-[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "result_flattening",
@@ -7931,6 +9808,9 @@ The tracking issue for this feature is: [#70142]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "return_type_notation",
@@ -7942,6 +9822,9 @@ The tracking issue for this feature is: [#109417]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "riscv_target_feature",
@@ -7953,6 +9836,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "round_char_boundary",
@@ -7964,6 +9850,9 @@ The tracking issue for this feature is: [#93743]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rt",
@@ -7973,6 +9862,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rtm_target_feature",
@@ -7984,6 +9876,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rust_cold_cc",
@@ -7995,6 +9890,9 @@ The tracking issue for this feature is: [#97544]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustc_allow_const_fn_unstable",
@@ -8006,6 +9904,9 @@ The tracking issue for this feature is: [#69399]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustc_attrs",
@@ -8063,6 +9964,9 @@ error: size: Size { raw: 16 }
 error: aborting due to 2 previous errors
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustc_encodable_decodable",
@@ -8072,6 +9976,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustc_private",
@@ -8082,7 +9989,14 @@ The tracking issue for this feature is: [#27812]
 [#27812]: https://github.com/rust-lang/rust/issues/27812
 
 ------------------------
+
+This feature allows access to unstable internal compiler crates.
+
+Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc_internals",
@@ -8094,6 +10008,9 @@ The tracking issue for this feature is: [#90418]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "rustdoc_missing_doc_code_examples",
@@ -8105,6 +10022,23 @@ The tracking issue for this feature is: [#101730]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "rwlock_downgrade",
+        description: r##"# `rwlock_downgrade`
+
+The tracking issue for this feature is: [#128203]
+
+[#128203]: https://github.com/rust-lang/rust/issues/128203
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "s390x_target_feature",
@@ -8116,6 +10050,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "sealed",
@@ -8125,6 +10062,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "seek_stream_len",
@@ -8136,6 +10076,9 @@ The tracking issue for this feature is: [#59359]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "set_ptr_value",
@@ -8147,6 +10090,9 @@ The tracking issue for this feature is: [#75091]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "setgroups",
@@ -8158,6 +10104,9 @@ The tracking issue for this feature is: [#90747]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "sgx_platform",
@@ -8169,17 +10118,23 @@ The tracking issue for this feature is: [#56975]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "shorter_tail_lifetimes",
-        description: r##"# `shorter_tail_lifetimes`
+        label: "sha512_sm_x86",
+        description: r##"# `sha512_sm_x86`
 
-The tracking issue for this feature is: [#123739]
+The tracking issue for this feature is: [#126624]
 
-[#123739]: https://github.com/rust-lang/rust/issues/123739
+[#126624]: https://github.com/rust-lang/rust/issues/126624
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "simd_ffi",
@@ -8191,6 +10146,9 @@ The tracking issue for this feature is: [#27731]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "sized_type_properties",
@@ -8200,6 +10158,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "slice_as_array",
+        description: r##"# `slice_as_array`
+
+The tracking issue for this feature is: [#133508]
+
+[#133508]: https://github.com/rust-lang/rust/issues/133508
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_as_chunks",
@@ -8211,6 +10186,9 @@ The tracking issue for this feature is: [#74985]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_concat_ext",
@@ -8222,6 +10200,9 @@ The tracking issue for this feature is: [#27747]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_concat_trait",
@@ -8233,6 +10214,9 @@ The tracking issue for this feature is: [#27747]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_from_ptr_range",
@@ -8244,6 +10228,9 @@ The tracking issue for this feature is: [#89792]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_index_methods",
@@ -8253,6 +10240,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_internals",
@@ -8262,6 +10252,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_iter_mut_as_mut_slice",
@@ -8273,6 +10266,9 @@ The tracking issue for this feature is: [#93079]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_partition_dedup",
@@ -8284,6 +10280,9 @@ The tracking issue for this feature is: [#54279]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_pattern",
@@ -8295,6 +10294,9 @@ The tracking issue for this feature is: [#56345]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_ptr_get",
@@ -8306,6 +10308,9 @@ The tracking issue for this feature is: [#74265]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_range",
@@ -8317,6 +10322,9 @@ The tracking issue for this feature is: [#76393]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_split_once",
@@ -8328,6 +10336,9 @@ The tracking issue for this feature is: [#112811]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_swap_unchecked",
@@ -8339,6 +10350,9 @@ The tracking issue for this feature is: [#88539]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "slice_take",
@@ -8350,6 +10364,9 @@ The tracking issue for this feature is: [#62280]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "solid_ext",
@@ -8359,6 +10376,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "sort_floats",
@@ -8370,6 +10390,23 @@ The tracking issue for this feature is: [#93396]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "sparc_target_feature",
+        description: r##"# `sparc_target_feature`
+
+The tracking issue for this feature is: [#132783]
+
+[#132783]: https://github.com/rust-lang/rust/issues/132783
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "specialization",
@@ -8381,6 +10418,9 @@ The tracking issue for this feature is: [#31844]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "split_array",
@@ -8392,6 +10432,9 @@ The tracking issue for this feature is: [#90091]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "split_as_slice",
@@ -8403,6 +10446,9 @@ The tracking issue for this feature is: [#96137]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "sse4a_target_feature",
@@ -8414,6 +10460,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "staged_api",
@@ -8423,6 +10472,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "start",
@@ -8486,6 +10538,9 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "std_internals",
@@ -8495,6 +10550,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "stdarch_arm_feature_detection",
@@ -8506,6 +10564,9 @@ The tracking issue for this feature is: [#111190]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "stdarch_mips_feature_detection",
@@ -8517,6 +10578,9 @@ The tracking issue for this feature is: [#111188]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "stdarch_powerpc_feature_detection",
@@ -8528,6 +10592,9 @@ The tracking issue for this feature is: [#111191]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "stdio_makes_pipe",
@@ -8539,6 +10606,9 @@ The tracking issue for this feature is: [#98288]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "step_trait",
@@ -8550,6 +10620,9 @@ The tracking issue for this feature is: [#42168]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "stmt_expr_attributes",
@@ -8561,6 +10634,23 @@ The tracking issue for this feature is: [#15701]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "str_as_str",
+        description: r##"# `str_as_str`
+
+The tracking issue for this feature is: [#130366]
+
+[#130366]: https://github.com/rust-lang/rust/issues/130366
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "str_from_raw_parts",
@@ -8572,6 +10662,9 @@ The tracking issue for this feature is: [#119206]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "str_from_utf16_endian",
@@ -8583,6 +10676,9 @@ The tracking issue for this feature is: [#116258]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "str_internals",
@@ -8592,6 +10688,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "str_lines_remainder",
@@ -8603,6 +10702,9 @@ The tracking issue for this feature is: [#77998]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "str_split_inclusive_remainder",
@@ -8614,6 +10716,9 @@ The tracking issue for this feature is: [#77998]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "str_split_remainder",
@@ -8625,6 +10730,9 @@ The tracking issue for this feature is: [#77998]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "str_split_whitespace_remainder",
@@ -8636,6 +10744,9 @@ The tracking issue for this feature is: [#77998]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "strict_overflow_ops",
@@ -8647,24 +10758,40 @@ The tracking issue for this feature is: [#118260]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "strict_provenance",
-        description: r##"# `strict_provenance`
+        label: "strict_provenance_atomic_ptr",
+        description: r##"# `strict_provenance_atomic_ptr`
+
+The tracking issue for this feature is: [#99108]
+
+[#99108]: https://github.com/rust-lang/rust/issues/99108
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "strict_provenance_lints",
+        description: r##"# `strict_provenance_lints`
 
 The tracking issue for this feature is: [#95228]
 
 [#95228]: https://github.com/rust-lang/rust/issues/95228
 -----
 
-The `strict_provenance` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints.
+The `strict_provenance_lints` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints.
 These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model.
-The same feature gate is also used for the experimental strict provenance API in `std` (actually `core`).
 
 ## Example
 
 ```rust
-#![feature(strict_provenance)]
+#![feature(strict_provenance_lints)]
 #![warn(fuzzy_provenance_casts)]
 
 fn main() {
@@ -8673,17 +10800,9 @@ fn main() {
 }
 ```
 "##,
-    },
-    Lint {
-        label: "strict_provenance_atomic_ptr",
-        description: r##"# `strict_provenance_atomic_ptr`
-
-The tracking issue for this feature is: [#99108]
-
-[#99108]: https://github.com/rust-lang/rust/issues/99108
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "string_deref_patterns",
@@ -8733,6 +10852,9 @@ pub fn is_it_the_answer(value: Value) -> bool {
 
 [its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "string_extend_from_within",
@@ -8744,6 +10866,23 @@ The tracking issue for this feature is: [#103806]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "string_from_utf8_lossy_owned",
+        description: r##"# `string_from_utf8_lossy_owned`
+
+The tracking issue for this feature is: [#129436]
+
+[#129436]: https://github.com/rust-lang/rust/issues/129436
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "string_remove_matches",
@@ -8755,6 +10894,9 @@ The tracking issue for this feature is: [#72826]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "structural_match",
@@ -8766,6 +10908,23 @@ The tracking issue for this feature is: [#31434]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "substr_range",
+        description: r##"# `substr_range`
+
+The tracking issue for this feature is: [#126769]
+
+[#126769]: https://github.com/rust-lang/rust/issues/126769
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "sync_unsafe_cell",
@@ -8777,6 +10936,9 @@ The tracking issue for this feature is: [#95439]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "target_feature_11",
@@ -8788,6 +10950,9 @@ The tracking issue for this feature is: [#69098]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "tbm_target_feature",
@@ -8799,6 +10964,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "tcp_deferaccept",
@@ -8810,6 +10978,9 @@ The tracking issue for this feature is: [#119639]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "tcp_linger",
@@ -8821,6 +10992,9 @@ The tracking issue for this feature is: [#88494]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "tcp_quickack",
@@ -8832,6 +11006,9 @@ The tracking issue for this feature is: [#96256]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "tcplistener_into_incoming",
@@ -8843,6 +11020,9 @@ The tracking issue for this feature is: [#88373]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "test",
@@ -9005,6 +11185,9 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
 However, the optimizer can still modify a testcase in an undesirable manner
 even when using either of the above.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "test_unstable_lint",
@@ -9014,6 +11197,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "thin_box",
@@ -9025,6 +11211,9 @@ The tracking issue for this feature is: [#92791]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "thread_id_value",
@@ -9036,6 +11225,9 @@ The tracking issue for this feature is: [#67939]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "thread_local",
@@ -9047,6 +11239,9 @@ The tracking issue for this feature is: [#29594]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "thread_local_internals",
@@ -9056,6 +11251,23 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "thread_raw",
+        description: r##"# `thread_raw`
+
+The tracking issue for this feature is: [#97523]
+
+[#97523]: https://github.com/rust-lang/rust/issues/97523
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "thread_sleep_until",
@@ -9067,17 +11279,23 @@ The tracking issue for this feature is: [#113752]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "thread_spawn_unchecked",
-        description: r##"# `thread_spawn_unchecked`
+        label: "thread_spawn_hook",
+        description: r##"# `thread_spawn_hook`
 
-The tracking issue for this feature is: [#55132]
+The tracking issue for this feature is: [#132951]
 
-[#55132]: https://github.com/rust-lang/rust/issues/55132
+[#132951]: https://github.com/rust-lang/rust/issues/132951
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trace_macros",
@@ -9121,6 +11339,9 @@ note: trace_macro
     Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "track_path",
@@ -9132,6 +11353,9 @@ The tracking issue for this feature is: [#99515]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trait_alias",
@@ -9170,6 +11394,9 @@ pub fn main() {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trait_upcasting",
@@ -9187,7 +11414,6 @@ so long as `Bar: Foo`.
 
 ```rust,edition2018
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo {}
 
@@ -9201,6 +11427,9 @@ let bar: &dyn Bar = &123;
 let foo: &dyn Foo = bar;
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "transmutability",
@@ -9212,6 +11441,9 @@ The tracking issue for this feature is: [#99571]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "transmute_generic_consts",
@@ -9223,6 +11455,9 @@ The tracking issue for this feature is: [#109929]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "transparent_unions",
@@ -9310,6 +11545,9 @@ it is transparent). The Rust compiler is free to perform this optimization if
 possible, but is not required to, and different compiler versions may differ in
 their application of these optimizations.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trivial_bounds",
@@ -9321,6 +11559,9 @@ The tracking issue for this feature is: [#48214]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trusted_fused",
@@ -9330,6 +11571,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trusted_len",
@@ -9341,6 +11585,9 @@ The tracking issue for this feature is: [#37572]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trusted_len_next_unchecked",
@@ -9352,6 +11599,9 @@ The tracking issue for this feature is: [#37572]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trusted_random_access",
@@ -9361,6 +11611,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "trusted_step",
@@ -9372,6 +11625,9 @@ The tracking issue for this feature is: [#85731]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "try_blocks",
@@ -9406,6 +11662,9 @@ let result: Result<i32, ParseIntError> = try {
 assert!(result.is_err());
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "try_find",
@@ -9417,6 +11676,9 @@ The tracking issue for this feature is: [#63178]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "try_reserve_kind",
@@ -9428,6 +11690,9 @@ The tracking issue for this feature is: [#48043]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "try_trait_v2",
@@ -9439,6 +11704,9 @@ The tracking issue for this feature is: [#84277]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "try_trait_v2_residual",
@@ -9450,6 +11718,9 @@ The tracking issue for this feature is: [#91285]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "try_trait_v2_yeet",
@@ -9461,6 +11732,9 @@ The tracking issue for this feature is: [#96374]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "try_with_capacity",
@@ -9472,6 +11746,9 @@ The tracking issue for this feature is: [#91913]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "tuple_trait",
@@ -9481,6 +11758,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "type_alias_impl_trait",
@@ -9492,6 +11772,9 @@ The tracking issue for this feature is: [#63063]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "type_ascription",
@@ -9503,6 +11786,9 @@ The tracking issue for this feature is: [#23416]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "type_changing_struct_update",
@@ -9540,6 +11826,9 @@ fn main () {
 }
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "ub_checks",
@@ -9549,6 +11838,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "uefi_std",
@@ -9560,6 +11852,23 @@ The tracking issue for this feature is: [#100499]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unbounded_shifts",
+        description: r##"# `unbounded_shifts`
+
+The tracking issue for this feature is: [#129375]
+
+[#129375]: https://github.com/rust-lang/rust/issues/129375
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unboxed_closures",
@@ -9589,6 +11898,9 @@ extern "rust-call" fn add_args(args: (u32, u32)) -> u32 {
 fn main() {}
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unchecked_neg",
@@ -9600,6 +11912,9 @@ The tracking issue for this feature is: [#85122]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unchecked_shifts",
@@ -9611,6 +11926,9 @@ The tracking issue for this feature is: [#85122]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unicode_internals",
@@ -9620,6 +11938,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unique_rc_arc",
@@ -9631,6 +11952,9 @@ The tracking issue for this feature is: [#112566]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unix_file_vectored_at",
@@ -9642,6 +11966,9 @@ The tracking issue for this feature is: [#89517]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unix_set_mark",
@@ -9653,6 +11980,9 @@ The tracking issue for this feature is: [#96467]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unix_socket_ancillary_data",
@@ -9664,6 +11994,9 @@ The tracking issue for this feature is: [#76915]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unix_socket_peek",
@@ -9675,59 +12008,89 @@ The tracking issue for this feature is: [#76923]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "unnamed_fields",
-        description: r##"# `unnamed_fields`
+        label: "unqualified_local_imports",
+        description: r##"# `unqualified_local_imports`
 
-The tracking issue for this feature is: [#49804]
-
-[#49804]: https://github.com/rust-lang/rust/issues/49804
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "unsafe_attributes",
-        description: r##"# `unsafe_attributes`
+        label: "unsafe_fields",
+        description: r##"# `unsafe_fields`
 
-The tracking issue for this feature is: [#123757]
+The tracking issue for this feature is: [#132922]
 
-[#123757]: https://github.com/rust-lang/rust/issues/123757
+[#132922]: https://github.com/rust-lang/rust/issues/132922
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "unsafe_cell_from_mut",
-        description: r##"# `unsafe_cell_from_mut`
+        label: "unsafe_pin_internals",
+        description: r##"# `unsafe_pin_internals`
+
+This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+
+------------------------
+"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "unsigned_is_multiple_of",
+        description: r##"# `unsigned_is_multiple_of`
 
-The tracking issue for this feature is: [#111645]
+The tracking issue for this feature is: [#128101]
 
-[#111645]: https://github.com/rust-lang/rust/issues/111645
+[#128101]: https://github.com/rust-lang/rust/issues/128101
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "unsafe_extern_blocks",
-        description: r##"# `unsafe_extern_blocks`
+        label: "unsigned_nonzero_div_ceil",
+        description: r##"# `unsigned_nonzero_div_ceil`
 
-The tracking issue for this feature is: [#123743]
+The tracking issue for this feature is: [#132968]
 
-[#123743]: https://github.com/rust-lang/rust/issues/123743
+[#132968]: https://github.com/rust-lang/rust/issues/132968
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "unsafe_pin_internals",
-        description: r##"# `unsafe_pin_internals`
+        label: "unsigned_signed_diff",
+        description: r##"# `unsigned_signed_diff`
 
-This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
+The tracking issue for this feature is: [#126041]
+
+[#126041]: https://github.com/rust-lang/rust/issues/126041
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsize",
@@ -9739,6 +12102,9 @@ The tracking issue for this feature is: [#18598]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsized_const_params",
@@ -9750,6 +12116,9 @@ The tracking issue for this feature is: [#95174]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsized_fn_params",
@@ -9761,6 +12130,9 @@ The tracking issue for this feature is: [#48055]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsized_locals",
@@ -9940,6 +12312,9 @@ fn main() {
 
 will unnecessarily extend the stack frame.
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unsized_tuple_coercion",
@@ -9971,6 +12346,9 @@ fn main() {
 
 [RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "unwrap_infallible",
@@ -9982,6 +12360,9 @@ The tracking issue for this feature is: [#61695]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "update_panic_count",
@@ -9991,6 +12372,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "used_with_arg",
@@ -10002,6 +12386,9 @@ The tracking issue for this feature is: [#93798]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "utf16_extra",
@@ -10013,28 +12400,37 @@ The tracking issue for this feature is: [#94919]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "utf16_extra_const",
-        description: r##"# `utf16_extra_const`
+        label: "variant_count",
+        description: r##"# `variant_count`
 
-The tracking issue for this feature is: [#94919]
+The tracking issue for this feature is: [#73662]
 
-[#94919]: https://github.com/rust-lang/rust/issues/94919
+[#73662]: https://github.com/rust-lang/rust/issues/73662
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
-        label: "variant_count",
-        description: r##"# `variant_count`
+        label: "vec_deque_iter_as_slices",
+        description: r##"# `vec_deque_iter_as_slices`
 
-The tracking issue for this feature is: [#73662]
+The tracking issue for this feature is: [#123947]
 
-[#73662]: https://github.com/rust-lang/rust/issues/73662
+[#123947]: https://github.com/rust-lang/rust/issues/123947
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "vec_into_raw_parts",
@@ -10046,6 +12442,9 @@ The tracking issue for this feature is: [#65816]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "vec_pop_if",
@@ -10057,6 +12456,9 @@ The tracking issue for this feature is: [#122741]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "vec_push_within_capacity",
@@ -10068,6 +12470,9 @@ The tracking issue for this feature is: [#100486]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "vec_split_at_spare",
@@ -10079,17 +12484,9 @@ The tracking issue for this feature is: [#81944]
 
 ------------------------
 "##,
-    },
-    Lint {
-        label: "waker_getters",
-        description: r##"# `waker_getters`
-
-The tracking issue for this feature is: [#96992]
-
-[#96992]: https://github.com/rust-lang/rust/issues/96992
-
-------------------------
-"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "wasi_ext",
@@ -10101,6 +12498,9 @@ The tracking issue for this feature is: [#71213]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "wasm_target_feature",
@@ -10112,6 +12512,9 @@ The tracking issue for this feature is: [#44839]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_by_handle",
@@ -10123,6 +12526,9 @@ The tracking issue for this feature is: [#63010]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_c",
@@ -10132,6 +12538,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_change_time",
@@ -10143,6 +12552,9 @@ The tracking issue for this feature is: [#121478]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_handle",
@@ -10152,6 +12564,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_net",
@@ -10161,6 +12576,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_process_exit_code_from",
@@ -10172,6 +12590,9 @@ The tracking issue for this feature is: [#111688]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_process_extensions_async_pipes",
@@ -10183,6 +12604,9 @@ The tracking issue for this feature is: [#98289]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_process_extensions_force_quotes",
@@ -10194,6 +12618,9 @@ The tracking issue for this feature is: [#82227]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_process_extensions_main_thread_handle",
@@ -10205,6 +12632,9 @@ The tracking issue for this feature is: [#96723]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_process_extensions_raw_attribute",
@@ -10216,6 +12646,9 @@ The tracking issue for this feature is: [#114854]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_process_extensions_show_window",
@@ -10227,6 +12660,9 @@ The tracking issue for this feature is: [#127544]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "windows_stdio",
@@ -10236,6 +12672,9 @@ This feature is internal to the Rust compiler and is not intended for general us
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "with_negative_coherence",
@@ -10245,6 +12684,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "wrapping_int_impl",
@@ -10256,6 +12698,9 @@ The tracking issue for this feature is: [#32463]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "wrapping_next_power_of_two",
@@ -10267,6 +12712,9 @@ The tracking issue for this feature is: [#32463]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "write_all_vectored",
@@ -10278,6 +12726,9 @@ The tracking issue for this feature is: [#70436]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "x86_amx_intrinsics",
@@ -10289,6 +12740,9 @@ The tracking issue for this feature is: [#126622]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "xop_target_feature",
@@ -10300,6 +12754,9 @@ The tracking issue for this feature is: [#127208]
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "yeet_desugar_details",
@@ -10309,6 +12766,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 
 ------------------------
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "yeet_expr",
@@ -10339,6 +12799,9 @@ fn bar() -> Option<String> {
 assert_eq!(bar(), None);
 ```
 "##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
 ];
 
@@ -10346,6 +12809,9 @@ pub const CLIPPY_LINTS: &[Lint] = &[
     Lint {
         label: "clippy::absolute_paths",
         description: r##"Checks for usage of items through absolute paths, like `std::env::current_dir`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::absurd_extreme_comparisons",
@@ -10353,10 +12819,16 @@ pub const CLIPPY_LINTS: &[Lint] = &[
 either the minimum or maximum value for its type and warns if it involves a
 case that is always true or always false. Only integer and boolean types are
 checked."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::alloc_instead_of_core",
         description: r##"Finds items imported through `alloc` when available through `core`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::allow_attributes",
@@ -10365,19 +12837,31 @@ the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reaso
 
 This lint only warns outer attributes (`#[allow]`), as inner attributes
 (`#![allow]`) are usually used to enable or disable lints on a global scale."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::allow_attributes_without_reason",
         description: r##"Checks for attributes that allow lints without a reason."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::almost_complete_range",
         description: r##"Checks for ranges which almost include the entire range of letters from 'a' to 'z'
 or digits from '0' to '9', but don't because they're a half open range."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::almost_swapped",
         description: r##"Checks for `foo = bar; bar = foo` sequences."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::approx_constant",
@@ -10387,11 +12871,17 @@ constants which are defined in
 or
 [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
 respectively, suggesting to use the predefined constant."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::arc_with_non_send_sync",
         description: r##".
 This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::arithmetic_side_effects",
@@ -10403,6 +12893,9 @@ or can panic (`/`, `%`).
 
 Known safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant
 environments, allowed types and non-constant operations that won't overflow are ignored."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::as_conversions",
@@ -10415,54 +12908,90 @@ If you want more precise lints for `as`, please consider using these separate li
 `fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`.
 There is a good explanation the reason why this lint should work in this way and how it is useful
 [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::as_ptr_cast_mut",
         description: r##"Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::as_underscore",
         description: r##"Checks for the usage of `as _` conversion using inferred type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::assertions_on_constants",
         description: r##"Checks for `assert!(true)` and `assert!(false)` calls."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::assertions_on_result_states",
         description: r##"Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::assign_op_pattern",
         description: r##"Checks for `a = a op b` or `a = b commutative_op a`
 patterns."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::assign_ops",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::assigning_clones",
         description: r##"Checks for code like `foo = bar.clone();`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::async_yields_async",
         description: r##"Checks for async blocks that yield values of types
 that can themselves be awaited."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::await_holding_invalid_type",
         description: r##"Allows users to configure types which should not be held across await
 suspension points."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::await_holding_lock",
         description: r##"Checks for calls to `await` while holding a non-async-aware
 `MutexGuard`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::await_holding_refcell_ref",
         description: r##"Checks for calls to `await` while holding a `RefCell`, `Ref`, or `RefMut`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::bad_bit_mask",
@@ -10481,126 +13010,210 @@ table:
 |`==` or `!=`| `\\|` |`x \\| 1 == 0`|`false`  |`c \\| m != c`         |
 |`<`  or `>=`| `\\|` |`x \\| 1 < 1` |`false`  |`m >= c`              |
 |`<=` or `>` | `\\|` |`x \\| 1 > 0` |`true`   |`m > c`               |"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::big_endian_bytes",
         description: r##"Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::bind_instead_of_map",
         description: r##"Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))`
 or `_.or_else(|x| Err(y))`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::blanket_clippy_restriction_lints",
         description: r##"Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::blocks_in_conditions",
         description: r##"Checks for `if` and `match` conditions that use blocks containing an
 expression, statements or conditions that use closures with blocks."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::bool_assert_comparison",
         description: r##"This lint warns about boolean comparisons in assert-like macros."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::bool_comparison",
         description: r##"Checks for expressions of the form `x == true`,
 `x != true` and order comparisons such as `x < true` (or vice versa) and
 suggest using the variable directly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::bool_to_int_with_if",
         description: r##"Instead of using an if statement to convert a bool to an int,
 this lint suggests using a `from()` function or an `as` coercion."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::borrow_as_ptr",
         description: r##"Checks for the usage of `&expr as *const T` or
 `&mut expr as *mut T`, and suggest using `ptr::addr_of` or
 `ptr::addr_of_mut` instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::borrow_deref_ref",
+        description: r##"Checks for `&*(&T)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::borrow_deref_ref", description: r##"Checks for `&*(&T)`."## },
     Lint {
         label: "clippy::borrow_interior_mutable_const",
         description: r##"Checks if `const` items which is interior mutable (e.g.,
 contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::borrowed_box",
         description: r##"Checks for usage of `&Box<T>` anywhere in the code.
 Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::box_collection",
         description: r##"Checks for usage of `Box<T>` where T is a collection such as Vec anywhere in the code.
 Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::box_default",
         description: r##"checks for `Box::new(Default::default())`, which can be written as
 `Box::default()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::boxed_local",
         description: r##"Checks for usage of `Box<T>` where an unboxed `T` would
 work fine."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::branches_sharing_code",
         description: r##"Checks if the `if` and `else` block contain shared code that can be
 moved out of the blocks."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::builtin_type_shadow",
         description: r##"Warns if a generic shadows a built-in type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::byte_char_slices",
         description: r##"Checks for hard to read slices of byte characters, that could be more easily expressed as a
 byte string."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::bytes_count_to_len",
         description: r##"It checks for `str::bytes().count()` and suggests replacing it with
 `str::len()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::bytes_nth",
         description: r##"Checks for the use of `.bytes().nth()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cargo_common_metadata",
         description: r##"Checks to see if all common metadata is defined in
 `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::case_sensitive_file_extension_comparisons",
         description: r##"Checks for calls to `ends_with` with possible file extensions
 and suggests to use a case-insensitive approach instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_abs_to_unsigned",
         description: r##"Checks for usage of the `abs()` method that cast the result to unsigned."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_enum_constructor",
         description: r##"Checks for casts from an enum tuple constructor to an integer."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_enum_truncation",
         description: r##"Checks for casts from an enum type to an integral type that will definitely truncate the
 value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_lossless",
         description: r##"Checks for casts between numeric types that can be replaced by safe
 conversion functions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_nan_to_int",
         description: r##"Checks for a known NaN float being cast to an integer"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_possible_truncation",
@@ -10608,6 +13221,9 @@ conversion functions."##,
 truncate large values. This is expected behavior, so the cast is `Allow` by
 default. It suggests user either explicitly ignore the lint,
 or use `try_from()` and handle the truncation, default, or panic explicitly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_possible_wrap",
@@ -10618,6 +13234,9 @@ changed at the bit level), and the binary representation of the value is
 reinterpreted. This can cause wrapping if the value is too big
 for the target signed type. However, the cast works as defined, so this lint
 is `Allow` by default."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_precision_loss",
@@ -10628,11 +13247,17 @@ rounding errors. This possible rounding is to be expected, so this lint is
 
 Basically, this warns on casting any integer with 32 or more bits to `f32`
 or any 64-bit integer to `f64`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_ptr_alignment",
         description: r##"Checks for casts, using `as` or `pointer::cast`, from a
 less strictly aligned pointer to a more strictly aligned pointer."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_sign_loss",
@@ -10640,79 +13265,130 @@ less strictly aligned pointer to a more strictly aligned pointer."##,
 type. In this case, negative values wrap around to large positive values,
 which can be quite surprising in practice. However, since the cast works as
 defined, this lint is `Allow` by default."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_slice_different_sizes",
         description: r##"Checks for `as` casts between raw pointers to slices with differently sized elements."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cast_slice_from_raw_parts",
         description: r##"Checks for a raw slice being cast to a slice pointer"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cfg_not_test",
-        description: r##"Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#{cfg(not(test))]`)"##,
+        description: r##"Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#[cfg(not(test))]`)"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::char_lit_as_u8",
         description: r##"Checks for expressions where a character literal is cast
 to `u8` and suggests using a byte literal instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::chars_last_cmp",
         description: r##"Checks for usage of `_.chars().last()` or
 `_.chars().next_back()` on a `str` to check if it ends with a given char."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::chars_next_cmp",
         description: r##"Checks for usage of `.chars().next()` on a `str` to check
 if it starts with a given char."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::checked_conversions",
         description: r##"Checks for explicit bounds checking when casting."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::clear_with_drain",
         description: r##"Checks for usage of `.drain(..)` for the sole purpose of clearing a container."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::clone_on_copy",
         description: r##"Checks for usage of `.clone()` on a `Copy` type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::clone_on_ref_ptr",
         description: r##"Checks for usage of `.clone()` on a ref-counted pointer,
 (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified
 function syntax instead (e.g., `Rc::clone(foo)`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cloned_instead_of_copied",
         description: r##"Checks for usage of `cloned()` on an `Iterator` or `Option` where
 `copied()` could be used instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cmp_null",
         description: r##"This lint checks for equality comparisons with `ptr::null`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cmp_owned",
         description: r##"Checks for conversions to owned values just for the sake
 of a comparison."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::cognitive_complexity",
         description: r##"Checks for methods with high cognitive complexity."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::collapsible_else_if",
         description: r##"Checks for collapsible `else { if ... }` expressions
 that can be collapsed to `else if ...`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::collapsible_if",
         description: r##"Checks for nested `if` statements which can be collapsed
 by `&&`-combining their conditions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::collapsible_match",
@@ -10721,73 +13397,121 @@ without adding any branches.
 
 Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only
 cases where merging would most likely make the code more readable."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::collapsible_str_replace",
         description: r##"Checks for consecutive calls to `str::replace` (2 or more)
 that can be collapsed into a single call."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::collection_is_never_read",
         description: r##"Checks for collections that are never queried."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::comparison_chain",
         description: r##"Checks comparison chains written with `if` that can be
 rewritten with `match` and `cmp`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::comparison_to_empty",
         description: r##"Checks for comparing to an empty slice such as `` or `[]`,
 and suggests using `.is_empty()` where applicable."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::const_is_empty",
         description: r##"It identifies calls to `.is_empty()` on constant values."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::copy_iterator",
         description: r##"Checks for types that implement `Copy` as well as
 `Iterator`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::crate_in_macro_def",
         description: r##"Checks for usage of `crate` as opposed to `$crate` in a macro definition."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::create_dir",
         description: r##"Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::crosspointer_transmute",
         description: r##"Checks for transmutes between a type `T` and `*T`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::dbg_macro",
         description: r##"Checks for usage of the [`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::debug_assert_with_mut_call",
         description: r##"Checks for function/method calls with a mutable
 parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::decimal_literal_representation",
         description: r##"Warns if there is a better representation for a numeric literal."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::declare_interior_mutable_const",
         description: r##"Checks for declaration of `const` items which is interior
 mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::default_constructed_unit_structs",
         description: r##"Checks for construction on unit struct using `default`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::default_instead_of_iter_empty",
         description: r##"It checks for `std::iter::Empty::default()` and suggests replacing it with
 `std::iter::empty()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::default_numeric_fallback",
@@ -10799,58 +13523,94 @@ types at the end of type inference, then integer type is bound to `i32`, and sim
 floating type is bound to `f64`.
 
 See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::default_trait_access",
         description: r##"Checks for literal calls to `Default::default()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::default_union_representation",
         description: r##"Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::deprecated_cfg_attr",
         description: r##"Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
 with `#[rustfmt::skip]`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::deprecated_clippy_cfg_attr",
         description: r##"Checks for `#[cfg_attr(feature = cargo-clippy, ...)]` and for
 `#[cfg(feature = cargo-clippy)]` and suggests to replace it with
 `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::deprecated_semver",
         description: r##"Checks for `#[deprecated]` annotations with a `since`
 field that is not a valid semantic version. Also allows TBD to signal
 future deprecation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::deref_addrof",
         description: r##"Checks for usage of `*&` and `*&mut` in expressions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::deref_by_slicing",
         description: r##"Checks for slicing expressions which are equivalent to dereferencing the
 value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::derivable_impls",
         description: r##"Detects manual `std::default::Default` implementations that are identical to a derived implementation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::derive_ord_xor_partial_ord",
         description: r##"Lints against manual `PartialOrd` and `Ord` implementations for types with a derived `Ord`
 or `PartialOrd` implementation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::derive_partial_eq_without_eq",
         description: r##"Checks for types that derive `PartialEq` and could implement `Eq`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::derived_hash_with_manual_eq",
         description: r##"Lints against manual `PartialEq` implementations for types with a derived `Hash`
 implementation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::disallowed_macros",
@@ -10858,6 +13618,9 @@ implementation."##,
 
 Note: Even though this lint is warn-by-default, it will only trigger if
 macros are defined in the clippy.toml file."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::disallowed_methods",
@@ -10865,11 +13628,17 @@ macros are defined in the clippy.toml file."##,
 
 Note: Even though this lint is warn-by-default, it will only trigger if
 methods are defined in the clippy.toml file."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::disallowed_names",
         description: r##"Checks for usage of disallowed names for variables, such
 as `foo`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::disallowed_script_idents",
@@ -10885,6 +13654,9 @@ See also: [`non_ascii_idents`].
 
 [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases
 [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::disallowed_types",
@@ -10892,11 +13664,17 @@ See also: [`non_ascii_idents`].
 
 Note: Even though this lint is warn-by-default, it will only trigger if
 types are defined in the clippy.toml file."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::diverging_sub_expression",
         description: r##"Checks for diverging calls that are not match arms or
 statements."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::doc_lazy_continuation",
@@ -10904,34 +13682,55 @@ statements."##,
 paragraph nested within a list or block quote does not need any line
 after the first one to be indented or marked. The specification calls
 this a lazy paragraph continuation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::doc_link_with_quotes",
         description: r##"Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks)
 outside of code blocks"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::doc_markdown",
         description: r##"Checks for the presence of `_`, `::` or camel-case words
 outside ticks in documentation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::double_comparisons",
         description: r##"Checks for double comparisons that could be simplified to a single expression."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::double_must_use",
         description: r##"Checks for a `#[must_use]` attribute without
 further information on functions and methods that return a type already
 marked as `#[must_use]`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::double_neg",
         description: r##"Detects expressions of the form `--x`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::double_parens",
         description: r##"Checks for unnecessary double parentheses."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::drain_collect",
@@ -10939,43 +13738,76 @@ marked as `#[must_use]`."##,
 
 > Collection in this context refers to any type with a `drain` method:
 > `Vec`, `VecDeque`, `BinaryHeap`, `HashSet`,`HashMap`, `String`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::drop_non_drop",
         description: r##"Checks for calls to `std::mem::drop` with a value that does not implement `Drop`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::duplicate_mod",
         description: r##"Checks for files that are included as modules multiple times."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::duplicate_underscore_argument",
         description: r##"Checks for function arguments having the similar names
 differing by an underscore."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::duplicated_attributes",
         description: r##"Checks for attributes that appear two or more times."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::duration_subsec",
         description: r##"Checks for calculation of subsecond microseconds or milliseconds
 from other `Duration` methods."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::eager_transmute",
         description: r##"Checks for integer validity checks, followed by a transmute that is (incorrectly) evaluated
 eagerly (e.g. using `bool::then_some`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::else_if_without_else",
         description: r##"Checks for usage of if expressions with an `else if` branch,
 but without a final `else` branch."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::empty_docs",
+        description: r##"Detects documentation that is empty."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::empty_docs", description: r##"Detects documentation that is empty."## },
     Lint {
         label: "clippy::empty_drop",
         description: r##"Checks for empty `Drop` implementations."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::empty_enum",
@@ -10984,271 +13816,458 @@ but without a final `else` branch."##,
 
 As of this writing, the `never_type` is still a nightly-only experimental API.
 Therefore, this lint is only triggered if `#![feature(never_type)]` is enabled."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::empty_enum_variants_with_brackets",
         description: r##"Finds enum variants without fields that are declared with empty brackets."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::empty_line_after_doc_comments",
-        description: r##"Checks for empty lines after documentation comments."##,
+        description: r##"Checks for empty lines after doc comments."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::empty_line_after_outer_attr",
         description: r##"Checks for empty lines after outer attributes"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::empty_loop",
+        description: r##"Checks for empty `loop` expressions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::empty_loop", description: r##"Checks for empty `loop` expressions."## },
     Lint {
         label: "clippy::empty_structs_with_brackets",
         description: r##"Finds structs without fields (a so-called empty struct) that are declared with brackets."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::enum_clike_unportable_variant",
         description: r##"Checks for C-like enumerations that are
 `repr(isize/usize)` and have values that don't fit into an `i32`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::enum_glob_use",
+        description: r##"Checks for `use Enum::*`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::enum_glob_use", description: r##"Checks for `use Enum::*`."## },
     Lint {
         label: "clippy::enum_variant_names",
         description: r##"Detects enumeration variants that are prefixed or suffixed
 by the same characters."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::eq_op",
         description: r##"Checks for equal operands to comparison, logical and
 bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
 `||`, `&`, `|`, `^`, `-` and `/`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::equatable_if_let",
         description: r##"Checks for pattern matchings that can be expressed using equality."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::erasing_op",
         description: r##"Checks for erasing operations, e.g., `x * 0`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::err_expect",
         description: r##"Checks for `.err().expect()` calls on the `Result` type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::error_impl_error",
         description: r##"Checks for types named `Error` that implement `Error`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::excessive_nesting",
         description: r##"Checks for blocks which are nested beyond a certain threshold.
 
 Note: Even though this lint is warn-by-default, it will only trigger if a maximum nesting level is defined in the clippy.toml file."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::excessive_precision",
         description: r##"Checks for float literals with a precision greater
 than that supported by the underlying type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::exhaustive_enums",
         description: r##"Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::exhaustive_structs",
         description: r##"Warns on any exported `struct`s that are not tagged `#[non_exhaustive]`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::exit",
         description: r##"Detects calls to the `exit()` function which terminates the program."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::expect_fun_call",
         description: r##"Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,
 etc., and suggests to use `unwrap_or_else` instead"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::expect_used",
         description: r##"Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::expl_impl_clone_on_copy",
         description: r##"Checks for explicit `Clone` implementations for `Copy`
 types."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::explicit_auto_deref",
         description: r##"Checks for dereferencing expressions which would be covered by auto-deref."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::explicit_counter_loop",
         description: r##"Checks `for` loops over slices with an explicit counter
 and suggests the use of `.enumerate()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::explicit_deref_methods",
         description: r##"Checks for explicit `deref()` or `deref_mut()` method calls."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::explicit_into_iter_loop",
         description: r##"Checks for loops on `y.into_iter()` where `y` will do, and
 suggests the latter."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::explicit_iter_loop",
         description: r##"Checks for loops on `x.iter()` where `&x` will do, and
 suggests the latter."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::explicit_write",
         description: r##"Checks for usage of `write!()` / `writeln()!` which can be
 replaced with `(e)print!()` / `(e)println!()`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::extend_from_slice",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::extend_with_drain",
         description: r##"Checks for occurrences where one vector gets extended instead of append"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::extra_unused_lifetimes",
         description: r##"Checks for lifetimes in generics that are never used
 anywhere else."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::extra_unused_type_parameters",
         description: r##"Checks for type parameters in generics that are never used anywhere else."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::fallible_impl_from",
         description: r##"Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::field_reassign_with_default",
         description: r##"Checks for immediate reassignment of fields initialized
 with Default::default()."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::field_scoped_visibility_modifiers",
         description: r##"Checks for usage of scoped visibility modifiers, like `pub(crate)`, on fields. These
 make a field visible within a scope between public and private."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::filetype_is_file",
         description: r##"Checks for `FileType::is_file()`."##,
-    },
-    Lint {
-        label: "clippy::filter_map",
-        description: r##"Nothing. This lint has been deprecated."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::filter_map_bool_then",
         description: r##"Checks for usage of `bool::then` in `Iterator::filter_map`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::filter_map_identity",
         description: r##"Checks for usage of `filter_map(|x| x)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::filter_map_next",
         description: r##"Checks for usage of `_.filter_map(_).next()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::filter_next",
         description: r##"Checks for usage of `_.filter(_).next()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::find_map", description: r##"Nothing. This lint has been deprecated."## },
     Lint {
         label: "clippy::flat_map_identity",
         description: r##"Checks for usage of `flat_map(|x| x)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::flat_map_option",
         description: r##"Checks for usage of `Iterator::flat_map()` where `filter_map()` could be
 used instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::float_arithmetic",
+        description: r##"Checks for float arithmetic."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::float_arithmetic", description: r##"Checks for float arithmetic."## },
     Lint {
         label: "clippy::float_cmp",
         description: r##"Checks for (in-)equality comparisons on floating-point
 values (apart from zero), except in functions called `*eq*` (which probably
 implement equality for a type involving floats)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::float_cmp_const",
         description: r##"Checks for (in-)equality comparisons on constant floating-point
 values (apart from zero), except in functions called `*eq*` (which probably
 implement equality for a type involving floats)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::float_equality_without_abs",
         description: r##"Checks for statements of the form `(a - b) < f32::EPSILON` or
 `(a - b) < f64::EPSILON`. Notes the missing `.abs()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::fn_address_comparisons",
         description: r##"Checks for comparisons with an address of a function item."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::fn_params_excessive_bools",
         description: r##"Checks for excessive use of
 bools in function definitions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::fn_to_numeric_cast",
         description: r##"Checks for casts of function pointers to something other than `usize`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::fn_to_numeric_cast_any",
         description: r##"Checks for casts of a function pointer to any integer type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::fn_to_numeric_cast_with_truncation",
         description: r##"Checks for casts of a function pointer to a numeric type not wide enough to
 store an address."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::for_kv_map",
         description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and
 ignoring either the keys or values."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::forget_non_drop",
         description: r##"Checks for calls to `std::mem::forget` with a value that does not implement `Drop`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::format_collect",
         description: r##"Checks for usage of `.map(|_| format!(..)).collect::<String>()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::format_in_format_args",
         description: r##"Detects `format!` within the arguments of another macro that does
 formatting such as `format!` itself, `write!` or `println!`. Suggests
 inlining the `format!` call."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::format_push_string",
         description: r##"Detects cases where the result of a `format!` call is
 appended to an existing `String`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::four_forward_slashes",
         description: r##"Checks for outer doc comments written with 4 forward slashes (`////`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::from_iter_instead_of_collect",
         description: r##"Checks for `from_iter()` function calls on types that implement the `FromIterator`
 trait."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::from_over_into",
         description: r##"Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::from_raw_with_void_ptr",
         description: r##"Checks if we're passing a `c_void` raw pointer to `{Box,Rc,Arc,Weak}::from_raw(_)`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::from_str_radix_10",
         description: r##"Checks for function invocations of the form `primitive::from_str_radix(s, 10)`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::future_not_send",
@@ -11256,60 +14275,92 @@ trait."##,
 functions and methods to implement the `Send` marker trait. It is mostly
 used by library authors (public and internal) that target an audience where
 multithreaded executors are likely to be used for running these Futures."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::get_first",
         description: r##"Checks for usage of `x.get(0)` instead of
 `x.first()` or `x.front()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::get_last_with_len",
         description: r##"Checks for usage of `x.get(x.len() - 1)` instead of
 `x.last()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::get_unwrap",
         description: r##"Checks for usage of `.get().unwrap()` (or
 `.get_mut().unwrap`) on a standard library type which implements `Index`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::host_endian_bytes",
         description: r##"Checks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::identity_op",
         description: r##"Checks for identity operations, e.g., `x + 0`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::if_let_mutex",
         description: r##"Checks for `Mutex::lock` calls in `if let` expression
 with lock calls in any of the else blocks."##,
-    },
-    Lint {
-        label: "clippy::if_let_redundant_pattern_matching",
-        description: r##"Nothing. This lint has been deprecated."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::if_not_else",
         description: r##"Checks for usage of `!` or `!=` in an if condition with an
 else branch."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::if_same_then_else",
         description: r##"Checks for `if/else` with the same body as the *then* part
 and the *else* part."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::if_then_some_else_none",
         description: r##"Checks for if-else that could be written using either `bool::then` or `bool::then_some`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ifs_same_cond",
         description: r##"Checks for consecutive `if`s with the same condition."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ignored_unit_patterns",
         description: r##"Checks for usage of `_` in patterns of type `()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::impl_hash_borrow_with_str_and_bytes",
@@ -11317,32 +14368,53 @@ and the *else* part."##,
 type that implements all three of `Hash`, `Borrow<str>` and `Borrow<[u8]>`
 as it is impossible to satisfy the semantics of Borrow and `Hash` for
 both `Borrow<str>` and `Borrow<[u8]>`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::impl_trait_in_params",
         description: r##"Lints when `impl Trait` is being used in a function's parameters."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::implicit_clone",
         description: r##"Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::implicit_hasher",
         description: r##"Checks for public `impl` or `fn` missing generalization
 over different hashers and implicitly defaulting to the default hashing
 algorithm (`SipHash`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::implicit_return",
         description: r##"Checks for missing return statements at the end of a block."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::implicit_saturating_add",
         description: r##"Checks for implicit saturating addition."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::implicit_saturating_sub",
         description: r##"Checks for implicit saturating subtraction."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::implied_bounds_in_impls",
@@ -11350,43 +14422,67 @@ algorithm (`SipHash`)."##,
 This can happen when a trait is specified that another trait already has as a supertrait
 (e.g. `fn() -> impl Deref + DerefMut<Target = i32>` has an unnecessary `Deref` bound,
 because `Deref` is a supertrait of `DerefMut`)"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::impossible_comparisons",
         description: r##"Checks for double comparisons that can never succeed"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::imprecise_flops",
         description: r##"Looks for floating-point expressions that
 can be expressed using built-in methods to improve accuracy
 at the cost of performance."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::incompatible_msrv",
         description: r##"This lint checks that no function newer than the defined MSRV (minimum
 supported rust version) is used in the crate."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inconsistent_digit_grouping",
         description: r##"Warns if an integral or floating-point constant is
 grouped inconsistently with underscores."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inconsistent_struct_constructor",
         description: r##"Checks for struct constructors where all fields are shorthand and
 the order of the field init shorthand in the constructor is inconsistent
 with the order in the struct definition."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::index_refutable_slice",
         description: r##"The lint checks for slice bindings in patterns that are only used to
 access individual slice values."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::indexing_slicing",
         description: r##"Checks for usage of indexing or slicing. Arrays are special cases, this lint
 does report on arrays if we can tell that slicing operations are in bounds and does not
 lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ineffective_bit_mask",
@@ -11398,241 +14494,417 @@ following table:
 |----------|----------|------------|-------|
 |`>` / `<=`|`\\|` / `^`|`x \\| 2 > 3`|`x > 3`|
 |`<` / `>=`|`\\|` / `^`|`x ^ 1 < 4` |`x < 4`|"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ineffective_open_options",
         description: r##"Checks if both `.write(true)` and `.append(true)` methods are called
 on a same `OpenOptions`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inefficient_to_string",
         description: r##"Checks for usage of `.to_string()` on an `&&T` where
 `T` implements `ToString` directly (like `&&str` or `&&String`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::infallible_destructuring_match",
         description: r##"Checks for matches being used to destructure a single-variant enum
 or tuple struct where a `let` will suffice."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::infinite_iter",
         description: r##"Checks for iteration that is guaranteed to be infinite."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::infinite_loop",
         description: r##"Checks for infinite loops in a function where the return type is not `!`
 and lint accordingly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inherent_to_string",
         description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inherent_to_string_shadow_display",
         description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::init_numbered_fields",
         description: r##"Checks for tuple structs initialized with field syntax.
 It will however not lint if a base initializer is present.
 The lint will also ignore code in macros."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inline_always",
         description: r##"Checks for items annotated with `#[inline(always)]`,
 unless the annotated function is empty or simply panics."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inline_asm_x86_att_syntax",
         description: r##"Checks for usage of AT&T x86 assembly syntax."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inline_asm_x86_intel_syntax",
         description: r##"Checks for usage of Intel x86 assembly syntax."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inline_fn_without_body",
         description: r##"Checks for `#[inline]` on trait methods without bodies"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::inspect_for_each",
         description: r##"Checks for usage of `inspect().for_each()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::int_plus_one",
         description: r##"Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::integer_division",
+        description: r##"Checks for division of integers"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::integer_division", description: r##"Checks for division of integers"## },
     Lint {
         label: "clippy::integer_division_remainder_used",
         description: r##"Checks for the usage of division (`/`) and remainder (`%`) operations
 when performed on any integer types using the default `Div` and `Rem` trait implementations."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::into_iter_on_ref",
         description: r##"Checks for `into_iter` calls on references which should be replaced by `iter`
 or `iter_mut`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::into_iter_without_iter",
         description: r##"This is the opposite of the `iter_without_into_iter` lint.
 It looks for `IntoIterator for (&|&mut) Type` implementations without an inherent `iter` or `iter_mut` method
 on the type or on any of the types in its `Deref` chain."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::invalid_null_ptr_usage",
         description: r##"This lint checks for invalid usages of `ptr::null`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::invalid_regex",
         description: r##"Checks [regex](https://crates.io/crates/regex) creation
 (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct
 regex syntax."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::invalid_upcast_comparisons",
         description: r##"Checks for comparisons where the relation is always either
 true or false, but where one side has been upcast so that the comparison is
 necessary. Only integer types are checked."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::inverted_saturating_sub",
+        description: r##"Checks for comparisons between integers, followed by subtracting the greater value from the
+lower one."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::invisible_characters",
         description: r##"Checks for invisible Unicode characters in the code."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::is_digit_ascii_radix",
         description: r##"Finds usages of [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) that
 can be replaced with [`is_ascii_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_digit) or
 [`is_ascii_hexdigit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_hexdigit)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::items_after_statements",
         description: r##"Checks for items declared after some statement in a block."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::items_after_test_module",
         description: r##"Triggers if an item is declared after the testing module marked with `#[cfg(test)]`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_cloned_collect",
         description: r##"Checks for the use of `.cloned().collect()` on slice to
 create a `Vec`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_count",
         description: r##"Checks for the use of `.iter().count()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_filter_is_ok",
         description: r##"Checks for usage of `.filter(Result::is_ok)` that may be replaced with a `.flatten()` call.
 This lint will require additional changes to the follow-up calls as it affects the type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_filter_is_some",
         description: r##"Checks for usage of `.filter(Option::is_some)` that may be replaced with a `.flatten()` call.
 This lint will require additional changes to the follow-up calls as it affects the type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_kv_map",
         description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and
 ignoring either the keys or values."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::iter_next_loop",
+        description: r##"Checks for loops on `x.next()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::iter_next_loop", description: r##"Checks for loops on `x.next()`."## },
     Lint {
         label: "clippy::iter_next_slice",
         description: r##"Checks for usage of `iter().next()` on a Slice or an Array"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_not_returning_iterator",
         description: r##"Detects methods named `iter` or `iter_mut` that do not have a return type that implements `Iterator`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_nth",
         description: r##"Checks for usage of `.iter().nth()`/`.iter_mut().nth()` on standard library types that have
 equivalent `.get()`/`.get_mut()` methods."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_nth_zero",
         description: r##"Checks for the use of `iter.nth(0)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_on_empty_collections",
         description: r##"Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_on_single_items",
         description: r##"Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_out_of_bounds",
         description: r##"Looks for iterator combinator calls such as `.take(x)` or `.skip(x)`
 where `x` is greater than the amount of items that an iterator will produce."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_over_hash_type",
         description: r##"This is a restriction lint which prevents the use of hash types (i.e., `HashSet` and `HashMap`) in for loops."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_overeager_cloned",
         description: r##"Checks for usage of `_.cloned().<func>()` where call to `.cloned()` can be postponed."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_skip_next",
         description: r##"Checks for usage of `.skip(x).next()` on iterators."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_skip_zero",
         description: r##"Checks for usage of `.skip(0)` on iterators."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_with_drain",
         description: r##"Checks for usage of `.drain(..)` on `Vec` and `VecDeque` for iteration."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iter_without_into_iter",
         description: r##"Looks for `iter` and `iter_mut` methods without an associated `IntoIterator for (&|&mut) Type` implementation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::iterator_step_by_zero",
         description: r##"Checks for calling `.step_by(0)` on iterators which panics."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::join_absolute_paths",
         description: r##"Checks for calls to `Path::join` that start with a path separator (`\\\\` or `/`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::just_underscores_and_digits",
         description: r##"Checks if you have variables whose name consists of just
 underscores and digits."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_const_arrays",
         description: r##"Checks for large `const` arrays that should
 be defined as `static` instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_digit_groups",
         description: r##"Warns if the digits of an integral or floating-point
 constant are grouped into groups that
 are too large."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_enum_variant",
         description: r##"Checks for large size differences between variants on
 `enum`s."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_futures",
         description: r##"It checks for the size of a `Future` created by `async fn` or `async {}`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_include_file",
         description: r##"Checks for the inclusion of large files via `include_bytes!()`
 or `include_str!()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_stack_arrays",
         description: r##"Checks for local arrays that may be too large."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_stack_frames",
@@ -11643,6 +14915,9 @@ or constructing *many* smaller-but-still-large structs, or copying around a lot
 
 This lint is a more general version of [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/#large_stack_arrays)
 that is intended to look at functions as a whole instead of only individual array expressions inside of a function."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::large_types_passed_by_value",
@@ -11651,60 +14926,102 @@ the argument type is `Copy` and large enough to be worth considering
 passing by reference. Does not trigger if the function is being exported,
 because that might induce API breakage, if the parameter is declared as mutable,
 or if the argument is a `self`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::legacy_numeric_constants",
         description: r##"Checks for usage of `<integer>::max_value()`, `std::<integer>::MAX`,
 `std::<float>::EPSILON`, etc."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::len_without_is_empty",
         description: r##"Checks for items that implement `.len()` but not
 `.is_empty()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::len_zero",
         description: r##"Checks for getting the length of something via `.len()`
 just to compare to zero, and suggests using `.is_empty()` where applicable."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::let_and_return",
         description: r##"Checks for `let`-bindings, which are subsequently
 returned."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::let_underscore_future",
         description: r##"Checks for `let _ = <expr>` where the resulting type of expr implements `Future`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::let_underscore_lock",
         description: r##"Checks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in
 `parking_lot`. For `std` locks see the `rustc` lint
 [`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::let_underscore_must_use",
         description: r##"Checks for `let _ = <expr>` where expr is `#[must_use]`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::let_underscore_untyped",
         description: r##"Checks for `let _ = <expr>` without a type annotation, and suggests to either provide one,
 or remove the `let` keyword altogether."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::let_unit_value",
+        description: r##"Checks for binding a unit value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::let_unit_value", description: r##"Checks for binding a unit value."## },
     Lint {
         label: "clippy::let_with_type_underscore",
         description: r##"Detects when a variable is declared with an explicit type of `_`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::lines_filter_map_ok",
         description: r##"Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)`
 when `lines` has type `std::io::Lines`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::linkedlist",
         description: r##"Checks for usage of any `LinkedList`, suggesting to use a
 `Vec` or a `VecDeque` (formerly called `RingBuf`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::lint_groups_priority",
@@ -11713,286 +15030,488 @@ when `lines` has type `std::io::Lines`."##,
 
 This lint will be removed once [cargo#12918](https://github.com/rust-lang/cargo/issues/12918)
 is resolved."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::little_endian_bytes",
         description: r##"Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::lossy_float_literal",
         description: r##"Checks for whole number float literals that
 cannot be represented as the underlying type without loss."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::macro_metavars_in_unsafe",
         description: r##"Looks for macros that expand metavariables in an unsafe block."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::macro_use_imports",
         description: r##"Checks for `#[macro_use] use...`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::main_recursion",
         description: r##"Checks for recursion using the entrypoint."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_assert",
         description: r##"Detects `if`-then-`panic!` that can be replaced with `assert!`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_async_fn",
         description: r##"It checks for manual implementations of `async` functions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_bits",
         description: r##"Checks for usage of `std::mem::size_of::<T>() * 8` when
 `T::BITS` is available."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_c_str_literals",
         description: r##"Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either
 through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()`
 on a (byte) string literal with a hardcoded `\\0` byte at the end."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_clamp",
         description: r##"Identifies good opportunities for a clamp function from std or core, and suggests using it."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::manual_div_ceil",
+        description: r##"Checks for an expression like `(x + (y - 1)) / y` which is a common manual reimplementation
+of `x.div_ceil(y)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_filter",
         description: r##"Checks for usage of `match` which could be implemented using `filter`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_filter_map",
         description: r##"Checks for usage of `_.filter(_).map(_)` that can be written more simply
 as `filter_map(_)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_find",
         description: r##"Checks for manual implementations of Iterator::find"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_find_map",
         description: r##"Checks for usage of `_.find(_).map(_)` that can be written more simply
 as `find_map(_)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_flatten",
         description: r##"Checks for unnecessary `if let` usage in a for loop
 where only the `Some` or `Ok` variant of the iterator element is used."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_hash_one",
         description: r##"Checks for cases where [`BuildHasher::hash_one`] can be used.
 
 [`BuildHasher::hash_one`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html#method.hash_one"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_inspect",
         description: r##"Checks for uses of `map` which return the original item."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_instant_elapsed",
         description: r##"Lints subtraction between `Instant::now()` and another `Instant`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_is_ascii_check",
         description: r##"Suggests to use dedicated built-in methods,
 `is_ascii_(lowercase|uppercase|digit|hexdigit)` for checking on corresponding
 ascii range"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_is_finite",
         description: r##"Checks for manual `is_finite` reimplementations
 (i.e., `x != <float>::INFINITY && x != <float>::NEG_INFINITY`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_is_infinite",
         description: r##"Checks for manual `is_infinite` reimplementations
 (i.e., `x == <float>::INFINITY || x == <float>::NEG_INFINITY`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::manual_is_power_of_two",
+        description: r##"Checks for expressions like `x.count_ones() == 1` or `x & (x - 1) == 0`, with x and unsigned integer, which are manual
+reimplementations of `x.is_power_of_two()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_is_variant_and",
         description: r##"Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_let_else",
         description: r##"Warn of cases where `let...else` could be used"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_main_separator_str",
         description: r##"Checks for references on `std::path::MAIN_SEPARATOR.to_string()` used
 to build a `&str`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_map",
         description: r##"Checks for usage of `match` which could be implemented using `map`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_memcpy",
         description: r##"Checks for for-loops that manually copy items between
 slices that could be optimized by having a memcpy."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_next_back",
         description: r##"Checks for `.rev().next()` on a `DoubleEndedIterator`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_non_exhaustive",
         description: r##"Checks for manual implementations of the non-exhaustive pattern."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_ok_or",
         description: r##"Finds patterns that reimplement `Option::ok_or`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_pattern_char_comparison",
         description: r##"Checks for manual `char` comparison in string patterns"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_range_contains",
         description: r##"Checks for expressions like `x >= 3 && x < 8` that could
 be more readably expressed as `(3..8).contains(x)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_range_patterns",
         description: r##"Looks for combined OR patterns that are all contained in a specific range,
 e.g. `6 | 4 | 5 | 9 | 7 | 8` can be rewritten as `4..=9`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_rem_euclid",
         description: r##"Checks for an expression like `((x % 4) + 4) % 4` which is a common manual reimplementation
 of `x.rem_euclid(4)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_retain",
         description: r##"Checks for code to be replaced by `.retain()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_rotate",
         description: r##"It detects manual bit rotations that could be rewritten using standard
 functions `rotate_left` or `rotate_right`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_saturating_arithmetic",
         description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_slice_size_calculation",
         description: r##"When `a` is `&[T]`, detect `a.len() * size_of::<T>()` and suggest `size_of_val(a)`
 instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_split_once",
         description: r##"Checks for usage of `str::splitn(2, _)`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_str_repeat",
         description: r##"Checks for manual implementations of `str::repeat`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_string_new",
         description: r##"Checks for usage of `` to create a `String`, such as `.to_string()`, `.to_owned()`,
 `String::from()` and others."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_strip",
         description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using
 the pattern's length."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_swap",
         description: r##"Checks for manual swapping.
 
 Note that the lint will not be emitted in const blocks, as the suggestion would not be applicable."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_try_fold",
         description: r##"Checks for usage of `Iterator::fold` with a type that implements `Try`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_unwrap_or",
         description: r##"Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_unwrap_or_default",
         description: r##"Checks if a `match` or `if let` expression can be simplified using
 `.unwrap_or_default()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::manual_while_let_some",
         description: r##"Looks for loops that check for emptiness of a `Vec` in the condition and pop an element
 in the body as a separate operation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::many_single_char_names",
         description: r##"Checks for too many variables whose name consists of a
 single character."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::map_clone",
         description: r##"Checks for usage of `map(|x| x.clone())` or
 dereferencing closures for `Copy` types, on `Iterator` or `Option`,
 and suggests `cloned()` or `copied()` instead"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::map_collect_result_unit",
         description: r##"Checks for usage of `_.map(_).collect::<Result<(), _>()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::map_entry",
         description: r##"Checks for usage of `contains_key` + `insert` on `HashMap`
 or `BTreeMap`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::map_err_ignore",
         description: r##"Checks for instances of `map_err(|_| Some::Enum)`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::map_flatten",
         description: r##"Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::map_identity",
         description: r##"Checks for instances of `map(f)` where `f` is the identity function."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::map_unwrap_or",
         description: r##"Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or
 `result.map(_).unwrap_or_else(_)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_as_ref",
         description: r##"Checks for match which is used to add a reference to an
 `Option` value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_bool",
         description: r##"Checks for matches where match expression is a `bool`. It
 suggests to replace the expression with an `if...else` block."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_like_matches_macro",
         description: r##"Checks for `match`  or `if let` expressions producing a
 `bool` that could be written using `matches!`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_on_vec_items",
         description: r##"Checks for `match vec[idx]` or `match vec[n..m]`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_overlapping_arm",
         description: r##"Checks for overlapping match arms."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_ref_pats",
         description: r##"Checks for matches where all arms match a reference,
 suggesting to remove the reference and deref the matched expression
 instead. It also checks for `if let &foo = bar` blocks."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_result_ok",
         description: r##"Checks for unnecessary `ok()` in `while let`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_same_arms",
@@ -12000,51 +15519,77 @@ instead. It also checks for `if let &foo = bar` blocks."##,
 
 Note: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is
 enabled and disallowed."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_single_binding",
         description: r##"Checks for useless match that binds to only one value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_str_case_mismatch",
         description: r##"Checks for `match` expressions modifying the case of a string with non-compliant arms"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_wild_err_arm",
         description: r##"Checks for arm which matches all errors with `Err(_)`
 and take drastic actions like `panic!`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::match_wildcard_for_single_variants",
         description: r##"Checks for wildcard enum matches for a single variant."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::maybe_infinite_iter",
         description: r##"Checks for iteration that may be infinite."##,
-    },
-    Lint {
-        label: "clippy::maybe_misused_cfg",
-        description: r##"Nothing. This lint has been deprecated."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mem_forget",
         description: r##"Checks for usage of `std::mem::forget(t)` where `t` is
 `Drop` or has a field that implements `Drop`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mem_replace_option_with_none",
         description: r##"Checks for `mem::replace()` on an `Option` with
 `None`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mem_replace_with_default",
         description: r##"Checks for `std::mem::replace` on a value of type
 `T` with `T::default()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mem_replace_with_uninit",
         description: r##"Checks for `mem::replace(&mut _, mem::uninitialized())`
 and `mem::replace(&mut _, mem::zeroed())`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::min_ident_chars",
@@ -12052,19 +15597,24 @@ and `mem::replace(&mut _, mem::zeroed())`."##,
 
 Note: This lint can be very noisy when enabled; it may be desirable to only enable it
 temporarily."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::min_max",
         description: r##"Checks for expressions where `std::cmp::min` and `max` are
 used to clamp values, but switched so that the result is constant."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::misaligned_transmute",
-        description: r##"Nothing. This lint has been deprecated."##,
-    },
-    Lint {
-        label: "clippy::mismatched_target_os",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mismatching_type_param_order",
@@ -12072,36 +15622,60 @@ used to clamp values, but switched so that the result is constant."##,
 a type definition and impl block. Specifically, a parameter in an impl
 block which has the same name as a parameter in the type def, but is in
 a different place."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::misnamed_getters",
         description: r##"Checks for getter methods that return a field that doesn't correspond
 to the name of the method, when there is a field's whose name matches that of the method."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::misrefactored_assign_op",
         description: r##"Checks for `a op= a op b` or `a op= b op a` patterns."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_assert_message",
         description: r##"Checks assertions without a custom panic message."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_asserts_for_indexing",
         description: r##"Checks for repeated slice indexing without asserting beforehand that the length
 is greater than the largest index used to index into the slice."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_const_for_fn",
         description: r##"Suggests the use of `const` in functions and methods where possible."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_const_for_thread_local",
         description: r##"Suggests to use `const` in `thread_local!` macro if possible."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_docs_in_private_items",
         description: r##"Warns if there is missing documentation for any private documentable item."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_enforced_import_renames",
@@ -12110,108 +15684,192 @@ in the `enforced-import-renames` config option.
 
 Note: Even though this lint is warn-by-default, it will only trigger if
 import renames are defined in the `clippy.toml` file."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_errors_doc",
         description: r##"Checks the doc comments of publicly visible functions that
 return a `Result` type and warns if there is no `# Errors` section."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_fields_in_debug",
         description: r##"Checks for manual [`core::fmt::Debug`](https://doc.rust-lang.org/core/fmt/trait.Debug.html) implementations that do not use all fields."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_inline_in_public_items",
         description: r##"It lints if an exported function, method, trait method with default impl,
 or trait method impl is not `#[inline]`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_panics_doc",
         description: r##"Checks the doc comments of publicly visible functions that
 may panic and warns if there is no `# Panics` section."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_safety_doc",
         description: r##"Checks for the doc comments of publicly visible
 unsafe functions and warns if there is no `# Safety` section."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::missing_spin_loop",
+        description: r##"Checks for empty spin loops"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::missing_spin_loop", description: r##"Checks for empty spin loops"## },
     Lint {
         label: "clippy::missing_trait_methods",
         description: r##"Checks if a provided method is used implicitly by a trait
 implementation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::missing_transmute_annotations",
         description: r##"Checks if transmute calls have all generics specified."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mistyped_literal_suffixes",
         description: r##"Warns for mistyped suffix in literals"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mixed_attributes_style",
         description: r##"Checks for items that have the same kind of attributes with mixed styles (inner/outer)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mixed_case_hex_literals",
         description: r##"Warns on hexadecimal literals with mixed-case letter
 digits."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mixed_read_write_in_expression",
         description: r##"Checks for a read and a write to the same variable where
 whether the read occurs before or after the write depends on the evaluation
 order of sub-expressions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mod_module_files",
         description: r##"Checks that module layout uses only self named module files; bans `mod.rs` files."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::module_inception",
         description: r##"Checks for modules that have the same name as their
 parent module"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::module_name_repetitions",
         description: r##"Detects type names that are prefixed or suffixed by the
 containing module's name."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::modulo_arithmetic",
+        description: r##"Checks for modulo arithmetic."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::modulo_arithmetic", description: r##"Checks for modulo arithmetic."## },
     Lint {
         label: "clippy::modulo_one",
         description: r##"Checks for getting the remainder of integer division by one or minus
 one."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::multi_assignments",
+        description: r##"Checks for nested assignments."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::multi_assignments", description: r##"Checks for nested assignments."## },
     Lint {
         label: "clippy::multiple_bound_locations",
         description: r##"Check if a generic is defined both in the bound predicate and in the `where` clause."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::multiple_crate_versions",
         description: r##"Checks to see if multiple versions of a crate are being
 used."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::multiple_inherent_impl",
         description: r##"Checks for multiple inherent implementations of a struct"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::multiple_unsafe_ops_per_block",
         description: r##"Checks for `unsafe` blocks that contain more than one unsafe operation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::must_use_candidate",
         description: r##"Checks for public functions that have no
 `#[must_use]` attribute, but return something not already marked
 must-use, have no mutable arg and mutate no statics."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::must_use_unit",
         description: r##"Checks for a `#[must_use]` attribute on
 unit-returning functions and methods."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mut_from_ref",
@@ -12221,77 +15879,131 @@ are multiple safe functions which will do this transformation
 
 To be on the conservative side, if there's at least one mutable
 reference with the output lifetime, this lint will not trigger."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mut_mut",
         description: r##"Checks for instances of `mut mut` references."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mut_mutex_lock",
         description: r##"Checks for `&mut Mutex::lock` calls"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mut_range_bound",
         description: r##"Checks for loops with a range bound that is a mutable variable."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mutable_key_type",
         description: r##"Checks for sets/maps with mutable key types."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mutex_atomic",
         description: r##"Checks for usage of `Mutex<X>` where an atomic will do."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::mutex_integer",
         description: r##"Checks for usage of `Mutex<X>` where `X` is an integral
 type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::naive_bytecount",
+        description: r##"Checks for naive byte counts"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::naive_bytecount", description: r##"Checks for naive byte counts"## },
     Lint {
         label: "clippy::needless_arbitrary_self_type",
         description: r##"The lint checks for `self` in fn parameters that
 specify the `Self`-type explicitly"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_bitwise_bool",
         description: r##"Checks for usage of bitwise and/or operators between booleans, where performance may be improved by using
 a lazy and."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_bool",
         description: r##"Checks for expressions of the form `if c { true } else {
 false }` (or vice versa) and suggests using the condition directly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_bool_assign",
         description: r##"Checks for expressions of the form `if c { x = true } else { x = false }`
 (or vice versa) and suggest assigning the variable directly from the
 condition."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_borrow",
         description: r##"Checks for address of operations (`&`) that are going to
 be dereferenced immediately by the compiler."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_borrowed_reference",
         description: r##"Checks for bindings that needlessly destructure a reference and borrow the inner
 value with `&ref`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_borrows_for_generic_args",
         description: r##"Checks for borrow operations (`&`) that are used as a generic argument to a
 function when the borrowed value could be used."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_character_iteration",
         description: r##"Checks if an iterator is used to check if a string is ascii."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_collect",
         description: r##"Checks for functions collecting an iterator when collect
 is not needed."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_continue",
@@ -12299,53 +16011,92 @@ is not needed."##,
 that contain a `continue` statement in either their main blocks or their
 `else`-blocks, when omitting the `else`-block possibly with some
 rearrangement of code can make the code easier to understand."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_doctest_main",
         description: r##"Checks for `fn main() { .. }` in doctests"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::needless_else",
+        description: r##"Checks for empty `else` branches."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::needless_else", description: r##"Checks for empty `else` branches."## },
     Lint {
         label: "clippy::needless_for_each",
         description: r##"Checks for usage of `for_each` that would be more simply written as a
 `for` loop."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_if",
         description: r##"Checks for empty `if` branches with no else branch."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_late_init",
         description: r##"Checks for late initializations that can be replaced by a `let` statement
 with an initializer."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_lifetimes",
         description: r##"Checks for lifetime annotations which can be removed by
 relying on lifetime elision."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_match",
         description: r##"Checks for unnecessary `match` or match-like `if let` returns for `Option` and `Result`
 when function signatures are the same."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_maybe_sized",
         description: r##"Lints `?Sized` bounds applied to type parameters that cannot be unsized"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_option_as_deref",
         description: r##"Checks for no-op uses of `Option::{as_deref, as_deref_mut}`,
 for example, `Option<&T>::as_deref()` returns the same type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_option_take",
         description: r##"Checks for calling `take` function after `as_ref`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_parens_on_range_literals",
         description: r##"The lint checks for parenthesis on literals in range statements that are
 superfluous."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_pass_by_ref_mut",
@@ -12353,45 +16104,75 @@ superfluous."##,
 
 Be careful if the function is publicly reexported as it would break compatibility with
 users of this function, when the users pass this function as an argument."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_pass_by_value",
         description: r##"Checks for functions taking arguments by value, but not
 consuming them in its
 body."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_pub_self",
         description: r##"Checks for usage of `pub(self)` and `pub(in self)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_question_mark",
         description: r##"Suggests alternatives for useless applications of `?` in terminating expressions"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_range_loop",
         description: r##"Checks for looping over the range of `0..len` of some
 collection just to get the values by index."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_raw_string_hashes",
         description: r##"Checks for raw string literals with an unnecessary amount of hashes around them."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_raw_strings",
         description: r##"Checks for raw string literals where a string literal can be used instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_return",
         description: r##"Checks for return statements at the end of a block."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_return_with_question_mark",
         description: r##"Checks for return statements on `Err` paired with the `?` operator."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_splitn",
         description: r##"Checks for usage of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::needless_update",
@@ -12400,70 +16181,118 @@ when all fields are changed anyway.
 
 This lint is not applied to structs marked with
 [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::neg_cmp_op_on_partial_ord",
         description: r##"Checks for the usage of negated comparison operators on types which only implement
 `PartialOrd` (e.g., `f64`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::neg_multiply",
         description: r##"Checks for multiplication by -1 as a form of negation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::negative_feature_names",
         description: r##"Checks for negative feature names with prefix `no-` or `not-`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::never_loop",
         description: r##"Checks for loops that will always `break`, `return` or
 `continue` an outer loop."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::new_ret_no_self",
         description: r##"Checks for `new` not returning a type that contains `Self`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::new_without_default",
         description: r##"Checks for public types with a `pub fn new() -> Self` method and no
 implementation of
 [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::no_effect",
         description: r##"Checks for statements which have no effect."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::no_effect_replace",
         description: r##"Checks for `replace` statements which have no effect."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::no_effect_underscore_binding",
         description: r##"Checks for binding to underscore prefixed variable without side-effects."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::no_mangle_with_rust_abi",
         description: r##"Checks for Rust ABI functions with the `#[no_mangle]` attribute."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::non_ascii_literal",
         description: r##"Checks for non-ASCII characters in string and char literals."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::non_canonical_clone_impl",
         description: r##"Checks for non-canonical implementations of `Clone` when `Copy` is already implemented."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::non_canonical_partial_ord_impl",
         description: r##"Checks for non-canonical implementations of `PartialOrd` when `Ord` is already implemented."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::non_minimal_cfg",
         description: r##"Checks for `any` and `all` combinators in `cfg` with only one condition."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::non_octal_unix_permissions",
         description: r##"Checks for non-octal values used to set Unix file permissions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::non_send_fields_in_send_ty",
@@ -12472,63 +16301,116 @@ contains fields that are not safe to be sent across threads.
 It tries to detect fields that can cause a soundness issue
 when sent to another thread (e.g., `Rc`) while allowing `!Send` fields
 that are expected to exist in a `Send` type, such as raw pointers."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::non_zero_suggestions",
+        description: r##"Checks for conversions from `NonZero` types to regular integer types,
+and suggests using `NonZero` types for the target as well."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::nonminimal_bool",
         description: r##"Checks for boolean expressions that can be written more
 concisely."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::nonsensical_open_options",
         description: r##"Checks for duplicate open options as well as combinations
 that make no sense."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::nonstandard_macro_braces",
         description: r##"Checks that common macros are used with consistent bracing."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::not_unsafe_ptr_arg_deref",
         description: r##"Checks for public functions that dereference raw pointer
 arguments but are not marked `unsafe`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::obfuscated_if_else",
         description: r##"Checks for usage of `.then_some(..).unwrap_or(..)`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::octal_escapes",
         description: r##"Checks for `\\0` escapes in string and byte literals that look like octal
 character escapes in C."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::ok_expect",
+        description: r##"Checks for usage of `ok().expect(..)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::ok_expect", description: r##"Checks for usage of `ok().expect(..)`."## },
     Lint {
         label: "clippy::only_used_in_recursion",
         description: r##"Checks for arguments that are only used in recursion with no side-effects."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::op_ref",
         description: r##"Checks for arguments to `==` which have their address
 taken to satisfy a bound
 and suggests to dereference the other argument instead"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_as_ref_cloned",
         description: r##"Checks for usage of `.as_ref().cloned()` and `.as_mut().cloned()` on `Option`s"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_as_ref_deref",
         description: r##"Checks for usage of `_.as_ref().map(Deref::deref)` or its aliases (such as String::as_str)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_env_unwrap",
         description: r##"Checks for usage of `option_env!(...).unwrap()` and
 suggests usage of the `env!` macro."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_filter_map",
         description: r##"Checks for iterators of `Option`s using `.filter(Option::is_some).map(Option::unwrap)` that may
 be replaced with a `.flatten()` call."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_if_let_else",
@@ -12537,24 +16419,39 @@ be replaced with a `.flatten()` call."##,
 idiomatically done with `Option::map_or` (if the else bit is a pure
 expression) or `Option::map_or_else` (if the else bit is an impure
 expression)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_map_or_err_ok",
         description: r##"Checks for usage of `_.map_or(Err(_), Ok)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_map_or_none",
         description: r##"Checks for usage of `_.map_or(None, _)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_map_unit_fn",
         description: r##"Checks for usage of `option.map(f)` where f is a function
 or closure that returns the unit type `()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::option_option",
         description: r##"Checks for usage of `Option<Option<_>>` in function signatures and type
 definitions"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::or_fun_call",
@@ -12562,52 +16459,91 @@ definitions"##,
 `.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`,
 `.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()`
 etc. instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::or_then_unwrap",
         description: r##"Checks for `.or(…).unwrap()` calls to Options and Results."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::out_of_bounds_indexing",
         description: r##"Checks for out of bounds array indexing with a constant
 index."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::overly_complex_bool_expr",
         description: r##"Checks for boolean expressions that contain terminals that
 can be eliminated."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::panic",
+        description: r##"Checks for usage of `panic!`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::panic", description: r##"Checks for usage of `panic!`."## },
     Lint {
         label: "clippy::panic_in_result_fn",
         description: r##"Checks for usage of `panic!` or assertions in a function whose return type is `Result`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::panicking_overflow_checks",
         description: r##"Detects C-style underflow/overflow checks."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::panicking_unwrap",
         description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::partial_pub_fields",
         description: r##"Checks whether some but not all fields of a `struct` are public.
 
 Either make all fields of a type public, or make none of them public"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::partialeq_ne_impl",
         description: r##"Checks for manual re-implementations of `PartialEq::ne`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::partialeq_to_none",
         description: r##"Checks for binary comparisons to a literal `Option::None`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::path_buf_push_overwrite",
         description: r##"* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)
 calls on `PathBuf` that can cause overwrites."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::path_ends_with_ext",
@@ -12617,10 +16553,16 @@ By default, Clippy has a short list of known filenames that start with a dot
 but aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default.
 The `allowed-dotfiles` configuration can be used to allow additional
 file extensions that Clippy should not lint."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::pathbuf_init_then_push",
         description: r##"Checks for calls to `push` immediately after creating a new `PathBuf`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::pattern_type_mismatch",
@@ -12642,90 +16584,157 @@ and reference semantics in your code. The available tooling would expose these t
 in a general way even outside of the various pattern matching mechanics. Of course
 this lint can still be used to highlight areas of interest and ensure a good understanding
 of ownership semantics."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::permissions_set_readonly_false",
         description: r##"Checks for calls to `std::fs::Permissions.set_readonly` with argument `false`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::pointers_in_nomem_asm_block",
+        description: r##"Checks if any pointer is being passed to an asm! block with `nomem` option."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::possible_missing_comma",
         description: r##"Checks for possible missing comma in an array. It lints if
 an array element is a binary operator expression and it lies on two lines."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::precedence",
         description: r##"Checks for operations where precedence may be unclear
 and suggests to add parentheses. Currently it catches the following:
 * mixed usage of arithmetic and bit shifting/combining operators without
-parentheses
-* a negative numeric literal (which is really a unary `-` followed by a
-numeric literal)
-  followed by a method call"##,
+parentheses"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::print_in_format_impl",
         description: r##"Checks for usage of `println`, `print`, `eprintln` or `eprint` in an
 implementation of a formatting trait."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::print_literal",
         description: r##"This lint warns about the use of literals as `print!`/`println!` args."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::print_stderr",
         description: r##"Checks for printing on *stderr*. The purpose of this lint
 is to catch debugging remnants."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::print_stdout",
         description: r##"Checks for printing on *stdout*. The purpose of this lint
 is to catch debugging remnants."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::print_with_newline",
         description: r##"This lint warns when you use `print!()` with a format
 string that ends in a newline."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::println_empty_string",
         description: r##"This lint warns when you use `println!()` to
 print a newline."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ptr_arg",
         description: r##"This lint checks for function arguments of type `&String`, `&Vec`,
 `&PathBuf`, and `Cow<_>`. It will also suggest you replace `.clone()` calls
 with the appropriate `.to_owned()`/`to_string()` calls."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ptr_as_ptr",
         description: r##"Checks for `as` casts between raw pointers that don't change their
 constness, namely `*const T` to `*const U` and `*mut T` to `*mut U`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ptr_cast_constness",
         description: r##"Checks for `as` casts between raw pointers that change their constness, namely `*const T` to
 `*mut T` and `*mut T` to `*const T`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::ptr_eq",
+        description: r##"Use `std::ptr::eq` when applicable"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::ptr_eq", description: r##"Use `std::ptr::eq` when applicable"## },
     Lint {
         label: "clippy::ptr_offset_with_cast",
         description: r##"Checks for usage of the `offset` pointer method with a `usize` casted to an
 `isize`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::pub_enum_variant_names",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::pub_underscore_fields",
         description: r##"Checks whether any field of the struct is prefixed with an `_` (underscore) and also marked
 `pub` (public)"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::pub_use",
+        description: r##"Restricts the usage of `pub use ...`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::pub_use", description: r##"Restricts the usage of `pub use ...`"## },
     Lint {
         label: "clippy::pub_with_shorthand",
         description: r##"Checks for usage of `pub(<loc>)` with `in`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::pub_without_shorthand",
@@ -12733,180 +16742,310 @@ constness, namely `*const T` to `*const U` and `*mut T` to `*mut U`."##,
 
 Note: As you cannot write a module's path in `pub(<loc>)`, this will only trigger on
 `pub(super)` and the like."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::question_mark",
         description: r##"Checks for expressions that could be replaced by the question mark operator."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::question_mark_used",
         description: r##"Checks for expressions that use the question mark operator and rejects them."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::range_minus_one",
         description: r##"Checks for inclusive ranges where 1 is subtracted from
 the upper bound, e.g., `x..=(y-1)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::range_plus_one",
         description: r##"Checks for exclusive ranges where 1 is added to the
 upper bound, e.g., `x..(y+1)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::range_step_by_zero",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::range_zip_with_len",
         description: r##"Checks for zipping a collection with the range of
 `0.._.len()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::rc_buffer",
         description: r##"Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::rc_clone_in_vec_init",
         description: r##"Checks for reference-counted pointers (`Arc`, `Rc`, `rc::Weak`, and `sync::Weak`)
 in `vec![elem; len]`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::rc_mutex",
+        description: r##"Checks for `Rc<Mutex<T>>`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::rc_mutex", description: r##"Checks for `Rc<Mutex<T>>`."## },
     Lint {
         label: "clippy::read_line_without_trim",
         description: r##"Looks for calls to [`Stdin::read_line`] to read a line from the standard input
 into a string, then later attempting to use that string for an operation that will never
 work for strings with a trailing newline character in it (e.g. parsing into a `i32`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::read_zero_byte_vec",
         description: r##"This lint catches reads into a zero-length `Vec`.
 Especially in the case of a call to `with_capacity`, this lint warns that read
 gets the number of bytes from the `Vec`'s length, not its capacity."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::readonly_write_lock",
         description: r##"Looks for calls to `RwLock::write` where the lock is only used for reading."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::recursive_format_impl",
         description: r##"Checks for format trait implementations (e.g. `Display`) with a recursive call to itself
 which uses `self` as a parameter.
 This is typically done indirectly with the `write!` macro or with `to_string()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_allocation",
         description: r##"Checks for usage of redundant allocations anywhere in the code."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_as_str",
         description: r##"Checks for usage of `as_str()` on a `String` chained with a method available on the `String` itself."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_async_block",
         description: r##"Checks for `async` block that only returns `await` on a future."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_at_rest_pattern",
         description: r##"Checks for `[all @ ..]` patterns."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_clone",
         description: r##"Checks for a redundant `clone()` (and its relatives) which clones an owned
 value that is going to be dropped without further use."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_closure",
         description: r##"Checks for closures which just call another function where
 the function can be called directly. `unsafe` functions, calls where types
 get adjusted or where the callee is marked `#[track_caller]` are ignored."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_closure_call",
         description: r##"Detects closures called in the same expression where they
 are defined."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_closure_for_method_calls",
         description: r##"Checks for closures which only invoke a method on the closure
 argument and can be replaced by referencing the method directly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_comparisons",
         description: r##"Checks for ineffective double comparisons against constants."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_else",
         description: r##"Checks for `else` blocks that can be removed without changing semantics."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_feature_names",
         description: r##"Checks for feature names with prefix `use-`, `with-` or suffix `-support`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_field_names",
         description: r##"Checks for fields in struct literals where shorthands
 could be used."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_guards",
         description: r##"Checks for unnecessary guards in match expressions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_locals",
         description: r##"Checks for redundant redefinitions of local bindings."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_pattern",
         description: r##"Checks for patterns in the form `name @ _`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_pattern_matching",
         description: r##"Lint for redundant pattern matching over `Result`, `Option`,
 `std::task::Poll`, `std::net::IpAddr` or `bool`s"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_pub_crate",
         description: r##"Checks for items declared `pub(crate)` that are not crate visible because they
 are inside a private module."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_slicing",
         description: r##"Checks for redundant slicing expressions which use the full range, and
 do not change the type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_static_lifetimes",
         description: r##"Checks for constants and statics with an explicit `'static` lifetime."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::redundant_type_annotations",
         description: r##"Warns about needless / redundant type annotations."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ref_as_ptr",
         description: r##"Checks for casts of references to pointer using `as`
 and suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ref_binding_to_reference",
         description: r##"Checks for `ref` bindings which create a reference to a reference."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::ref_option",
+        description: r##"Warns when a function signature uses `&Option<T>` instead of `Option<&T>`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ref_option_ref",
         description: r##"Checks for usage of `&Option<&T>`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::ref_patterns",
         description: r##"Checks for usages of the `ref` keyword."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::regex_macro",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::renamed_function_params",
         description: r##"Lints when the name of function parameters from trait impl is
 different than its default implementation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::repeat_once",
@@ -12917,152 +17056,248 @@ different than its default implementation."##,
 
 The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if
 they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::repeat_vec_with_capacity",
         description: r##"Looks for patterns such as `vec![Vec::with_capacity(x); n]` or `iter::repeat(Vec::with_capacity(x))`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::replace_consts",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::reserve_after_initialization",
         description: r##"Informs the user about a more concise way to create a vector with a known capacity."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::rest_pat_in_fully_bound_structs",
         description: r##"Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::result_filter_map",
         description: r##"Checks for iterators of `Result`s using `.filter(Result::is_ok).map(Result::unwrap)` that may
 be replaced with a `.flatten()` call."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::result_large_err",
         description: r##"Checks for functions that return `Result` with an unusually large
 `Err`-variant."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::result_map_or_into_option",
         description: r##"Checks for usage of `_.map_or(None, Some)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::result_map_unit_fn",
         description: r##"Checks for usage of `result.map(f)` where f is a function
 or closure that returns the unit type `()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::result_unit_err",
         description: r##"Checks for public functions that return a `Result`
 with an `Err` type of `()`. It suggests using a custom type that
 implements `std::error::Error`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::return_self_not_must_use",
         description: r##"This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::reversed_empty_ranges",
         description: r##"Checks for range expressions `x..y` where both `x` and `y`
 are constant and `x` is greater to `y`. Also triggers if `x` is equal to `y` when they are conditions to a `for` loop."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::same_functions_in_if_condition",
         description: r##"Checks for consecutive `if`s with the same function call."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::same_item_push",
         description: r##"Checks whether a for loop is being used to push a constant
 value into a Vec."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::same_name_method",
         description: r##"It lints if a struct has two methods with the same name:
 one from a trait, another not from a trait."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::search_is_some",
         description: r##"Checks for an iterator or string search (such as `find()`,
 `position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::seek_from_current",
         description: r##"Checks if the `seek` method of the `Seek` trait is called with `SeekFrom::Current(0)`,
 and if it is, suggests using `stream_position` instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::seek_to_start_instead_of_rewind",
         description: r##"Checks for jumps to the start of a stream that implements `Seek`
 and uses the `seek` method providing `Start` as parameter."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::self_assignment",
         description: r##"Checks for explicit self-assignments."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::self_named_constructors",
         description: r##"Warns when constructors have the same name as their types."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::self_named_module_files",
         description: r##"Checks that module layout uses only `mod.rs` files."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::semicolon_if_nothing_returned",
         description: r##"Looks for blocks of expressions and fires if the last expression returns
 `()` but is not followed by a semicolon."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::semicolon_inside_block",
         description: r##"Suggests moving the semicolon after a block to the inside of the block, after its last
 expression."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::semicolon_outside_block",
         description: r##"Suggests moving the semicolon from a block's final expression outside of the block."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::separated_literal_suffix",
         description: r##"Warns if literal suffixes are separated by an underscore.
 To enforce separated literal suffix style,
 see the `unseparated_literal_suffix` lint."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::serde_api_misuse",
         description: r##"Checks for misuses of the serde API."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::set_contains_or_insert",
-        description: r##"Checks for usage of `contains` to see if a value is not
-present on `HashSet` followed by a `insert`."##,
+        description: r##"Checks for usage of `contains` to see if a value is not present
+in a set like `HashSet` or `BTreeSet`, followed by an `insert`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::shadow_reuse",
         description: r##"Checks for bindings that shadow other bindings already in
 scope, while reusing the original value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::shadow_same",
         description: r##"Checks for bindings that shadow other bindings already in
 scope, while just changing reference level or mutability."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::shadow_unrelated",
         description: r##"Checks for bindings that shadow other bindings already in
 scope, either without an initialization or with one that does not even use
 the original value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::short_circuit_statement",
         description: r##"Checks for the use of short circuit boolean conditions as
 a
 statement."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::should_assert_eq",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::should_implement_trait",
@@ -13070,21 +17305,33 @@ statement."##,
 implementation of a `std` trait (see [llogiq's blog
 post](http://llogiq.github.io/2015/07/30/traits.html) for further
 information) instead of an inherent implementation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::should_panic_without_expect",
         description: r##"Checks for `#[should_panic]` attributes without specifying the expected panic message."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::significant_drop_in_scrutinee",
         description: r##"Checks for temporaries returned from function calls in a match scrutinee that have the
 `clippy::has_significant_drop` attribute."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::significant_drop_tightening",
         description: r##"Searches for elements marked with `#[clippy::has_significant_drop]` that could be early
 dropped but are in fact dropped at the end of their scopes. In other words, enforces the
 tightening of their possible lifetimes."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::similar_names",
@@ -13093,33 +17340,54 @@ tightening of their possible lifetimes."##,
 Note: this lint looks for similar names throughout each
 scope. To allow it, you need to allow it on the scope
 level, not on the name that is reported."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_call_fn",
         description: r##"Checks for functions that are only used once. Does not lint tests."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_char_add_str",
         description: r##"Warns when using `push_str`/`insert_str` with a single-character string literal
 where `push`/`insert` with a `char` would work fine."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_char_lifetime_names",
         description: r##"Checks for lifetimes with names which are one character
 long."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_char_pattern",
         description: r##"Checks for string methods that receive a single-character
 `str` as an argument, e.g., `_.split(x)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_component_path_imports",
         description: r##"Checking for imports with single component use path."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_element_loop",
         description: r##"Checks whether a for loop has a single element."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_match",
@@ -13130,337 +17398,572 @@ This intentionally does not lint if there are comments
 inside of the other arm, so as to allow the user to document
 why having another explicit pattern with an empty body is necessary,
 or because the comments need to be preserved for other reasons."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_match_else",
         description: r##"Checks for matches with two arms where an `if let else` will
 usually suffice."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::single_range_in_vec_init",
         description: r##"Checks for `Vec` or array initializations that contain only one range."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::size_of_in_element_count",
         description: r##"Detects expressions where
 `size_of::<T>` or `size_of_val::<T>` is used as a
 count of elements of type `T`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::size_of_ref",
         description: r##"Checks for calls to `std::mem::size_of_val()` where the argument is
 a reference to a reference."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::skip_while_next",
         description: r##"Checks for usage of `_.skip_while(condition).next()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::slow_vector_initialization",
         description: r##"Checks slow zero-filled vector initialization"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::stable_sort_primitive",
         description: r##"When sorting primitive values (integers, bools, chars, as well
 as arrays, slices, and tuples of such items), it is typically better to
 use an unstable sort than a stable sort."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::std_instead_of_alloc",
         description: r##"Finds items imported through `std` when available through `alloc`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::std_instead_of_core",
         description: r##"Finds items imported through `std` when available through `core`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::str_split_at_newline",
         description: r##"Checks for usages of `str.trim().split(\
 )` and `str.trim().split(\\
 )`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::str_to_string",
         description: r##"This lint checks for `.to_string()` method calls on values of type `&str`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_add",
         description: r##"Checks for all instances of `x + _` where `x` is of type
 `String`, but only if [`string_add_assign`](#string_add_assign) does *not*
 match."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_add_assign",
         description: r##"Checks for string appends of the form `x = x + y` (without
 `let`!)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_extend_chars",
         description: r##"Checks for the use of `.extend(s.chars())` where s is a
 `&str` or `String`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_from_utf8_as_bytes",
         description: r##"Check if the string is transformed to byte array and casted back to string."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_lit_as_bytes",
         description: r##"Checks for the `as_bytes` method called on string literals
 that contain only ASCII characters."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_lit_chars_any",
         description: r##"Checks for `<string_lit>.chars().any(|i| i == c)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_slice",
         description: r##"Checks for slice operations on strings"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::string_to_string",
         description: r##"This lint checks for `.to_string()` method calls on values of type `String`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::strlen_on_c_strings",
         description: r##"Checks for usage of `libc::strlen` on a `CString` or `CStr` value,
 and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::struct_excessive_bools",
         description: r##"Checks for excessive
 use of bools in structs."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::struct_field_names",
         description: r##"Detects struct fields that are prefixed or suffixed
 by the same characters or the name of the struct itself."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suboptimal_flops",
         description: r##"Looks for floating-point expressions that
 can be expressed using built-in methods to improve both
 accuracy and performance."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_arithmetic_impl",
         description: r##"Lints for suspicious operations in impls of arithmetic operators, e.g.
 subtracting elements in an Add impl."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_assignment_formatting",
         description: r##"Checks for usage of the non-existent `=*`, `=!` and `=-`
 operators."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_command_arg_space",
         description: r##"Checks for `Command::arg()` invocations that look like they
 should be multiple arguments instead, such as `arg(-t ext2)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_doc_comments",
         description: r##"Detects the use of outer doc comments (`///`, `/**`) followed by a bang (`!`): `///!`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_else_formatting",
         description: r##"Checks for formatting of `else`. It lints if the `else`
 is followed immediately by a newline or the `else` seems to be missing."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_map",
         description: r##"Checks for calls to `map` followed by a `count`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_op_assign_impl",
         description: r##"Lints for suspicious operations in impls of OpAssign, e.g.
 subtracting elements in an AddAssign impl."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_open_options",
         description: r##"Checks for the suspicious use of `OpenOptions::create()`
 without an explicit `OpenOptions::truncate()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_operation_groupings",
         description: r##"Checks for unlikely usages of binary operators that are almost
 certainly typos and/or copy/paste errors, given the other usages
 of binary operators nearby."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_splitn",
         description: r##"Checks for calls to [`splitn`]
 (https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and
 related functions with either zero or one splits."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_to_owned",
         description: r##"Checks for the usage of `_.to_owned()`, on a `Cow<'_, _>`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_unary_op_formatting",
         description: r##"Checks the formatting of a unary operator on the right hand side
 of a binary operator. It lints if there is no space between the binary and unary operators,
 but there is a space between the unary and its operand."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::suspicious_xor_used_as_pow",
         description: r##"Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::swap_ptr_to_ref",
         description: r##"Checks for calls to `core::mem::swap` where either parameter is derived from a pointer"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::tabs_in_doc_comments",
         description: r##"Checks doc comments for usage of tab characters."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::temporary_assignment",
         description: r##"Checks for construction of a structure or tuple just to
 assign a value in it."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::test_attr_in_doctest",
         description: r##"Checks for `#[test]` in doctests unless they are marked with
 either `ignore`, `no_run` or `compile_fail`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::tests_outside_test_module",
         description: r##"Triggers when a testing function (marked with the `#[test]` attribute) isn't inside a testing module
 (marked with `#[cfg(test)]`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::to_digit_is_some",
         description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::to_string_in_format_args",
         description: r##"Checks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string)
 applied to a type that implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html)
 in a macro that does formatting."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::to_string_trait_impl",
         description: r##"Checks for direct implementations of `ToString`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::todo",
+        description: r##"Checks for usage of `todo!`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::too_long_first_doc_paragraph",
+        description: r##"Checks if the first line in the documentation of items listed in module page is too long."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::todo", description: r##"Checks for usage of `todo!`."## },
     Lint {
         label: "clippy::too_many_arguments",
         description: r##"Checks for functions with too many parameters."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::too_many_lines",
         description: r##"Checks for functions with a large amount of lines."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::toplevel_ref_arg",
         description: r##"Checks for function arguments and let bindings denoted as
 `ref`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::trailing_empty_array",
         description: r##"Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::trait_duplication_in_bounds",
         description: r##"Checks for cases where generics or trait objects are being used and multiple
 syntax specifications for trait bounds are used simultaneously."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_bytes_to_str",
         description: r##"Checks for transmutes from a `&[u8]` to a `&str`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_float_to_int",
         description: r##"Checks for transmutes from a float to an integer."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_int_to_bool",
         description: r##"Checks for transmutes from an integer to a `bool`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_int_to_char",
         description: r##"Checks for transmutes from an integer to a `char`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_int_to_float",
         description: r##"Checks for transmutes from an integer to a float."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_int_to_non_zero",
         description: r##"Checks for transmutes from `T` to `NonZero<T>`, and suggests the `new_unchecked`
 method instead."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_null_to_fn",
         description: r##"Checks for null function pointer creation through transmute."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_num_to_bytes",
         description: r##"Checks for transmutes from a number to an array of `u8`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_ptr_to_ptr",
         description: r##"Checks for transmutes from a pointer to a pointer, or
 from a reference to a reference."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_ptr_to_ref",
         description: r##"Checks for transmutes from a pointer to a reference."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmute_undefined_repr",
         description: r##"Checks for transmutes between types which do not have a representation defined relative to
 each other."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmutes_expressible_as_ptr_casts",
         description: r##"Checks for transmutes that could be a pointer cast."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::transmuting_null",
         description: r##"Checks for transmute calls which would receive a null pointer."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::trim_split_whitespace",
         description: r##"Warns about calling `str::trim` (or variants) before `str::split_whitespace`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::trivial_regex",
         description: r##"Checks for trivial [regex](https://crates.io/crates/regex)
 creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::trivially_copy_pass_by_ref",
         description: r##"Checks for functions taking arguments by reference, where
 the argument type is `Copy` and small enough to be more efficient to always
 pass by value."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::try_err",
+        description: r##"Checks for usage of `Err(x)?`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::try_err", description: r##"Checks for usage of `Err(x)?`."## },
     Lint {
         label: "clippy::tuple_array_conversions",
         description: r##"Checks for tuple<=>array conversions that are not done with `.into()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::type_complexity",
         description: r##"Checks for types used in structs, parameters and `let`
 declarations above a certain complexity threshold."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::type_id_on_box",
         description: r##"Looks for calls to `.type_id()` on a `Box<dyn _>`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::type_repetition_in_bounds",
         description: r##"This lint warns about unnecessary type repetitions in trait bounds"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unchecked_duration_subtraction",
         description: r##"Lints subtraction between an `Instant` and a `Duration`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unconditional_recursion",
         description: r##"Checks that there isn't an infinite recursion in trait
 implementations."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::undocumented_unsafe_blocks",
@@ -13485,53 +17988,89 @@ foo(
     /* SAFETY: Neither is this */ unsafe { *x },
 );
 ```"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unicode_not_nfc",
         description: r##"Checks for string literals that contain Unicode in a form
 that is not equal to its
 [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unimplemented",
         description: r##"Checks for usage of `unimplemented!`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::uninhabited_references",
         description: r##"It detects references to uninhabited types, such as `!` and
 warns when those are either dereferenced or returned from a function."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::uninit_assumed_init",
         description: r##"Checks for `MaybeUninit::uninit().assume_init()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::uninit_vec",
         description: r##"Checks for `set_len()` call that creates `Vec` with uninitialized elements.
 This is commonly caused by calling `set_len()` right after allocating or
 reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::uninlined_format_args",
         description: r##"Detect when a variable is not inlined in a format string,
 and suggests to inline it."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unit_arg",
         description: r##"Checks for passing a unit value as an argument to a function without using a
 unit literal (`()`)."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unit_cmp",
         description: r##"Checks for comparisons to unit. This includes all binary
 comparisons (like `==` and `<`) and asserts."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::unit_hash",
+        description: r##"Detects `().hash(_)`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::unit_hash", description: r##"Detects `().hash(_)`."## },
     Lint {
         label: "clippy::unit_return_expecting_ord",
         description: r##"Checks for functions that expect closures of type
 Fn(...) -> Ord where the implemented closure returns the unit type.
 The lint also suggests to remove the semi-colon at the end of the statement if present."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_box_returns",
@@ -13539,48 +18078,83 @@ The lint also suggests to remove the semi-colon at the end of the statement if p
 
 The lint ignores `Box<T>` where `T` is larger than `unnecessary_box_size`,
 as returning a large `T` directly may be detrimental to performance."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_cast",
         description: r##"Checks for casts to the same type, casts of int literals to integer
 types, casts of float literals to float types, and casts between raw
 pointers that don't change type or constness."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_clippy_cfg",
         description: r##"Checks for `#[cfg_attr(clippy, allow(clippy::lint))]`
 and suggests to replace it with `#[allow(clippy::lint)]`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_fallible_conversions",
         description: r##"Checks for calls to `TryInto::try_into` and `TryFrom::try_from` when their infallible counterparts
 could be used."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_filter_map",
         description: r##"Checks for `filter_map` calls that could be replaced by `filter` or `map`.
 More specifically it checks if the closure provided is only performing one of the
 filter or map operations and suggests the appropriate option."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_find_map",
         description: r##"Checks for `find_map` calls that could be replaced by `find` or `map`. More
 specifically it checks if the closure provided is only performing one of the
 find or map operations and suggests the appropriate option."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::unnecessary_first_then_check",
+        description: r##"Checks the usage of `.first().is_some()` or `.first().is_none()` to check if a slice is
+empty."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_fold",
         description: r##"Checks for usage of `fold` when a more succinct alternative exists.
 Specifically, this checks for `fold`s which could be replaced by `any`, `all`,
 `sum` or `product`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_get_then_check",
         description: r##"Checks the usage of `.get().is_some()` or `.get().is_none()` on std map types."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_join",
         description: r##"Checks for usage of `.collect::<Vec<String>>().join()` on iterators."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_lazy_evaluations",
@@ -13595,80 +18169,131 @@ simpler code:
  - `get_or_insert_with` to `get_or_insert`
  - `ok_or_else` to `ok_or`
  - `then` to `then_some` (for msrv >= 1.62.0)"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_literal_unwrap",
         description: r##"Checks for `.unwrap()` related calls on `Result`s and `Option`s that are constructed."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_map_on_constructor",
         description: r##"Suggests removing the use of a `map()` (or `map_err()`) method when an `Option` or `Result`
 is being constructed."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_min_or_max",
         description: r##"Checks for unnecessary calls to `min()` or `max()` in the following cases
 - Either both side is constant
 - One side is clearly larger than the other, like i32::MIN and an i32 variable"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_mut_passed",
         description: r##"Detects passing a mutable reference to a function that only
 requires an immutable reference."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_operation",
         description: r##"Checks for expression statements that can be reduced to a
 sub-expression."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_owned_empty_strings",
         description: r##"Detects cases of owned empty strings being passed as an argument to a function expecting `&str`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_result_map_or_else",
         description: r##"Checks for usage of `.map_or_else()` map closure for `Result` type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_safety_comment",
         description: r##"Checks for `// SAFETY: ` comments on safe code."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_safety_doc",
         description: r##"Checks for the doc comments of publicly visible
 safe functions and traits and warns if there is a `# Safety` section."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_self_imports",
         description: r##"Checks for imports ending in `::{self}`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_sort_by",
         description: r##"Checks for usage of `Vec::sort_by` passing in a closure
 which compares the two arguments, either directly or indirectly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_struct_initialization",
         description: r##"Checks for initialization of an identical `struct` from another instance
 of the type, either by copying a base without setting any field or by
 moving all fields individually."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_to_owned",
         description: r##"Checks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned)
 and other `to_owned`-like functions."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_unwrap",
         description: r##"Checks for calls of `unwrap[_err]()` that cannot fail."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnecessary_wraps",
         description: r##"Checks for private functions that only return `Ok` or `Some`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unneeded_field_pattern",
         description: r##"Checks for structure field patterns bound to wildcards."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unneeded_wildcard_pattern",
@@ -13679,6 +18304,9 @@ _NOTE_: While `_, ..` means there is at least one element left, `..`
 means there are 0 or more elements left. This can make a difference
 when refactoring, but shouldn't result in errors in the refactored code,
 since the wildcard pattern isn't used anyway."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unnested_or_patterns",
@@ -13687,26 +18315,47 @@ suggests replacing the pattern with a nested one, `Some(0 | 2)`.
 
 Another way to think of this is that it rewrites patterns in
 *disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::unreachable",
+        description: r##"Checks for usage of `unreachable!`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::unreachable", description: r##"Checks for usage of `unreachable!`."## },
     Lint {
         label: "clippy::unreadable_literal",
         description: r##"Warns if a long integral or floating-point constant does
 not contain underscores."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unsafe_derive_deserialize",
         description: r##"Checks for deriving `serde::Deserialize` on a type that
 has methods using `unsafe`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unsafe_removed_from_name",
         description: r##"Checks for imports that remove unsafe from an item's
 name."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unsafe_vector_initialization",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unseparated_literal_suffix",
@@ -13714,66 +18363,125 @@ name."##,
 underscore.
 To enforce unseparated literal suffix style,
 see the `separated_literal_suffix` lint."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unsound_collection_transmute",
         description: r##"Checks for transmutes between collections whose
 types have different ABI, size or alignment."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unstable_as_mut_slice",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unstable_as_slice",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_async",
         description: r##"Checks for functions that are declared `async` but have no `.await`s inside of them."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_collect",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_enumerate_index",
         description: r##"Checks for uses of the `enumerate` method where the index is unused (`_`)"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_format_specs",
         description: r##"Detects [formatting parameters] that have no effect on the output of
 `format!()`, `println!()` or similar macros."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_io_amount",
         description: r##"Checks for unused written/read amount."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_peekable",
         description: r##"Checks for the creation of a `peekable` iterator that is never `.peek()`ed"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::unused_result_ok",
+        description: r##"Checks for calls to `Result::ok()` without using the returned `Option`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_rounding",
         description: r##"Detects cases where a whole-number literal float is being rounded, using
 the `floor`, `ceil`, or `round` methods."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_self",
         description: r##"Checks methods that contain a `self` argument but don't use it"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::unused_trait_names",
+        description: r##"Checks for `use Trait` where the Trait is only used for its methods and not referenced by a path directly."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unused_unit",
         description: r##"Checks for unit (`()`) expressions that can be removed."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unusual_byte_groupings",
         description: r##"Warns if hexadecimal or binary literals are not grouped
 by nibble or byte."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unwrap_in_result",
         description: r##"Checks for functions of type `Result` that contain `expect()` or `unwrap()`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unwrap_or_default",
@@ -13783,34 +18491,63 @@ by nibble or byte."##,
 - `unwrap_or_else`
 - `or_insert`
 - `or_insert_with`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::unwrap_used",
         description: r##"Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::upper_case_acronyms",
         description: r##"Checks for fully capitalized names and optionally names containing a capitalized acronym."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::use_debug",
         description: r##"Checks for usage of `Debug` formatting. The purpose of this
 lint is to catch debugging remnants."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::use_self",
         description: r##"Checks for unnecessary repetition of structure name when a
 replacement with `Self` is applicable."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::used_underscore_binding",
         description: r##"Checks for the use of bindings with a single leading
 underscore."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::used_underscore_items",
+        description: r##"Checks for the use of item with a single leading
+underscore."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::useless_asref",
         description: r##"Checks for usage of `.as_ref()` or `.as_mut()` where the
 types before and after the call are the same."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::useless_attribute",
@@ -13838,36 +18575,57 @@ For `use` items these lints are:
 
 For `extern crate` items these lints are:
 * `unused_imports` on items with `#[macro_use]`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::useless_conversion",
         description: r##"Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls
 which uselessly convert to the same type."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::useless_format",
         description: r##"Checks for the use of `format!(string literal with no
 argument)` and `format!({}, foo)` where `foo` is a string."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::useless_let_if_seq",
         description: r##"Checks for variable declarations immediately followed by a
 conditional affectation."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::useless_transmute",
         description: r##"Checks for transmutes to the original type of the object
 and transmutes that could be a cast."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::useless_vec",
         description: r##"Checks for usage of `vec![..]` when using `[..]` would
 be possible."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::vec_box",
         description: r##"Checks for usage of `Vec<Box<T>>` where T: Sized anywhere in the code.
 Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::vec_init_then_push",
@@ -13879,76 +18637,127 @@ constant and the number of pushes is greater than or equal to the initial capaci
 If the `Vec` is extended after the initial sequence of pushes and it was default initialized
 then this will only lint after there were at least four pushes. This number may change in
 the future."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::vec_resize_to_zero",
         description: r##"Finds occurrences of `Vec::resize(0, an_int)`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::verbose_bit_mask",
         description: r##"Checks for bit masks that can be replaced by a call
 to `trailing_zeros`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::verbose_file_reads",
         description: r##"Checks for usage of File::read_to_end and File::read_to_string."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::waker_clone_wake",
         description: r##"Checks for usage of `waker.clone().wake()`"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::while_float",
         description: r##"Checks for while loops comparing floating point values."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::while_immutable_condition",
         description: r##"Checks whether variables used within while loop condition
 can be (and are) mutated in the body."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::while_let_loop",
         description: r##"Detects `loop + match` combinations that are easier
 written as a `while let` loop."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::while_let_on_iterator",
         description: r##"Checks for `while let` expressions on iterators."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::wildcard_dependencies",
         description: r##"Checks for wildcard dependencies in the `Cargo.toml`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::wildcard_enum_match_arm",
         description: r##"Checks for wildcard enum matches using `_`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::wildcard_imports",
         description: r##"Checks for wildcard imports `use _::*`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::wildcard_in_or_patterns",
         description: r##"Checks for wildcard pattern used with others patterns in same match arm."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::write_literal",
         description: r##"This lint warns about the use of literals as `write!`/`writeln!` args."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::write_with_newline",
         description: r##"This lint warns when you use `write!()` with a format
 string that
 ends in a newline."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::writeln_empty_string",
         description: r##"This lint warns when you use `writeln!(buf, )` to
 print a newline."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::wrong_pub_self_convention",
-        description: r##"Nothing. This lint has been deprecated."##,
+        description: r##"Nothing. This lint has been deprecated"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::wrong_self_convention",
@@ -13977,34 +18786,68 @@ Clippy allows `Pin<&Self>` and `Pin<&mut Self>` if `&self` and `&mut self` is re
 
 Please find more info here:
 https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::wrong_transmute",
         description: r##"Checks for transmutes that can't ever be correct on any
 architecture."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::zero_divided_by_zero",
+        description: r##"Checks for `0.0 / 0.0`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
-    Lint { label: "clippy::zero_divided_by_zero", description: r##"Checks for `0.0 / 0.0`."## },
     Lint {
         label: "clippy::zero_prefixed_literal",
         description: r##"Warns if an integral constant literal starts with `0`."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::zero_ptr",
         description: r##"Catch casts from `0` to some pointer type"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::zero_repeat_side_effects",
         description: r##"Checks for array or vec initializations which call a function or method,
 but which have a repeat count of zero."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::zero_sized_map_values",
         description: r##"Checks for maps with zero-sized value types anywhere in the code."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
+    },
+    Lint {
+        label: "clippy::zombie_processes",
+        description: r##"Looks for code that spawns a process but never calls `wait()` on the child."##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
     Lint {
         label: "clippy::zst_offset",
         description: r##"Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to
 zero-sized types"##,
+        default_severity: Severity::Allow,
+        warn_since: None,
+        deny_since: None,
     },
 ];
 pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
@@ -14012,6 +18855,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
         lint: Lint {
             label: "clippy::cargo",
             description: r##"lint group for: clippy::cargo_common_metadata, clippy::multiple_crate_versions, clippy::negative_feature_names, clippy::redundant_feature_names, clippy::wildcard_dependencies"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::cargo_common_metadata",
@@ -14024,7 +18870,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::complexity",
-            description: r##"lint group for: clippy::bind_instead_of_map, clippy::bool_comparison, clippy::borrow_deref_ref, clippy::borrowed_box, clippy::bytes_count_to_len, clippy::char_lit_as_u8, clippy::clone_on_copy, clippy::crosspointer_transmute, clippy::default_constructed_unit_structs, clippy::deprecated_cfg_attr, clippy::deref_addrof, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::double_comparisons, clippy::double_parens, clippy::duration_subsec, clippy::excessive_nesting, clippy::explicit_auto_deref, clippy::explicit_counter_loop, clippy::explicit_write, clippy::extra_unused_lifetimes, clippy::extra_unused_type_parameters, clippy::filter_map_identity, clippy::filter_next, clippy::flat_map_identity, clippy::get_last_with_len, clippy::identity_op, clippy::implied_bounds_in_impls, clippy::inspect_for_each, clippy::int_plus_one, clippy::iter_count, clippy::iter_kv_map, clippy::let_with_type_underscore, clippy::manual_clamp, clippy::manual_filter, clippy::manual_filter_map, clippy::manual_find, clippy::manual_find_map, clippy::manual_flatten, clippy::manual_hash_one, clippy::manual_inspect, clippy::manual_main_separator_str, clippy::manual_range_patterns, clippy::manual_rem_euclid, clippy::manual_slice_size_calculation, clippy::manual_split_once, clippy::manual_strip, clippy::manual_swap, clippy::manual_unwrap_or, clippy::map_flatten, clippy::map_identity, clippy::match_as_ref, clippy::match_single_binding, clippy::needless_arbitrary_self_type, clippy::needless_bool, clippy::needless_bool_assign, clippy::needless_borrowed_reference, clippy::needless_if, clippy::needless_lifetimes, clippy::needless_match, clippy::needless_option_as_deref, clippy::needless_option_take, clippy::needless_question_mark, clippy::needless_splitn, clippy::needless_update, clippy::neg_cmp_op_on_partial_ord, clippy::no_effect, clippy::nonminimal_bool, clippy::only_used_in_recursion, clippy::option_as_ref_deref, clippy::option_filter_map, clippy::option_map_unit_fn, clippy::or_then_unwrap, clippy::partialeq_ne_impl, clippy::precedence, clippy::ptr_offset_with_cast, clippy::range_zip_with_len, clippy::redundant_as_str, clippy::redundant_async_block, clippy::redundant_at_rest_pattern, clippy::redundant_closure_call, clippy::redundant_guards, clippy::redundant_slicing, clippy::repeat_once, clippy::reserve_after_initialization, clippy::result_filter_map, clippy::result_map_unit_fn, clippy::search_is_some, clippy::seek_from_current, clippy::seek_to_start_instead_of_rewind, clippy::short_circuit_statement, clippy::single_element_loop, clippy::skip_while_next, clippy::string_from_utf8_as_bytes, clippy::strlen_on_c_strings, clippy::temporary_assignment, clippy::too_many_arguments, clippy::transmute_bytes_to_str, clippy::transmute_float_to_int, clippy::transmute_int_to_bool, clippy::transmute_int_to_char, clippy::transmute_int_to_float, clippy::transmute_int_to_non_zero, clippy::transmute_num_to_bytes, clippy::transmute_ptr_to_ref, clippy::transmutes_expressible_as_ptr_casts, clippy::type_complexity, clippy::unit_arg, clippy::unnecessary_cast, clippy::unnecessary_filter_map, clippy::unnecessary_find_map, clippy::unnecessary_literal_unwrap, clippy::unnecessary_map_on_constructor, clippy::unnecessary_min_or_max, clippy::unnecessary_operation, clippy::unnecessary_sort_by, clippy::unnecessary_unwrap, clippy::unneeded_wildcard_pattern, clippy::unused_format_specs, clippy::useless_asref, clippy::useless_conversion, clippy::useless_format, clippy::useless_transmute, clippy::vec_box, clippy::while_let_loop, clippy::wildcard_in_or_patterns, clippy::zero_divided_by_zero, clippy::zero_prefixed_literal"##,
+            description: r##"lint group for: clippy::bind_instead_of_map, clippy::bool_comparison, clippy::borrow_deref_ref, clippy::borrowed_box, clippy::bytes_count_to_len, clippy::char_lit_as_u8, clippy::clone_on_copy, clippy::crosspointer_transmute, clippy::default_constructed_unit_structs, clippy::deprecated_cfg_attr, clippy::deref_addrof, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::double_comparisons, clippy::double_parens, clippy::duration_subsec, clippy::excessive_nesting, clippy::explicit_auto_deref, clippy::explicit_counter_loop, clippy::explicit_write, clippy::extra_unused_lifetimes, clippy::extra_unused_type_parameters, clippy::filter_map_identity, clippy::filter_next, clippy::flat_map_identity, clippy::get_last_with_len, clippy::identity_op, clippy::implied_bounds_in_impls, clippy::inspect_for_each, clippy::int_plus_one, clippy::iter_count, clippy::iter_kv_map, clippy::let_with_type_underscore, clippy::manual_c_str_literals, clippy::manual_clamp, clippy::manual_div_ceil, clippy::manual_filter, clippy::manual_filter_map, clippy::manual_find, clippy::manual_find_map, clippy::manual_flatten, clippy::manual_hash_one, clippy::manual_inspect, clippy::manual_is_power_of_two, clippy::manual_main_separator_str, clippy::manual_range_patterns, clippy::manual_rem_euclid, clippy::manual_slice_size_calculation, clippy::manual_split_once, clippy::manual_strip, clippy::manual_swap, clippy::manual_unwrap_or, clippy::map_flatten, clippy::map_identity, clippy::match_as_ref, clippy::match_single_binding, clippy::needless_arbitrary_self_type, clippy::needless_bool, clippy::needless_bool_assign, clippy::needless_borrowed_reference, clippy::needless_if, clippy::needless_lifetimes, clippy::needless_match, clippy::needless_option_as_deref, clippy::needless_option_take, clippy::needless_question_mark, clippy::needless_splitn, clippy::needless_update, clippy::neg_cmp_op_on_partial_ord, clippy::no_effect, clippy::nonminimal_bool, clippy::only_used_in_recursion, clippy::option_as_ref_deref, clippy::option_filter_map, clippy::option_map_unit_fn, clippy::or_then_unwrap, clippy::partialeq_ne_impl, clippy::precedence, clippy::ptr_offset_with_cast, clippy::range_zip_with_len, clippy::redundant_as_str, clippy::redundant_async_block, clippy::redundant_at_rest_pattern, clippy::redundant_closure_call, clippy::redundant_guards, clippy::redundant_slicing, clippy::repeat_once, clippy::reserve_after_initialization, clippy::result_filter_map, clippy::result_map_unit_fn, clippy::search_is_some, clippy::seek_from_current, clippy::seek_to_start_instead_of_rewind, clippy::short_circuit_statement, clippy::single_element_loop, clippy::skip_while_next, clippy::string_from_utf8_as_bytes, clippy::strlen_on_c_strings, clippy::temporary_assignment, clippy::too_many_arguments, clippy::transmute_bytes_to_str, clippy::transmute_float_to_int, clippy::transmute_int_to_bool, clippy::transmute_int_to_char, clippy::transmute_int_to_float, clippy::transmute_int_to_non_zero, clippy::transmute_num_to_bytes, clippy::transmute_ptr_to_ref, clippy::transmutes_expressible_as_ptr_casts, clippy::type_complexity, clippy::unit_arg, clippy::unnecessary_cast, clippy::unnecessary_filter_map, clippy::unnecessary_find_map, clippy::unnecessary_first_then_check, clippy::unnecessary_literal_unwrap, clippy::unnecessary_map_on_constructor, clippy::unnecessary_min_or_max, clippy::unnecessary_operation, clippy::unnecessary_sort_by, clippy::unnecessary_unwrap, clippy::unneeded_wildcard_pattern, clippy::unused_format_specs, clippy::useless_asref, clippy::useless_conversion, clippy::useless_format, clippy::useless_transmute, clippy::vec_box, clippy::while_let_loop, clippy::wildcard_in_or_patterns, clippy::zero_divided_by_zero, clippy::zero_prefixed_literal"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::bind_instead_of_map",
@@ -14060,7 +18909,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::iter_count",
             "clippy::iter_kv_map",
             "clippy::let_with_type_underscore",
+            "clippy::manual_c_str_literals",
             "clippy::manual_clamp",
+            "clippy::manual_div_ceil",
             "clippy::manual_filter",
             "clippy::manual_filter_map",
             "clippy::manual_find",
@@ -14068,6 +18919,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::manual_flatten",
             "clippy::manual_hash_one",
             "clippy::manual_inspect",
+            "clippy::manual_is_power_of_two",
             "clippy::manual_main_separator_str",
             "clippy::manual_range_patterns",
             "clippy::manual_rem_euclid",
@@ -14138,6 +18990,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::unnecessary_cast",
             "clippy::unnecessary_filter_map",
             "clippy::unnecessary_find_map",
+            "clippy::unnecessary_first_then_check",
             "clippy::unnecessary_literal_unwrap",
             "clippy::unnecessary_map_on_constructor",
             "clippy::unnecessary_min_or_max",
@@ -14160,7 +19013,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::correctness",
-            description: r##"lint group for: clippy::absurd_extreme_comparisons, clippy::almost_swapped, clippy::approx_constant, clippy::async_yields_async, clippy::bad_bit_mask, clippy::cast_slice_different_sizes, clippy::deprecated_semver, clippy::derive_ord_xor_partial_ord, clippy::derived_hash_with_manual_eq, clippy::eager_transmute, clippy::enum_clike_unportable_variant, clippy::eq_op, clippy::erasing_op, clippy::fn_address_comparisons, clippy::if_let_mutex, clippy::ifs_same_cond, clippy::impl_hash_borrow_with_str_and_bytes, clippy::impossible_comparisons, clippy::ineffective_bit_mask, clippy::infinite_iter, clippy::inherent_to_string_shadow_display, clippy::inline_fn_without_body, clippy::invalid_null_ptr_usage, clippy::invalid_regex, clippy::invisible_characters, clippy::iter_next_loop, clippy::iter_skip_zero, clippy::iterator_step_by_zero, clippy::let_underscore_lock, clippy::lint_groups_priority, clippy::match_str_case_mismatch, clippy::mem_replace_with_uninit, clippy::min_max, clippy::mistyped_literal_suffixes, clippy::modulo_one, clippy::mut_from_ref, clippy::never_loop, clippy::non_octal_unix_permissions, clippy::nonsensical_open_options, clippy::not_unsafe_ptr_arg_deref, clippy::option_env_unwrap, clippy::out_of_bounds_indexing, clippy::overly_complex_bool_expr, clippy::panicking_overflow_checks, clippy::panicking_unwrap, clippy::possible_missing_comma, clippy::read_line_without_trim, clippy::recursive_format_impl, clippy::redundant_comparisons, clippy::redundant_locals, clippy::reversed_empty_ranges, clippy::self_assignment, clippy::serde_api_misuse, clippy::size_of_in_element_count, clippy::suspicious_splitn, clippy::transmute_null_to_fn, clippy::transmuting_null, clippy::uninit_assumed_init, clippy::uninit_vec, clippy::unit_cmp, clippy::unit_hash, clippy::unit_return_expecting_ord, clippy::unsound_collection_transmute, clippy::unused_io_amount, clippy::useless_attribute, clippy::vec_resize_to_zero, clippy::while_immutable_condition, clippy::wrong_transmute, clippy::zst_offset"##,
+            description: r##"lint group for: clippy::absurd_extreme_comparisons, clippy::almost_swapped, clippy::approx_constant, clippy::async_yields_async, clippy::bad_bit_mask, clippy::cast_slice_different_sizes, clippy::deprecated_semver, clippy::derive_ord_xor_partial_ord, clippy::derived_hash_with_manual_eq, clippy::eager_transmute, clippy::enum_clike_unportable_variant, clippy::eq_op, clippy::erasing_op, clippy::fn_address_comparisons, clippy::if_let_mutex, clippy::ifs_same_cond, clippy::impl_hash_borrow_with_str_and_bytes, clippy::impossible_comparisons, clippy::ineffective_bit_mask, clippy::infinite_iter, clippy::inherent_to_string_shadow_display, clippy::inline_fn_without_body, clippy::invalid_null_ptr_usage, clippy::invalid_regex, clippy::inverted_saturating_sub, clippy::invisible_characters, clippy::iter_next_loop, clippy::iter_skip_zero, clippy::iterator_step_by_zero, clippy::let_underscore_lock, clippy::lint_groups_priority, clippy::match_str_case_mismatch, clippy::mem_replace_with_uninit, clippy::min_max, clippy::mistyped_literal_suffixes, clippy::modulo_one, clippy::mut_from_ref, clippy::never_loop, clippy::non_octal_unix_permissions, clippy::nonsensical_open_options, clippy::not_unsafe_ptr_arg_deref, clippy::option_env_unwrap, clippy::out_of_bounds_indexing, clippy::overly_complex_bool_expr, clippy::panicking_overflow_checks, clippy::panicking_unwrap, clippy::possible_missing_comma, clippy::read_line_without_trim, clippy::recursive_format_impl, clippy::redundant_comparisons, clippy::redundant_locals, clippy::reversed_empty_ranges, clippy::self_assignment, clippy::serde_api_misuse, clippy::size_of_in_element_count, clippy::suspicious_splitn, clippy::transmute_null_to_fn, clippy::transmuting_null, clippy::uninit_assumed_init, clippy::uninit_vec, clippy::unit_cmp, clippy::unit_hash, clippy::unit_return_expecting_ord, clippy::unsound_collection_transmute, clippy::unused_io_amount, clippy::useless_attribute, clippy::vec_resize_to_zero, clippy::while_immutable_condition, clippy::wrong_transmute, clippy::zst_offset"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::absurd_extreme_comparisons",
@@ -14187,6 +19043,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::inline_fn_without_body",
             "clippy::invalid_null_ptr_usage",
             "clippy::invalid_regex",
+            "clippy::inverted_saturating_sub",
             "clippy::invisible_characters",
             "clippy::iter_next_loop",
             "clippy::iter_skip_zero",
@@ -14237,17 +19094,15 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::deprecated",
-            description: r##"lint group for: clippy::assign_ops, clippy::extend_from_slice, clippy::filter_map, clippy::find_map, clippy::if_let_redundant_pattern_matching, clippy::maybe_misused_cfg, clippy::misaligned_transmute, clippy::mismatched_target_os, clippy::pub_enum_variant_names, clippy::range_step_by_zero, clippy::regex_macro, clippy::replace_consts, clippy::should_assert_eq, clippy::unsafe_vector_initialization, clippy::unstable_as_mut_slice, clippy::unstable_as_slice, clippy::unused_collect, clippy::wrong_pub_self_convention"##,
+            description: r##"lint group for: clippy::assign_ops, clippy::extend_from_slice, clippy::misaligned_transmute, clippy::pub_enum_variant_names, clippy::range_step_by_zero, clippy::regex_macro, clippy::replace_consts, clippy::should_assert_eq, clippy::unsafe_vector_initialization, clippy::unstable_as_mut_slice, clippy::unstable_as_slice, clippy::unused_collect, clippy::wrong_pub_self_convention"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::assign_ops",
             "clippy::extend_from_slice",
-            "clippy::filter_map",
-            "clippy::find_map",
-            "clippy::if_let_redundant_pattern_matching",
-            "clippy::maybe_misused_cfg",
             "clippy::misaligned_transmute",
-            "clippy::mismatched_target_os",
             "clippy::pub_enum_variant_names",
             "clippy::range_step_by_zero",
             "clippy::regex_macro",
@@ -14263,7 +19118,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::nursery",
-            description: r##"lint group for: clippy::as_ptr_cast_mut, clippy::branches_sharing_code, clippy::clear_with_drain, clippy::cognitive_complexity, clippy::collection_is_never_read, clippy::debug_assert_with_mut_call, clippy::derive_partial_eq_without_eq, clippy::empty_line_after_doc_comments, clippy::empty_line_after_outer_attr, clippy::equatable_if_let, clippy::fallible_impl_from, clippy::future_not_send, clippy::imprecise_flops, clippy::iter_on_empty_collections, clippy::iter_on_single_items, clippy::iter_with_drain, clippy::large_stack_frames, clippy::missing_const_for_fn, clippy::mutex_integer, clippy::needless_collect, clippy::needless_pass_by_ref_mut, clippy::non_send_fields_in_send_ty, clippy::nonstandard_macro_braces, clippy::option_if_let_else, clippy::or_fun_call, clippy::path_buf_push_overwrite, clippy::read_zero_byte_vec, clippy::redundant_clone, clippy::redundant_pub_crate, clippy::set_contains_or_insert, clippy::significant_drop_in_scrutinee, clippy::significant_drop_tightening, clippy::string_lit_as_bytes, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::trailing_empty_array, clippy::trait_duplication_in_bounds, clippy::transmute_undefined_repr, clippy::trivial_regex, clippy::tuple_array_conversions, clippy::type_repetition_in_bounds, clippy::uninhabited_references, clippy::unnecessary_struct_initialization, clippy::unused_peekable, clippy::unused_rounding, clippy::use_self, clippy::useless_let_if_seq, clippy::while_float"##,
+            description: r##"lint group for: clippy::as_ptr_cast_mut, clippy::branches_sharing_code, clippy::clear_with_drain, clippy::cognitive_complexity, clippy::collection_is_never_read, clippy::debug_assert_with_mut_call, clippy::derive_partial_eq_without_eq, clippy::equatable_if_let, clippy::fallible_impl_from, clippy::future_not_send, clippy::imprecise_flops, clippy::iter_on_empty_collections, clippy::iter_on_single_items, clippy::iter_with_drain, clippy::large_stack_frames, clippy::missing_const_for_fn, clippy::mutex_integer, clippy::needless_collect, clippy::needless_pass_by_ref_mut, clippy::non_send_fields_in_send_ty, clippy::nonstandard_macro_braces, clippy::option_if_let_else, clippy::or_fun_call, clippy::path_buf_push_overwrite, clippy::read_zero_byte_vec, clippy::redundant_clone, clippy::redundant_pub_crate, clippy::set_contains_or_insert, clippy::significant_drop_in_scrutinee, clippy::significant_drop_tightening, clippy::string_lit_as_bytes, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::trailing_empty_array, clippy::trait_duplication_in_bounds, clippy::transmute_undefined_repr, clippy::trivial_regex, clippy::tuple_array_conversions, clippy::type_repetition_in_bounds, clippy::uninhabited_references, clippy::unnecessary_struct_initialization, clippy::unused_peekable, clippy::unused_rounding, clippy::use_self, clippy::useless_let_if_seq, clippy::while_float"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::as_ptr_cast_mut",
@@ -14273,8 +19131,6 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::collection_is_never_read",
             "clippy::debug_assert_with_mut_call",
             "clippy::derive_partial_eq_without_eq",
-            "clippy::empty_line_after_doc_comments",
-            "clippy::empty_line_after_outer_attr",
             "clippy::equatable_if_let",
             "clippy::fallible_impl_from",
             "clippy::future_not_send",
@@ -14319,7 +19175,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::pedantic",
-            description: r##"lint group for: clippy::assigning_clones, clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_c_str_literals, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_as_ptr, clippy::ref_binding_to_reference, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_char_pattern, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##,
+            description: r##"lint group for: clippy::assigning_clones, clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_as_ptr, clippy::ref_binding_to_reference, clippy::ref_option, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_char_pattern, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::used_underscore_items, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::assigning_clones",
@@ -14371,7 +19230,6 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::linkedlist",
             "clippy::macro_use_imports",
             "clippy::manual_assert",
-            "clippy::manual_c_str_literals",
             "clippy::manual_instant_elapsed",
             "clippy::manual_is_variant_and",
             "clippy::manual_let_else",
@@ -14411,6 +19269,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::redundant_else",
             "clippy::ref_as_ptr",
             "clippy::ref_binding_to_reference",
+            "clippy::ref_option",
             "clippy::ref_option_ref",
             "clippy::return_self_not_must_use",
             "clippy::same_functions_in_if_condition",
@@ -14439,6 +19298,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::unused_async",
             "clippy::unused_self",
             "clippy::used_underscore_binding",
+            "clippy::used_underscore_items",
             "clippy::verbose_bit_mask",
             "clippy::wildcard_imports",
             "clippy::zero_sized_map_values",
@@ -14448,6 +19308,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
         lint: Lint {
             label: "clippy::perf",
             description: r##"lint group for: clippy::box_collection, clippy::boxed_local, clippy::cmp_owned, clippy::collapsible_str_replace, clippy::drain_collect, clippy::expect_fun_call, clippy::extend_with_drain, clippy::format_collect, clippy::format_in_format_args, clippy::iter_overeager_cloned, clippy::large_const_arrays, clippy::large_enum_variant, clippy::manual_memcpy, clippy::manual_retain, clippy::manual_str_repeat, clippy::manual_try_fold, clippy::map_entry, clippy::missing_const_for_thread_local, clippy::missing_spin_loop, clippy::readonly_write_lock, clippy::redundant_allocation, clippy::result_large_err, clippy::slow_vector_initialization, clippy::to_string_in_format_args, clippy::unnecessary_to_owned, clippy::useless_vec, clippy::vec_init_then_push, clippy::waker_clone_wake"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::box_collection",
@@ -14483,7 +19346,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::restriction",
-            description: r##"lint group for: clippy::absolute_paths, clippy::alloc_instead_of_core, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::arithmetic_side_effects, clippy::as_conversions, clippy::as_underscore, clippy::assertions_on_result_states, clippy::big_endian_bytes, clippy::cfg_not_test, clippy::clone_on_ref_ptr, clippy::create_dir, clippy::dbg_macro, clippy::decimal_literal_representation, clippy::default_numeric_fallback, clippy::default_union_representation, clippy::deref_by_slicing, clippy::disallowed_script_idents, clippy::else_if_without_else, clippy::empty_drop, clippy::empty_enum_variants_with_brackets, clippy::empty_structs_with_brackets, clippy::error_impl_error, clippy::exhaustive_enums, clippy::exhaustive_structs, clippy::exit, clippy::expect_used, clippy::field_scoped_visibility_modifiers, clippy::filetype_is_file, clippy::float_arithmetic, clippy::float_cmp_const, clippy::fn_to_numeric_cast_any, clippy::format_push_string, clippy::get_unwrap, clippy::host_endian_bytes, clippy::if_then_some_else_none, clippy::impl_trait_in_params, clippy::implicit_return, clippy::indexing_slicing, clippy::infinite_loop, clippy::inline_asm_x86_att_syntax, clippy::inline_asm_x86_intel_syntax, clippy::integer_division, clippy::integer_division_remainder_used, clippy::iter_over_hash_type, clippy::large_include_file, clippy::let_underscore_must_use, clippy::let_underscore_untyped, clippy::little_endian_bytes, clippy::lossy_float_literal, clippy::map_err_ignore, clippy::mem_forget, clippy::min_ident_chars, clippy::missing_assert_message, clippy::missing_asserts_for_indexing, clippy::missing_docs_in_private_items, clippy::missing_inline_in_public_items, clippy::missing_trait_methods, clippy::mixed_read_write_in_expression, clippy::mod_module_files, clippy::modulo_arithmetic, clippy::multiple_inherent_impl, clippy::multiple_unsafe_ops_per_block, clippy::mutex_atomic, clippy::needless_raw_strings, clippy::non_ascii_literal, clippy::panic, clippy::panic_in_result_fn, clippy::partial_pub_fields, clippy::pathbuf_init_then_push, clippy::pattern_type_mismatch, clippy::print_stderr, clippy::print_stdout, clippy::pub_use, clippy::pub_with_shorthand, clippy::pub_without_shorthand, clippy::question_mark_used, clippy::rc_buffer, clippy::rc_mutex, clippy::redundant_type_annotations, clippy::ref_patterns, clippy::renamed_function_params, clippy::rest_pat_in_fully_bound_structs, clippy::same_name_method, clippy::self_named_module_files, clippy::semicolon_inside_block, clippy::semicolon_outside_block, clippy::separated_literal_suffix, clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated, clippy::single_call_fn, clippy::single_char_lifetime_names, clippy::std_instead_of_alloc, clippy::std_instead_of_core, clippy::str_to_string, clippy::string_add, clippy::string_lit_chars_any, clippy::string_slice, clippy::string_to_string, clippy::suspicious_xor_used_as_pow, clippy::tests_outside_test_module, clippy::todo, clippy::try_err, clippy::undocumented_unsafe_blocks, clippy::unimplemented, clippy::unnecessary_safety_comment, clippy::unnecessary_safety_doc, clippy::unnecessary_self_imports, clippy::unneeded_field_pattern, clippy::unreachable, clippy::unseparated_literal_suffix, clippy::unwrap_in_result, clippy::unwrap_used, clippy::use_debug, clippy::verbose_file_reads, clippy::wildcard_enum_match_arm"##,
+            description: r##"lint group for: clippy::absolute_paths, clippy::alloc_instead_of_core, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::arithmetic_side_effects, clippy::as_conversions, clippy::as_underscore, clippy::assertions_on_result_states, clippy::big_endian_bytes, clippy::cfg_not_test, clippy::clone_on_ref_ptr, clippy::create_dir, clippy::dbg_macro, clippy::decimal_literal_representation, clippy::default_numeric_fallback, clippy::default_union_representation, clippy::deref_by_slicing, clippy::disallowed_script_idents, clippy::else_if_without_else, clippy::empty_drop, clippy::empty_enum_variants_with_brackets, clippy::empty_structs_with_brackets, clippy::error_impl_error, clippy::exhaustive_enums, clippy::exhaustive_structs, clippy::exit, clippy::expect_used, clippy::field_scoped_visibility_modifiers, clippy::filetype_is_file, clippy::float_arithmetic, clippy::float_cmp_const, clippy::fn_to_numeric_cast_any, clippy::format_push_string, clippy::get_unwrap, clippy::host_endian_bytes, clippy::if_then_some_else_none, clippy::impl_trait_in_params, clippy::implicit_return, clippy::indexing_slicing, clippy::infinite_loop, clippy::inline_asm_x86_att_syntax, clippy::inline_asm_x86_intel_syntax, clippy::integer_division, clippy::integer_division_remainder_used, clippy::iter_over_hash_type, clippy::large_include_file, clippy::let_underscore_must_use, clippy::let_underscore_untyped, clippy::little_endian_bytes, clippy::lossy_float_literal, clippy::map_err_ignore, clippy::mem_forget, clippy::min_ident_chars, clippy::missing_assert_message, clippy::missing_asserts_for_indexing, clippy::missing_docs_in_private_items, clippy::missing_inline_in_public_items, clippy::missing_trait_methods, clippy::mixed_read_write_in_expression, clippy::mod_module_files, clippy::modulo_arithmetic, clippy::multiple_inherent_impl, clippy::multiple_unsafe_ops_per_block, clippy::mutex_atomic, clippy::needless_raw_strings, clippy::non_ascii_literal, clippy::non_zero_suggestions, clippy::panic, clippy::panic_in_result_fn, clippy::partial_pub_fields, clippy::pathbuf_init_then_push, clippy::pattern_type_mismatch, clippy::print_stderr, clippy::print_stdout, clippy::pub_use, clippy::pub_with_shorthand, clippy::pub_without_shorthand, clippy::question_mark_used, clippy::rc_buffer, clippy::rc_mutex, clippy::redundant_type_annotations, clippy::ref_patterns, clippy::renamed_function_params, clippy::rest_pat_in_fully_bound_structs, clippy::same_name_method, clippy::self_named_module_files, clippy::semicolon_inside_block, clippy::semicolon_outside_block, clippy::separated_literal_suffix, clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated, clippy::single_call_fn, clippy::single_char_lifetime_names, clippy::std_instead_of_alloc, clippy::std_instead_of_core, clippy::str_to_string, clippy::string_add, clippy::string_lit_chars_any, clippy::string_slice, clippy::string_to_string, clippy::suspicious_xor_used_as_pow, clippy::tests_outside_test_module, clippy::todo, clippy::try_err, clippy::undocumented_unsafe_blocks, clippy::unimplemented, clippy::unnecessary_safety_comment, clippy::unnecessary_safety_doc, clippy::unnecessary_self_imports, clippy::unneeded_field_pattern, clippy::unreachable, clippy::unseparated_literal_suffix, clippy::unused_result_ok, clippy::unused_trait_names, clippy::unwrap_in_result, clippy::unwrap_used, clippy::use_debug, clippy::verbose_file_reads, clippy::wildcard_enum_match_arm"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::absolute_paths",
@@ -14552,6 +19418,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::mutex_atomic",
             "clippy::needless_raw_strings",
             "clippy::non_ascii_literal",
+            "clippy::non_zero_suggestions",
             "clippy::panic",
             "clippy::panic_in_result_fn",
             "clippy::partial_pub_fields",
@@ -14598,6 +19465,8 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::unneeded_field_pattern",
             "clippy::unreachable",
             "clippy::unseparated_literal_suffix",
+            "clippy::unused_result_ok",
+            "clippy::unused_trait_names",
             "clippy::unwrap_in_result",
             "clippy::unwrap_used",
             "clippy::use_debug",
@@ -14608,7 +19477,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::style",
-            description: r##"lint group for: clippy::assertions_on_constants, clippy::assign_op_pattern, clippy::blocks_in_conditions, clippy::bool_assert_comparison, clippy::borrow_interior_mutable_const, clippy::box_default, clippy::builtin_type_shadow, clippy::byte_char_slices, clippy::bytes_nth, clippy::chars_last_cmp, clippy::chars_next_cmp, clippy::cmp_null, clippy::collapsible_else_if, clippy::collapsible_if, clippy::collapsible_match, clippy::comparison_chain, clippy::comparison_to_empty, clippy::declare_interior_mutable_const, clippy::default_instead_of_iter_empty, clippy::disallowed_macros, clippy::disallowed_methods, clippy::disallowed_names, clippy::disallowed_types, clippy::doc_lazy_continuation, clippy::double_must_use, clippy::double_neg, clippy::duplicate_underscore_argument, clippy::enum_variant_names, clippy::err_expect, clippy::excessive_precision, clippy::field_reassign_with_default, clippy::filter_map_bool_then, clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation, clippy::for_kv_map, clippy::from_over_into, clippy::from_str_radix_10, clippy::get_first, clippy::if_same_then_else, clippy::implicit_saturating_add, clippy::implicit_saturating_sub, clippy::inconsistent_digit_grouping, clippy::infallible_destructuring_match, clippy::inherent_to_string, clippy::init_numbered_fields, clippy::into_iter_on_ref, clippy::is_digit_ascii_radix, clippy::items_after_test_module, clippy::iter_cloned_collect, clippy::iter_next_slice, clippy::iter_nth, clippy::iter_nth_zero, clippy::iter_skip_next, clippy::just_underscores_and_digits, clippy::legacy_numeric_constants, clippy::len_without_is_empty, clippy::len_zero, clippy::let_and_return, clippy::let_unit_value, clippy::main_recursion, clippy::manual_async_fn, clippy::manual_bits, clippy::manual_is_ascii_check, clippy::manual_is_finite, clippy::manual_is_infinite, clippy::manual_map, clippy::manual_next_back, clippy::manual_non_exhaustive, clippy::manual_pattern_char_comparison, clippy::manual_range_contains, clippy::manual_rotate, clippy::manual_saturating_arithmetic, clippy::manual_while_let_some, clippy::map_clone, clippy::map_collect_result_unit, clippy::match_like_matches_macro, clippy::match_overlapping_arm, clippy::match_ref_pats, clippy::match_result_ok, clippy::mem_replace_option_with_none, clippy::mem_replace_with_default, clippy::missing_enforced_import_renames, clippy::missing_safety_doc, clippy::mixed_attributes_style, clippy::mixed_case_hex_literals, clippy::module_inception, clippy::must_use_unit, clippy::mut_mutex_lock, clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::needless_doctest_main, clippy::needless_else, clippy::needless_late_init, clippy::needless_parens_on_range_literals, clippy::needless_pub_self, clippy::needless_range_loop, clippy::needless_return, clippy::needless_return_with_question_mark, clippy::neg_multiply, clippy::new_ret_no_self, clippy::new_without_default, clippy::non_minimal_cfg, clippy::obfuscated_if_else, clippy::ok_expect, clippy::op_ref, clippy::option_map_or_err_ok, clippy::option_map_or_none, clippy::partialeq_to_none, clippy::print_literal, clippy::print_with_newline, clippy::println_empty_string, clippy::ptr_arg, clippy::ptr_eq, clippy::question_mark, clippy::redundant_closure, clippy::redundant_field_names, clippy::redundant_pattern, clippy::redundant_pattern_matching, clippy::redundant_static_lifetimes, clippy::result_map_or_into_option, clippy::result_unit_err, clippy::same_item_push, clippy::self_named_constructors, clippy::should_implement_trait, clippy::single_char_add_str, clippy::single_component_path_imports, clippy::single_match, clippy::string_extend_chars, clippy::tabs_in_doc_comments, clippy::to_digit_is_some, clippy::to_string_trait_impl, clippy::toplevel_ref_arg, clippy::trim_split_whitespace, clippy::unnecessary_fallible_conversions, clippy::unnecessary_fold, clippy::unnecessary_lazy_evaluations, clippy::unnecessary_mut_passed, clippy::unnecessary_owned_empty_strings, clippy::unsafe_removed_from_name, clippy::unused_enumerate_index, clippy::unused_unit, clippy::unusual_byte_groupings, clippy::unwrap_or_default, clippy::upper_case_acronyms, clippy::while_let_on_iterator, clippy::write_literal, clippy::write_with_newline, clippy::writeln_empty_string, clippy::wrong_self_convention, clippy::zero_ptr"##,
+            description: r##"lint group for: clippy::assertions_on_constants, clippy::assign_op_pattern, clippy::blocks_in_conditions, clippy::bool_assert_comparison, clippy::borrow_interior_mutable_const, clippy::box_default, clippy::builtin_type_shadow, clippy::byte_char_slices, clippy::bytes_nth, clippy::chars_last_cmp, clippy::chars_next_cmp, clippy::cmp_null, clippy::collapsible_else_if, clippy::collapsible_if, clippy::collapsible_match, clippy::comparison_chain, clippy::comparison_to_empty, clippy::declare_interior_mutable_const, clippy::default_instead_of_iter_empty, clippy::disallowed_macros, clippy::disallowed_methods, clippy::disallowed_names, clippy::disallowed_types, clippy::doc_lazy_continuation, clippy::double_must_use, clippy::double_neg, clippy::duplicate_underscore_argument, clippy::enum_variant_names, clippy::err_expect, clippy::excessive_precision, clippy::field_reassign_with_default, clippy::filter_map_bool_then, clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation, clippy::for_kv_map, clippy::from_over_into, clippy::from_str_radix_10, clippy::get_first, clippy::if_same_then_else, clippy::implicit_saturating_add, clippy::implicit_saturating_sub, clippy::inconsistent_digit_grouping, clippy::infallible_destructuring_match, clippy::inherent_to_string, clippy::init_numbered_fields, clippy::into_iter_on_ref, clippy::is_digit_ascii_radix, clippy::items_after_test_module, clippy::iter_cloned_collect, clippy::iter_next_slice, clippy::iter_nth, clippy::iter_nth_zero, clippy::iter_skip_next, clippy::just_underscores_and_digits, clippy::legacy_numeric_constants, clippy::len_without_is_empty, clippy::len_zero, clippy::let_and_return, clippy::let_unit_value, clippy::main_recursion, clippy::manual_async_fn, clippy::manual_bits, clippy::manual_is_ascii_check, clippy::manual_is_finite, clippy::manual_is_infinite, clippy::manual_map, clippy::manual_next_back, clippy::manual_non_exhaustive, clippy::manual_pattern_char_comparison, clippy::manual_range_contains, clippy::manual_rotate, clippy::manual_saturating_arithmetic, clippy::manual_while_let_some, clippy::map_clone, clippy::map_collect_result_unit, clippy::match_like_matches_macro, clippy::match_overlapping_arm, clippy::match_ref_pats, clippy::match_result_ok, clippy::mem_replace_option_with_none, clippy::mem_replace_with_default, clippy::missing_enforced_import_renames, clippy::missing_safety_doc, clippy::mixed_attributes_style, clippy::mixed_case_hex_literals, clippy::module_inception, clippy::must_use_unit, clippy::mut_mutex_lock, clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::needless_doctest_main, clippy::needless_else, clippy::needless_late_init, clippy::needless_parens_on_range_literals, clippy::needless_pub_self, clippy::needless_range_loop, clippy::needless_return, clippy::needless_return_with_question_mark, clippy::neg_multiply, clippy::new_ret_no_self, clippy::new_without_default, clippy::non_minimal_cfg, clippy::obfuscated_if_else, clippy::ok_expect, clippy::op_ref, clippy::option_map_or_err_ok, clippy::option_map_or_none, clippy::partialeq_to_none, clippy::print_literal, clippy::print_with_newline, clippy::println_empty_string, clippy::ptr_arg, clippy::ptr_eq, clippy::question_mark, clippy::redundant_closure, clippy::redundant_field_names, clippy::redundant_pattern, clippy::redundant_pattern_matching, clippy::redundant_static_lifetimes, clippy::result_map_or_into_option, clippy::result_unit_err, clippy::same_item_push, clippy::self_named_constructors, clippy::should_implement_trait, clippy::single_char_add_str, clippy::single_component_path_imports, clippy::single_match, clippy::string_extend_chars, clippy::tabs_in_doc_comments, clippy::to_digit_is_some, clippy::to_string_trait_impl, clippy::too_long_first_doc_paragraph, clippy::toplevel_ref_arg, clippy::trim_split_whitespace, clippy::unnecessary_fallible_conversions, clippy::unnecessary_fold, clippy::unnecessary_lazy_evaluations, clippy::unnecessary_mut_passed, clippy::unnecessary_owned_empty_strings, clippy::unsafe_removed_from_name, clippy::unused_enumerate_index, clippy::unused_unit, clippy::unusual_byte_groupings, clippy::unwrap_or_default, clippy::upper_case_acronyms, clippy::while_let_on_iterator, clippy::write_literal, clippy::write_with_newline, clippy::writeln_empty_string, clippy::wrong_self_convention, clippy::zero_ptr"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::assertions_on_constants",
@@ -14742,6 +19614,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::tabs_in_doc_comments",
             "clippy::to_digit_is_some",
             "clippy::to_string_trait_impl",
+            "clippy::too_long_first_doc_paragraph",
             "clippy::toplevel_ref_arg",
             "clippy::trim_split_whitespace",
             "clippy::unnecessary_fallible_conversions",
@@ -14766,7 +19639,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
     LintGroup {
         lint: Lint {
             label: "clippy::suspicious",
-            description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::const_is_empty, clippy::crate_in_macro_def, clippy::deprecated_clippy_cfg_attr, clippy::drop_non_drop, clippy::duplicate_mod, clippy::duplicated_attributes, clippy::empty_docs, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::macro_metavars_in_unsafe, clippy::manual_unwrap_or_default, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::missing_transmute_annotations, clippy::multi_assignments, clippy::multiple_bound_locations, clippy::mut_range_bound, clippy::mutable_key_type, clippy::needless_character_iteration, clippy::needless_maybe_sized, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_clippy_cfg, clippy::unnecessary_get_then_check, clippy::unnecessary_result_map_or_else, clippy::zero_repeat_side_effects"##,
+            description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::const_is_empty, clippy::crate_in_macro_def, clippy::deprecated_clippy_cfg_attr, clippy::drop_non_drop, clippy::duplicate_mod, clippy::duplicated_attributes, clippy::empty_docs, clippy::empty_line_after_doc_comments, clippy::empty_line_after_outer_attr, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::macro_metavars_in_unsafe, clippy::manual_unwrap_or_default, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::missing_transmute_annotations, clippy::multi_assignments, clippy::multiple_bound_locations, clippy::mut_range_bound, clippy::mutable_key_type, clippy::needless_character_iteration, clippy::needless_maybe_sized, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::pointers_in_nomem_asm_block, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_clippy_cfg, clippy::unnecessary_get_then_check, clippy::unnecessary_result_map_or_else, clippy::zero_repeat_side_effects, clippy::zombie_processes"##,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
         },
         children: &[
             "clippy::almost_complete_range",
@@ -14787,6 +19663,8 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::duplicate_mod",
             "clippy::duplicated_attributes",
             "clippy::empty_docs",
+            "clippy::empty_line_after_doc_comments",
+            "clippy::empty_line_after_outer_attr",
             "clippy::empty_loop",
             "clippy::float_equality_without_abs",
             "clippy::forget_non_drop",
@@ -14815,6 +19693,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::octal_escapes",
             "clippy::path_ends_with_ext",
             "clippy::permissions_set_readonly_false",
+            "clippy::pointers_in_nomem_asm_block",
             "clippy::print_in_format_impl",
             "clippy::rc_clone_in_vec_init",
             "clippy::repeat_vec_with_capacity",
@@ -14838,6 +19717,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[
             "clippy::unnecessary_get_then_check",
             "clippy::unnecessary_result_map_or_else",
             "clippy::zero_repeat_side_effects",
+            "clippy::zombie_processes",
         ],
     },
 ];
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index 81260c3e080..1f77ea1ec66 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -327,3 +327,11 @@ impl<'a> Ranker<'a> {
             | ((no_tt_parent as usize) << 3)
     }
 }
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum Severity {
+    Error,
+    Warning,
+    WeakWarning,
+    Allow,
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
index a508f2fedd6..156f21b784e 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -184,7 +184,7 @@ impl<'a> PathTransform<'a> {
                     if let Some(expr) = v.expr() {
                         // FIXME: expressions in curly brackets can cause ambiguity after insertion
                         // (e.g. `N * 2` -> `{1 + 1} * 2`; it's unclear whether `{1 + 1}`
-                        // is a standalone statement or a part of another expresson)
+                        // is a standalone statement or a part of another expression)
                         // and sometimes require slight modifications; see
                         // https://doc.rust-lang.org/reference/statements.html#expression-statements
                         // (default values in curly brackets can cause the same problem)
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
index 4bd29b8c79b..c7cdcf49820 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
@@ -59,7 +59,7 @@ pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast) -
             DiagnosticCode::RustcHardError("E0606"),
             format_ty!(
                 ctx,
-                "casting `{}` as `{}` is invalid: needs defererence or removal of unneeded borrow",
+                "casting `{}` as `{}` is invalid: needs dereference or removal of unneeded borrow",
                 d.expr_ty,
                 d.cast_ty
             ),
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
index 2bfdda35659..dc3dee5c9ce 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
@@ -586,14 +586,47 @@ fn main() {
     }
 
     #[test]
-    fn unsafe_op_in_unsafe_fn_allowed_by_default() {
+    fn unsafe_op_in_unsafe_fn_allowed_by_default_in_edition_2021() {
         check_diagnostics(
             r#"
+//- /lib.rs crate:foo edition:2021
 unsafe fn foo(p: *mut i32) {
     *p = 123;
 }
             "#,
-        )
+        );
+        check_diagnostics(
+            r#"
+//- /lib.rs crate:foo edition:2021
+#![deny(warnings)]
+unsafe fn foo(p: *mut i32) {
+    *p = 123;
+}
+            "#,
+        );
+    }
+
+    #[test]
+    fn unsafe_op_in_unsafe_fn_warn_by_default_in_edition_2024() {
+        check_diagnostics(
+            r#"
+//- /lib.rs crate:foo edition:2024
+unsafe fn foo(p: *mut i32) {
+    *p = 123;
+  //^^💡 warn: dereference of raw pointer is unsafe and requires an unsafe function or block
+}
+            "#,
+        );
+        check_diagnostics(
+            r#"
+//- /lib.rs crate:foo edition:2024
+#![deny(warnings)]
+unsafe fn foo(p: *mut i32) {
+    *p = 123;
+  //^^💡 error: dereference of raw pointer is unsafe and requires an unsafe function or block
+}
+            "#,
+        );
     }
 
     #[test]
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index ad339569081..1e99d7ad6e6 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -84,12 +84,12 @@ use hir::{db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, HirFileId, InFi
 use ide_db::{
     assists::{Assist, AssistId, AssistKind, AssistResolveStrategy},
     base_db::SourceDatabase,
-    generated::lints::{LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS},
+    generated::lints::{Lint, LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, DEFAULT_LINT_GROUPS},
     imports::insert_use::InsertUseConfig,
     label::Label,
     source_change::SourceChange,
     syntax_helpers::node_ext::parse_tt_as_comma_sep_paths,
-    EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, SnippetCap,
+    EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap,
 };
 use itertools::Itertools;
 use syntax::{
@@ -210,14 +210,6 @@ impl Diagnostic {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum Severity {
-    Error,
-    Warning,
-    WeakWarning,
-    Allow,
-}
-
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum ExprFillDefaultMode {
     Todo,
@@ -568,26 +560,35 @@ fn handle_diag_from_macros(
 
 // `__RA_EVERY_LINT` is a fake lint group to allow every lint in proc macros
 
-static RUSTC_LINT_GROUPS_DICT: LazyLock<FxHashMap<&str, Vec<&str>>> =
-    LazyLock::new(|| build_group_dict(DEFAULT_LINT_GROUPS, &["warnings", "__RA_EVERY_LINT"], ""));
+struct BuiltLint {
+    lint: &'static Lint,
+    groups: Vec<&'static str>,
+}
 
-static CLIPPY_LINT_GROUPS_DICT: LazyLock<FxHashMap<&str, Vec<&str>>> =
-    LazyLock::new(|| build_group_dict(CLIPPY_LINT_GROUPS, &["__RA_EVERY_LINT"], "clippy::"));
+static RUSTC_LINTS: LazyLock<FxHashMap<&str, BuiltLint>> =
+    LazyLock::new(|| build_lints_map(DEFAULT_LINTS, DEFAULT_LINT_GROUPS, ""));
+
+static CLIPPY_LINTS: LazyLock<FxHashMap<&str, BuiltLint>> = LazyLock::new(|| {
+    build_lints_map(ide_db::generated::lints::CLIPPY_LINTS, CLIPPY_LINT_GROUPS, "clippy::")
+});
 
 // FIXME: Autogenerate this instead of enumerating by hand.
 static LINTS_TO_REPORT_IN_EXTERNAL_MACROS: LazyLock<FxHashSet<&str>> =
     LazyLock::new(|| FxHashSet::from_iter([]));
 
-fn build_group_dict(
+fn build_lints_map(
+    lints: &'static [Lint],
     lint_group: &'static [LintGroup],
-    all_groups: &'static [&'static str],
     prefix: &'static str,
-) -> FxHashMap<&'static str, Vec<&'static str>> {
-    let mut map_with_prefixes: FxHashMap<&str, Vec<&str>> = FxHashMap::default();
+) -> FxHashMap<&'static str, BuiltLint> {
+    let mut map_with_prefixes: FxHashMap<_, _> = lints
+        .iter()
+        .map(|lint| (lint.label, BuiltLint { lint, groups: vec![lint.label, "__RA_EVERY_LINT"] }))
+        .collect();
     for g in lint_group {
         let mut add_children = |label: &'static str| {
             for child in g.children {
-                map_with_prefixes.entry(child).or_default().push(label);
+                map_with_prefixes.get_mut(child).unwrap().groups.push(label);
             }
         };
         add_children(g.lint.label);
@@ -597,18 +598,9 @@ fn build_group_dict(
             add_children("bad_style");
         }
     }
-    for (lint, groups) in map_with_prefixes.iter_mut() {
-        groups.push(lint);
-        groups.extend_from_slice(all_groups);
-    }
     map_with_prefixes.into_iter().map(|(k, v)| (k.strip_prefix(prefix).unwrap(), v)).collect()
 }
 
-/// Thd default severity for lints that are not warn by default.
-// FIXME: Autogenerate this instead of write manually.
-static LINTS_DEFAULT_SEVERITY: LazyLock<FxHashMap<&str, Severity>> =
-    LazyLock::new(|| FxHashMap::from_iter([("unsafe_op_in_unsafe_fn", Severity::Allow)]));
-
 fn handle_lints(
     sema: &Semantics<'_, RootDatabase>,
     cache: &mut FxHashMap<HirFileId, FxHashMap<SmolStr, SeverityAttr>>,
@@ -618,10 +610,12 @@ fn handle_lints(
 ) {
     for (node, diag) in diagnostics {
         let lint = match diag.code {
-            DiagnosticCode::RustcLint(lint) | DiagnosticCode::Clippy(lint) => lint,
+            DiagnosticCode::RustcLint(lint) => RUSTC_LINTS[lint].lint,
+            DiagnosticCode::Clippy(lint) => CLIPPY_LINTS[lint].lint,
             _ => panic!("non-lint passed to `handle_lints()`"),
         };
-        if let Some(&default_severity) = LINTS_DEFAULT_SEVERITY.get(lint) {
+        let default_severity = default_lint_severity(lint, edition);
+        if !(default_severity == Severity::Allow && diag.severity == Severity::WeakWarning) {
             diag.severity = default_severity;
         }
 
@@ -639,6 +633,16 @@ fn handle_lints(
     }
 }
 
+fn default_lint_severity(lint: &Lint, edition: Edition) -> Severity {
+    if lint.deny_since.is_some_and(|e| edition >= e) {
+        Severity::Error
+    } else if lint.warn_since.is_some_and(|e| edition >= e) {
+        Severity::Warning
+    } else {
+        lint.default_severity
+    }
+}
+
 fn find_outline_mod_lint_severity(
     sema: &Semantics<'_, RootDatabase>,
     node: &InFile<SyntaxNode>,
@@ -654,14 +658,14 @@ fn find_outline_mod_lint_severity(
     let mod_def = sema.to_module_def(&mod_node)?;
     let module_source_file = sema.module_definition_node(mod_def);
     let mut result = None;
-    let lint_groups = lint_groups(&diag.code);
+    let lint_groups = lint_groups(&diag.code, edition);
     lint_attrs(
         sema,
         ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"),
         edition,
     )
     .for_each(|(lint, severity)| {
-        if lint_groups.contains(&&*lint) {
+        if lint_groups.contains(&lint) {
             result = Some(severity);
         }
     });
@@ -737,9 +741,9 @@ fn fill_lint_attrs(
                     }
                 });
 
-                let all_matching_groups = lint_groups(&diag.code)
+                let all_matching_groups = lint_groups(&diag.code, edition)
                     .iter()
-                    .filter_map(|lint_group| cached.get(&**lint_group));
+                    .filter_map(|lint_group| cached.get(lint_group));
                 let cached_severity =
                     all_matching_groups.min_by_key(|it| it.depth).map(|it| it.severity);
 
@@ -751,7 +755,7 @@ fn fill_lint_attrs(
             // Insert this node's descendants' attributes into any outline descendant, but not including this node.
             // This must come before inserting this node's own attributes to preserve order.
             collected_lint_attrs.drain().for_each(|(lint, severity)| {
-                if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) {
+                if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) {
                     diag_severity = Some(severity.severity);
                 }
 
@@ -774,7 +778,7 @@ fn fill_lint_attrs(
             if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) {
                 // Insert this node's attributes into any outline descendant, including this node.
                 lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| {
-                    if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) {
+                    if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) {
                         diag_severity = Some(severity);
                     }
 
@@ -804,7 +808,7 @@ fn fill_lint_attrs(
             return diag_severity;
         } else if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) {
             lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| {
-                if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) {
+                if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) {
                     diag_severity = Some(severity);
                 }
 
@@ -905,16 +909,37 @@ fn cfg_attr_lint_attrs(
     }
 }
 
-fn lint_groups(lint: &DiagnosticCode) -> &'static [&'static str] {
-    match lint {
+#[derive(Debug)]
+struct LintGroups {
+    groups: &'static [&'static str],
+    inside_warnings: bool,
+}
+
+impl LintGroups {
+    fn contains(&self, group: &str) -> bool {
+        self.groups.contains(&group) || (self.inside_warnings && group == "warnings")
+    }
+
+    fn iter(&self) -> impl Iterator<Item = &'static str> {
+        self.groups.iter().copied().chain(self.inside_warnings.then_some("warnings"))
+    }
+}
+
+fn lint_groups(lint: &DiagnosticCode, edition: Edition) -> LintGroups {
+    let (groups, inside_warnings) = match lint {
         DiagnosticCode::RustcLint(name) => {
-            RUSTC_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default()
+            let lint = &RUSTC_LINTS[name];
+            let inside_warnings = default_lint_severity(lint.lint, edition) == Severity::Warning;
+            (&lint.groups, inside_warnings)
         }
         DiagnosticCode::Clippy(name) => {
-            CLIPPY_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default()
+            let lint = &CLIPPY_LINTS[name];
+            let inside_warnings = default_lint_severity(lint.lint, edition) == Severity::Warning;
+            (&lint.groups, inside_warnings)
         }
-        _ => &[],
-    }
+        _ => panic!("non-lint passed to `handle_lints()`"),
+    };
+    LintGroups { groups, inside_warnings }
 }
 
 fn fix(id: &'static str, label: &str, source_change: SourceChange, target: TextRange) -> Assist {
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
index eaca95d98c2..6b654f89345 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
@@ -286,7 +286,7 @@ impl<'db> MatchFinder<'db> {
                     });
                 }
             } else if let Some(macro_call) = ast::MacroCall::cast(node.clone()) {
-                if let Some(expanded) = self.sema.expand(&macro_call) {
+                if let Some(expanded) = self.sema.expand_macro_call(&macro_call) {
                     if let Some(tt) = macro_call.token_tree() {
                         self.output_debug_for_nodes_at_range(
                             &expanded,
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs
index 241de10b44d..b1cade39266 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs
@@ -189,7 +189,7 @@ impl MatchFinder<'_> {
         // If we've got a macro call, we already tried matching it pre-expansion, which is the only
         // way to match the whole macro, now try expanding it and matching the expansion.
         if let Some(macro_call) = ast::MacroCall::cast(code.clone()) {
-            if let Some(expanded) = self.sema.expand(&macro_call) {
+            if let Some(expanded) = self.sema.expand_macro_call(&macro_call) {
                 if let Some(tt) = macro_call.token_tree() {
                     // When matching within a macro expansion, we only want to allow matches of
                     // nodes that originated entirely from within the token tree of the macro call.
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index 79fdf75b7f7..10a73edd51c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -1,10 +1,11 @@
 use hir::db::ExpandDatabase;
-use hir::{InFile, MacroFileIdExt, Semantics};
+use hir::{ExpandResult, InFile, MacroFileIdExt, Semantics};
 use ide_db::base_db::CrateId;
 use ide_db::{
     helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase,
 };
 use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize};
+use stdx::format_to;
 use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T};
 
 use crate::FilePosition;
@@ -63,10 +64,10 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
             .take_while(|it| it != &token)
             .filter(|it| it.kind() == T![,])
             .count();
-        let expansion = expansions.get(idx)?.clone();
+        let ExpandResult { err, value: expansion } = expansions.get(idx)?.clone();
         let expansion_file_id = sema.hir_file_for(&expansion).macro_file()?;
         let expansion_span_map = db.expansion_span_map(expansion_file_id);
-        let expansion = format(
+        let mut expansion = format(
             db,
             SyntaxKind::MACRO_ITEMS,
             position.file_id,
@@ -74,6 +75,12 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
             &expansion_span_map,
             krate,
         );
+        if let Some(err) = err {
+            expansion.insert_str(
+                0,
+                &format!("Expansion had errors: {}\n\n", err.render_to_string(sema.db)),
+            );
+        }
         Some(ExpandedMacro { name, expansion })
     });
 
@@ -83,6 +90,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
 
     let mut anc = tok.parent_ancestors();
     let mut span_map = SpanMap::empty();
+    let mut error = String::new();
     let (name, expanded, kind) = loop {
         let node = anc.next()?;
 
@@ -97,7 +105,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
                                 .unwrap_or(Edition::CURRENT),
                         )
                         .to_string(),
-                    expand_macro_recur(&sema, &item, &mut span_map, TextSize::new(0))?,
+                    expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
                     SyntaxKind::MACRO_ITEMS,
                 );
             }
@@ -112,6 +120,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
                 expand_macro_recur(
                     &sema,
                     &ast::Item::MacroCall(mac),
+                    &mut error,
                     &mut span_map,
                     TextSize::new(0),
                 )?,
@@ -123,24 +132,31 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
     // FIXME:
     // macro expansion may lose all white space information
     // But we hope someday we can use ra_fmt for that
-    let expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
+    let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
 
+    if !error.is_empty() {
+        expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n"));
+    }
     Some(ExpandedMacro { name, expansion })
 }
 
 fn expand_macro_recur(
     sema: &Semantics<'_, RootDatabase>,
     macro_call: &ast::Item,
+    error: &mut String,
     result_span_map: &mut SpanMap<SyntaxContextId>,
     offset_in_original_node: TextSize,
 ) -> Option<SyntaxNode> {
-    let expanded = match macro_call {
-        item @ ast::Item::MacroCall(macro_call) => sema
-            .expand_attr_macro(item)
-            .or_else(|| sema.expand_allowed_builtins(macro_call))?
-            .clone_for_update(),
-        item => sema.expand_attr_macro(item)?.clone_for_update(),
+    let ExpandResult { value: expanded, err } = match macro_call {
+        item @ ast::Item::MacroCall(macro_call) => {
+            sema.expand_attr_macro(item).or_else(|| sema.expand_allowed_builtins(macro_call))?
+        }
+        item => sema.expand_attr_macro(item)?,
     };
+    let expanded = expanded.clone_for_update();
+    if let Some(err) = err {
+        format_to!(error, "\n{}", err.render_to_string(sema.db));
+    }
     let file_id =
         sema.hir_file_for(&expanded).macro_file().expect("expansion must produce a macro file");
     let expansion_span_map = sema.db.expansion_span_map(file_id);
@@ -149,12 +165,13 @@ fn expand_macro_recur(
         expanded.text_range().len(),
         &expansion_span_map,
     );
-    Some(expand(sema, expanded, result_span_map, u32::from(offset_in_original_node) as i32))
+    Some(expand(sema, expanded, error, result_span_map, u32::from(offset_in_original_node) as i32))
 }
 
 fn expand(
     sema: &Semantics<'_, RootDatabase>,
     expanded: SyntaxNode,
+    error: &mut String,
     result_span_map: &mut SpanMap<SyntaxContextId>,
     mut offset_in_original_node: i32,
 ) -> SyntaxNode {
@@ -165,6 +182,7 @@ fn expand(
         if let Some(new_node) = expand_macro_recur(
             sema,
             &child,
+            error,
             result_span_map,
             TextSize::new(
                 (offset_in_original_node + (u32::from(child.syntax().text_range().start()) as i32))
@@ -495,6 +513,9 @@ fn main() {
 "#,
             expect![[r#"
                 foo!
+                Expansion had errors:
+                expected ident: `BAD`
+
             "#]],
         );
     }
diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
index fc29ba06dad..4690416e059 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -608,7 +608,7 @@ impl<'a> WalkExpandedExprCtx<'a> {
 
                     if let ast::Expr::MacroExpr(expr) = expr {
                         if let Some(expanded) =
-                            expr.macro_call().and_then(|call| self.sema.expand(&call))
+                            expr.macro_call().and_then(|call| self.sema.expand_macro_call(&call))
                         {
                             match_ast! {
                                 match expanded {
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 5a00d635698..e617d462ecd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -1,5 +1,5 @@
 //! Logic for rendering the different hover messages
-use std::{mem, ops::Not};
+use std::{env, mem, ops::Not};
 
 use either::Either;
 use hir::{
@@ -28,6 +28,7 @@ use syntax::{algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxToken, T}
 use crate::{
     doc_links::{remove_links, rewrite_links},
     hover::{notable_traits, walk_and_push_ty},
+    interpret::render_const_eval_error,
     HoverAction, HoverConfig, HoverResult, Markup, MemoryLayoutHoverConfig,
     MemoryLayoutHoverRenderKind,
 };
@@ -464,41 +465,77 @@ pub(super) fn definition(
                     Ok(it) => {
                         Some(if it >= 10 { format!("{it} ({it:#X})") } else { format!("{it}") })
                     }
-                    Err(_) => it.value(db).map(|it| format!("{it:?}")),
+                    Err(err) => {
+                        let res = it.value(db).map(|it| format!("{it:?}"));
+                        if env::var_os("RA_DEV").is_some() {
+                            let res = res.as_deref().unwrap_or("");
+                            Some(format!("{res} ({})", render_const_eval_error(db, err, edition)))
+                        } else {
+                            res
+                        }
+                    }
                 }
             } else {
                 None
             }
         }
         Definition::Const(it) => {
-            let body = it.render_eval(db, edition);
-            match body {
-                Ok(it) => Some(it),
-                Err(_) => {
+            let body = it.eval(db);
+            Some(match body {
+                Ok(it) => match it.render_debug(db) {
+                    Ok(it) => it,
+                    Err(err) => {
+                        let it = it.render(db, edition);
+                        if env::var_os("RA_DEV").is_some() {
+                            format!("{it}\n{}", render_const_eval_error(db, err.into(), edition))
+                        } else {
+                            it
+                        }
+                    }
+                },
+                Err(err) => {
                     let source = it.source(db)?;
                     let mut body = source.value.body()?.syntax().clone();
                     if let Some(macro_file) = source.file_id.macro_file() {
                         let span_map = db.expansion_span_map(macro_file);
                         body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into());
                     }
-                    Some(body.to_string())
+                    if env::var_os("RA_DEV").is_some() {
+                        format!("{body}\n{}", render_const_eval_error(db, err, edition))
+                    } else {
+                        body.to_string()
+                    }
                 }
-            }
+            })
         }
         Definition::Static(it) => {
-            let body = it.render_eval(db, edition);
-            match body {
-                Ok(it) => Some(it),
-                Err(_) => {
+            let body = it.eval(db);
+            Some(match body {
+                Ok(it) => match it.render_debug(db) {
+                    Ok(it) => it,
+                    Err(err) => {
+                        let it = it.render(db, edition);
+                        if env::var_os("RA_DEV").is_some() {
+                            format!("{it}\n{}", render_const_eval_error(db, err.into(), edition))
+                        } else {
+                            it
+                        }
+                    }
+                },
+                Err(err) => {
                     let source = it.source(db)?;
                     let mut body = source.value.body()?.syntax().clone();
                     if let Some(macro_file) = source.file_id.macro_file() {
                         let span_map = db.expansion_span_map(macro_file);
                         body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into());
                     }
-                    Some(body.to_string())
+                    if env::var_os("RA_DEV").is_some() {
+                        format!("{body}\n{}", render_const_eval_error(db, err, edition))
+                    } else {
+                        body.to_string()
+                    }
                 }
-            }
+            })
         }
         _ => None,
     };
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index ea18b89c5c9..50d0d4c5df6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -6413,7 +6413,7 @@ fn hover_feature() {
             by the codegen backend, but not the MIR inliner.
 
             ```rust
-            #![feature(rustc_attrs)]
+            #![feature(intrinsics)]
             #![allow(internal_features)]
 
             #[rustc_intrinsic]
@@ -6423,7 +6423,7 @@ fn hover_feature() {
             Since these are just regular functions, it is perfectly ok to create the intrinsic twice:
 
             ```rust
-            #![feature(rustc_attrs)]
+            #![feature(intrinsics)]
             #![allow(internal_features)]
 
             #[rustc_intrinsic]
@@ -9465,4 +9465,39 @@ fn main() {
             size = 0, align = 1
         "#]],
     );
+
+    check(
+        r#"
+//- minicore: eq
+pub struct RandomState;
+pub struct HashMap<K, V, S = RandomState>(K, V, S);
+
+impl<K, V> HashMap<K, V, RandomState> {
+    pub fn new() -> HashMap<K, V, RandomState> {
+        loop {}
+    }
+}
+
+impl<K, V, S> PartialEq for HashMap<K, V, S> {
+    fn eq(&self, other: &HashMap<K, V, S>) -> bool {
+        false
+    }
+}
+
+fn main() {
+    let s$0 = HashMap::<_, u64>::ne;
+}
+"#,
+        expect![[r#"
+            *s*
+
+            ```rust
+            let s: fn ne<HashMap<{unknown}, u64>>(&HashMap<{unknown}, u64>, &HashMap<{unknown}, u64>) -> bool
+            ```
+
+            ---
+
+            size = 0, align = 1
+        "#]],
+    );
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs
index 5fa6f4e4842..e0fdc3dd6f9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs
@@ -1,5 +1,6 @@
-use hir::{DefWithBody, Semantics};
+use hir::{ConstEvalError, DefWithBody, Semantics};
 use ide_db::{base_db::SourceRootDatabase, FilePosition, LineIndexDatabase, RootDatabase};
+use span::Edition;
 use std::time::{Duration, Instant};
 use stdx::format_to;
 use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange};
@@ -47,18 +48,36 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura
             None => format!("file://{path} range {text_range:?}"),
         }
     };
+    let edition = def.module(db).krate().edition(db);
     let start_time = Instant::now();
     let res = match def {
         DefWithBody::Function(it) => it.eval(db, span_formatter),
-        DefWithBody::Static(it) => it.eval(db),
-        DefWithBody::Const(it) => it.eval(db),
+        DefWithBody::Static(it) => it.eval(db).map(|it| it.render(db, edition)),
+        DefWithBody::Const(it) => it.eval(db).map(|it| it.render(db, edition)),
         _ => unreachable!(),
     };
-    let res = res.unwrap_or_else(|e| {
-        let mut r = String::new();
-        _ = e.pretty_print(&mut r, db, span_formatter, def.module(db).krate().edition(db));
-        r
-    });
+    let res = res.unwrap_or_else(|e| render_const_eval_error(db, e, edition));
     let duration = Instant::now() - start_time;
     Some((duration, res))
 }
+
+pub(crate) fn render_const_eval_error(
+    db: &RootDatabase,
+    e: ConstEvalError,
+    edition: Edition,
+) -> String {
+    let span_formatter = |file_id, text_range: TextRange| {
+        let path = &db
+            .source_root(db.file_source_root(file_id))
+            .path_for_file(&file_id)
+            .map(|x| x.to_string());
+        let path = path.as_deref().unwrap_or("<unknown file>");
+        match db.line_index(file_id).try_line_col(text_range.start()) {
+            Some(line_col) => format!("file://{path}:{}:{}", line_col.line + 1, line_col.col),
+            None => format!("file://{path} range {text_range:?}"),
+        }
+    };
+    let mut r = String::new();
+    _ = e.pretty_print(&mut r, db, span_formatter, edition);
+    r
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index c960b88a3e9..c13fc843568 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -132,11 +132,9 @@ pub use ide_db::{
     search::{ReferenceCategory, SearchScope},
     source_change::{FileSystemEdit, SnippetEdit, SourceChange},
     symbol_index::Query,
-    FileId, FilePosition, FileRange, RootDatabase, SymbolKind,
-};
-pub use ide_diagnostics::{
-    Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode, Severity,
+    FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind,
 };
+pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode};
 pub use ide_ssr::SsrError;
 pub use span::Edition;
 pub use syntax::{TextRange, TextSize};
@@ -301,7 +299,7 @@ impl Analysis {
 
     /// Gets the syntax tree of the file.
     pub fn parse(&self, file_id: FileId) -> Cancellable<SourceFile> {
-        // FIXME editiojn
+        // FIXME edition
         self.with_db(|db| db.parse(EditionedFileId::current_edition(file_id)).tree())
     }
 
@@ -542,7 +540,7 @@ impl Analysis {
     /// Returns URL(s) for the documentation of the symbol under the cursor.
     /// # Arguments
     /// * `position` - Position in the file.
-    /// * `target_dir` - Directory where the build output is storeda.
+    /// * `target_dir` - Directory where the build output is stored.
     pub fn external_docs(
         &self,
         position: FilePosition,
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index 1120d3c7d60..c15751e7c68 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -307,6 +307,7 @@ define_symbols! {
     module_path,
     mul_assign,
     mul,
+    naked_asm,
     ne,
     neg,
     Neg,
diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
index cf26845b119..aa64f570ed5 100644
--- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
@@ -15,9 +15,7 @@ use ide_db::{
 };
 use itertools::Itertools;
 use proc_macro_api::{MacroDylib, ProcMacroServer};
-use project_model::{
-    CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace, ProjectWorkspaceKind,
-};
+use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace};
 use span::Span;
 use vfs::{
     file_set::FileSetConfig,
@@ -244,6 +242,9 @@ impl ProjectFolders {
                     }
                 }
 
+                if dirs.include.is_empty() {
+                    continue;
+                }
                 vfs::loader::Entry::Directories(dirs)
             };
 
@@ -258,43 +259,6 @@ impl ProjectFolders {
             fsc.add_file_set(file_set_roots)
         }
 
-        // register the workspace manifest as well, note that this currently causes duplicates for
-        // non-virtual cargo workspaces! We ought to fix that
-        for ws in workspaces.iter() {
-            let mut file_set_roots: Vec<VfsPath> = vec![];
-            let mut entries = vec![];
-
-            if let Some(manifest) = ws.manifest().map(|it| it.to_path_buf()) {
-                file_set_roots.push(VfsPath::from(manifest.to_owned()));
-                entries.push(manifest.to_owned());
-            }
-
-            for buildfile in ws.buildfiles() {
-                file_set_roots.push(VfsPath::from(buildfile.to_owned()));
-                entries.push(buildfile.to_owned());
-            }
-
-            // In case of detached files we do **not** look for a rust-analyzer.toml.
-            if !matches!(ws.kind, ProjectWorkspaceKind::DetachedFile { .. }) {
-                let ws_root = ws.workspace_root();
-                let ratoml_path = {
-                    let mut p = ws_root.to_path_buf();
-                    p.push("rust-analyzer.toml");
-                    p
-                };
-                file_set_roots.push(VfsPath::from(ratoml_path.to_owned()));
-                entries.push(ratoml_path.to_owned());
-            }
-
-            if !file_set_roots.is_empty() {
-                let entry = vfs::loader::Entry::Files(entries);
-                res.watch.push(res.load.len());
-                res.load.push(entry);
-                local_filesets.push(fsc.len() as u64);
-                fsc.add_file_set(file_set_roots)
-            }
-        }
-
         if let Some(user_config_path) = user_config_dir_path {
             let ratoml_path = {
                 let mut p = user_config_path.to_path_buf();
@@ -303,7 +267,7 @@ impl ProjectFolders {
             };
 
             let file_set_roots = vec![VfsPath::from(ratoml_path.to_owned())];
-            let entry = vfs::loader::Entry::Files(vec![ratoml_path.to_owned()]);
+            let entry = vfs::loader::Entry::Files(vec![ratoml_path]);
 
             res.watch.push(res.load.len());
             res.load.push(entry);
diff --git a/src/tools/rust-analyzer/crates/parser/Cargo.toml b/src/tools/rust-analyzer/crates/parser/Cargo.toml
index d5255665b46..3629d275c0c 100644
--- a/src/tools/rust-analyzer/crates/parser/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/parser/Cargo.toml
@@ -18,6 +18,8 @@ ra-ap-rustc_lexer.workspace = true
 limit.workspace = true
 tracing = { workspace = true, optional = true }
 
+edition.workspace = true
+
 [dev-dependencies]
 expect-test = "1.4.0"
 
diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs
index 679492066a3..e461492cc6f 100644
--- a/src/tools/rust-analyzer/crates/parser/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs
@@ -25,7 +25,6 @@ extern crate ra_ap_rustc_lexer as rustc_lexer;
 #[cfg(feature = "in-rust-tree")]
 extern crate rustc_lexer;
 
-mod edition;
 mod event;
 mod grammar;
 mod input;
@@ -41,8 +40,9 @@ mod tests;
 
 pub(crate) use token_set::TokenSet;
 
+pub use edition::Edition;
+
 pub use crate::{
-    edition::Edition,
     input::Input,
     lexed_str::LexedStr,
     output::{Output, Step},
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
index 5443a9bd67b..af3412e90e4 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
@@ -42,7 +42,7 @@ use rustc_hash::FxHashMap;
 use serde::{Deserialize, Serialize};
 use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange};
 
-use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
+use crate::msg::EXTENDED_LEAF_DATA;
 
 pub type SpanDataIndexMap =
     indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
@@ -145,11 +145,7 @@ impl FlatTree {
         w.write(subtree);
 
         FlatTree {
-            subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
-                write_vec(w.subtree, SubtreeRepr::write_with_close_span)
-            } else {
-                write_vec(w.subtree, SubtreeRepr::write)
-            },
+            subtree: write_vec(w.subtree, SubtreeRepr::write),
             literal: if version >= EXTENDED_LEAF_DATA {
                 write_vec(w.literal, LiteralRepr::write_with_kind)
             } else {
@@ -183,11 +179,7 @@ impl FlatTree {
         w.write(subtree);
 
         FlatTree {
-            subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
-                write_vec(w.subtree, SubtreeRepr::write_with_close_span)
-            } else {
-                write_vec(w.subtree, SubtreeRepr::write)
-            },
+            subtree: write_vec(w.subtree, SubtreeRepr::write),
             literal: if version >= EXTENDED_LEAF_DATA {
                 write_vec(w.literal, LiteralRepr::write_with_kind)
             } else {
@@ -210,11 +202,7 @@ impl FlatTree {
         span_data_table: &SpanDataIndexMap,
     ) -> tt::Subtree<Span> {
         Reader {
-            subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
-                read_vec(self.subtree, SubtreeRepr::read_with_close_span)
-            } else {
-                read_vec(self.subtree, SubtreeRepr::read)
-            },
+            subtree: read_vec(self.subtree, SubtreeRepr::read),
             literal: if version >= EXTENDED_LEAF_DATA {
                 read_vec(self.literal, LiteralRepr::read_with_kind)
             } else {
@@ -236,11 +224,7 @@ impl FlatTree {
 
     pub fn to_subtree_unresolved(self, version: u32) -> tt::Subtree<TokenId> {
         Reader {
-            subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
-                read_vec(self.subtree, SubtreeRepr::read_with_close_span)
-            } else {
-                read_vec(self.subtree, SubtreeRepr::read)
-            },
+            subtree: read_vec(self.subtree, SubtreeRepr::read),
             literal: if version >= EXTENDED_LEAF_DATA {
                 read_vec(self.literal, LiteralRepr::read_with_kind)
             } else {
@@ -273,26 +257,7 @@ fn write_vec<T, F: Fn(T) -> [u32; N], const N: usize>(xs: Vec<T>, f: F) -> Vec<u
 }
 
 impl SubtreeRepr {
-    fn write(self) -> [u32; 4] {
-        let kind = match self.kind {
-            tt::DelimiterKind::Invisible => 0,
-            tt::DelimiterKind::Parenthesis => 1,
-            tt::DelimiterKind::Brace => 2,
-            tt::DelimiterKind::Bracket => 3,
-        };
-        [self.open.0, kind, self.tt[0], self.tt[1]]
-    }
-    fn read([open, kind, lo, len]: [u32; 4]) -> SubtreeRepr {
-        let kind = match kind {
-            0 => tt::DelimiterKind::Invisible,
-            1 => tt::DelimiterKind::Parenthesis,
-            2 => tt::DelimiterKind::Brace,
-            3 => tt::DelimiterKind::Bracket,
-            other => panic!("bad kind {other}"),
-        };
-        SubtreeRepr { open: TokenId(open), close: TokenId(!0), kind, tt: [lo, len] }
-    }
-    fn write_with_close_span(self) -> [u32; 5] {
+    fn write(self) -> [u32; 5] {
         let kind = match self.kind {
             tt::DelimiterKind::Invisible => 0,
             tt::DelimiterKind::Parenthesis => 1,
@@ -301,7 +266,7 @@ impl SubtreeRepr {
         };
         [self.open.0, self.close.0, kind, self.tt[0], self.tt[1]]
     }
-    fn read_with_close_span([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr {
+    fn read([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr {
         let kind = match kind {
             0 => tt::DelimiterKind::Invisible,
             1 => tt::DelimiterKind::Parenthesis,
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
index 4045e25fdf1..b1e35b7a08b 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
@@ -56,8 +56,25 @@ impl ProcMacroProcessSrv {
         match srv.version_check() {
             Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new(
                 io::ErrorKind::Other,
-                format!( "The version of the proc-macro server ({v}) in your Rust toolchain is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}).
-            This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain."
+                format!(
+                    "The version of the proc-macro server ({v}) in your Rust toolchain \
+                is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}).
+\
+                This will prevent proc-macro expansion from working. \
+                Please consider updating your rust-analyzer to ensure compatibility with your \
+                current toolchain."
+                ),
+            )),
+            Ok(v) if v < RUST_ANALYZER_SPAN_SUPPORT => Err(io::Error::new(
+                io::ErrorKind::Other,
+                format!(
+                    "The version of the proc-macro server ({v}) in your Rust toolchain \
+                is too old and no longer supported by your rust-analyzer which requires\
+                version {RUST_ANALYZER_SPAN_SUPPORT} or higher.
+\
+                This will prevent proc-macro expansion from working. \
+                Please consider updating your toolchain or downgrading your rust-analyzer \
+                to ensure compatibility with your current toolchain."
                 ),
             )),
             Ok(v) => {
@@ -72,10 +89,10 @@ impl ProcMacroProcessSrv {
                 tracing::info!("Proc-macro server span mode: {:?}", srv.mode);
                 Ok(srv)
             }
-            Err(e) => {
-                tracing::info!(%e, "proc-macro version check failed, restarting and assuming version 0");
-                create_srv(false)
-            }
+            Err(e) => Err(io::Error::new(
+                io::ErrorKind::Other,
+                format!("Failed to fetch proc-macro server version: {e}"),
+            )),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs
index 174f9c52462..137efd5e7a0 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs
@@ -6,21 +6,16 @@
 #[cfg(feature = "in-rust-tree")]
 extern crate rustc_driver as _;
 
-use proc_macro_api::json::{read_json, write_json};
-
 use std::io;
 
 fn main() -> std::io::Result<()> {
     let v = std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE");
-    match v.as_deref() {
-        Ok("this is unstable") => {
-            // very well, if you must
-        }
-        _ => {
-            eprintln!("If you're rust-analyzer, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE='this is unstable'.");
-            eprintln!("If not, you probably shouldn't use this tool. But do what you want: I'm an error message, not a cop.");
-            std::process::exit(122);
-        }
+    if v.is_err() {
+        eprintln!("This is an IDE implementation detail, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE.");
+        eprintln!(
+            "Note that this tool's API is highly unstable and may break without prior notice"
+        );
+        std::process::exit(122);
     }
 
     run()
@@ -28,40 +23,19 @@ fn main() -> std::io::Result<()> {
 
 #[cfg(not(any(feature = "sysroot-abi", rust_analyzer)))]
 fn run() -> io::Result<()> {
-    let err = "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function";
-    eprintln!("{err}");
-    use proc_macro_api::msg::{self, Message};
-
-    let read_request =
-        |buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf);
-
-    let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
-
-    let mut buf = String::new();
-
-    while let Some(req) = read_request(&mut buf)? {
-        let res = match req {
-            msg::Request::ListMacros { .. } => msg::Response::ListMacros(Err(err.to_owned())),
-            msg::Request::ExpandMacro(_) => {
-                msg::Response::ExpandMacro(Err(msg::PanicMessage(err.to_owned())))
-            }
-            msg::Request::ApiVersionCheck {} => {
-                msg::Response::ApiVersionCheck(proc_macro_api::msg::CURRENT_API_VERSION)
-            }
-            msg::Request::SetConfig(_) => {
-                msg::Response::SetConfig(proc_macro_api::msg::ServerConfig {
-                    span_mode: msg::SpanMode::Id,
-                })
-            }
-        };
-        write_response(res)?
-    }
-    Ok(())
+    Err(io::Error::new(
+        io::ErrorKind::Unsupported,
+        "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function"
+            .to_owned(),
+    ))
 }
 
 #[cfg(any(feature = "sysroot-abi", rust_analyzer))]
 fn run() -> io::Result<()> {
-    use proc_macro_api::msg::{self, Message};
+    use proc_macro_api::{
+        json::{read_json, write_json},
+        msg::{self, Message},
+    };
     use proc_macro_srv::EnvSnapshot;
 
     let read_request =
@@ -69,7 +43,7 @@ fn run() -> io::Result<()> {
 
     let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
 
-    let env = EnvSnapshot::new();
+    let env = EnvSnapshot::default();
     let mut srv = proc_macro_srv::ProcMacroSrv::new(&env);
     let mut buf = String::new();
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
index 78ae4574c40..26f6af84aae 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
@@ -3,12 +3,11 @@
 mod version;
 
 use proc_macro::bridge;
-use std::{fmt, fs::File, io};
+use std::{fmt, fs, io, time::SystemTime};
 
 use libloading::Library;
-use memmap2::Mmap;
 use object::Object;
-use paths::{AbsPath, Utf8Path, Utf8PathBuf};
+use paths::{Utf8Path, Utf8PathBuf};
 use proc_macro_api::ProcMacroKind;
 
 use crate::ProcMacroSrvSpan;
@@ -23,14 +22,9 @@ fn is_derive_registrar_symbol(symbol: &str) -> bool {
     symbol.contains(NEW_REGISTRAR_SYMBOL)
 }
 
-fn find_registrar_symbol(file: &Utf8Path) -> io::Result<Option<String>> {
-    let file = File::open(file)?;
-    let buffer = unsafe { Mmap::map(&file)? };
-
-    Ok(object::File::parse(&*buffer)
-        .map_err(invalid_data_err)?
-        .exports()
-        .map_err(invalid_data_err)?
+fn find_registrar_symbol(obj: &object::File<'_>) -> object::Result<Option<String>> {
+    Ok(obj
+        .exports()?
         .into_iter()
         .map(|export| export.name())
         .filter_map(|sym| String::from_utf8(sym.into()).ok())
@@ -113,17 +107,18 @@ struct ProcMacroLibraryLibloading {
 }
 
 impl ProcMacroLibraryLibloading {
-    fn open(file: &Utf8Path) -> Result<Self, LoadProcMacroDylibError> {
-        let symbol_name = find_registrar_symbol(file)?.ok_or_else(|| {
-            invalid_data_err(format!("Cannot find registrar symbol in file {file}"))
-        })?;
-
-        let abs_file: &AbsPath = file
-            .try_into()
-            .map_err(|_| invalid_data_err(format!("expected an absolute path, got {file}")))?;
-        let version_info = version::read_dylib_info(abs_file)?;
-
-        let lib = load_library(file).map_err(invalid_data_err)?;
+    fn open(path: &Utf8Path) -> Result<Self, LoadProcMacroDylibError> {
+        let file = fs::File::open(path)?;
+        let file = unsafe { memmap2::Mmap::map(&file) }?;
+        let obj = object::File::parse(&*file)
+            .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
+        let version_info = version::read_dylib_info(&obj)?;
+        let symbol_name =
+            find_registrar_symbol(&obj).map_err(invalid_data_err)?.ok_or_else(|| {
+                invalid_data_err(format!("Cannot find registrar symbol in file {path}"))
+            })?;
+
+        let lib = load_library(path).map_err(invalid_data_err)?;
         let proc_macros = crate::proc_macros::ProcMacros::from_lib(
             &lib,
             symbol_name,
@@ -133,30 +128,33 @@ impl ProcMacroLibraryLibloading {
     }
 }
 
-pub(crate) struct Expander {
-    inner: ProcMacroLibraryLibloading,
-    path: Utf8PathBuf,
-}
-
-impl Drop for Expander {
+struct RemoveFileOnDrop(Utf8PathBuf);
+impl Drop for RemoveFileOnDrop {
     fn drop(&mut self) {
         #[cfg(windows)]
-        std::fs::remove_file(&self.path).ok();
-        _ = self.path;
+        std::fs::remove_file(&self.0).unwrap();
+        _ = self.0;
     }
 }
 
+// Drop order matters as we can't remove the dylib before the library is unloaded
+pub(crate) struct Expander {
+    inner: ProcMacroLibraryLibloading,
+    _remove_on_drop: RemoveFileOnDrop,
+    modified_time: SystemTime,
+}
+
 impl Expander {
     pub(crate) fn new(lib: &Utf8Path) -> Result<Expander, LoadProcMacroDylibError> {
         // Some libraries for dynamic loading require canonicalized path even when it is
         // already absolute
         let lib = lib.canonicalize_utf8()?;
+        let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?;
 
         let path = ensure_file_with_lock_free_access(&lib)?;
-
         let library = ProcMacroLibraryLibloading::open(path.as_ref())?;
 
-        Ok(Expander { inner: library, path })
+        Ok(Expander { inner: library, _remove_on_drop: RemoveFileOnDrop(path), modified_time })
     }
 
     pub(crate) fn expand<S: ProcMacroSrvSpan>(
@@ -181,6 +179,10 @@ impl Expander {
     pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
         self.inner.proc_macros.list_macros()
     }
+
+    pub(crate) fn modified_time(&self) -> SystemTime {
+        self.modified_time
+    }
 }
 
 /// Copy the dylib to temp directory to prevent locking in Windows
@@ -194,20 +196,20 @@ fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf>
     }
 
     let mut to = Utf8PathBuf::from_path_buf(std::env::temp_dir()).unwrap();
+    to.push("rust-analyzer-proc-macros");
+    _ = fs::create_dir(&to);
 
-    let file_name = path.file_name().ok_or_else(|| {
+    let file_name = path.file_stem().ok_or_else(|| {
         io::Error::new(io::ErrorKind::InvalidInput, format!("File path is invalid: {path}"))
     })?;
 
-    // Generate a unique number by abusing `HashMap`'s hasher.
-    // Maybe this will also "inspire" a libs team member to finally put `rand` in libstd.
-    let t = RandomState::new().build_hasher().finish();
-
-    let mut unique_name = t.to_string();
-    unique_name.push_str(file_name);
-
-    to.push(unique_name);
-    std::fs::copy(path, &to)?;
+    to.push({
+        // Generate a unique number by abusing `HashMap`'s hasher.
+        // Maybe this will also "inspire" a libs team member to finally put `rand` in libstd.
+        let unique_name = RandomState::new().build_hasher().finish();
+        format!("{file_name}-{unique_name}.dll")
+    });
+    fs::copy(path, &to)?;
     Ok(to)
 }
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
index 7f0e95c50de..4e28aaced9b 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
@@ -1,13 +1,8 @@
 //! Reading proc-macro rustc version information from binary data
 
-use std::{
-    fs::File,
-    io::{self, Read},
-};
+use std::io::{self, Read};
 
-use memmap2::Mmap;
-use object::read::{File as BinaryFile, Object, ObjectSection};
-use paths::AbsPath;
+use object::read::{Object, ObjectSection};
 
 #[derive(Debug)]
 #[allow(dead_code)]
@@ -21,14 +16,14 @@ pub struct RustCInfo {
 }
 
 /// Read rustc dylib information
-pub fn read_dylib_info(dylib_path: &AbsPath) -> io::Result<RustCInfo> {
+pub fn read_dylib_info(obj: &object::File<'_>) -> io::Result<RustCInfo> {
     macro_rules! err {
         ($e:literal) => {
             io::Error::new(io::ErrorKind::InvalidData, $e)
         };
     }
 
-    let ver_str = read_version(dylib_path)?;
+    let ver_str = read_version(obj)?;
     let mut items = ver_str.split_whitespace();
     let tag = items.next().ok_or_else(|| err!("version format error"))?;
     if tag != "rustc" {
@@ -75,10 +70,8 @@ pub fn read_dylib_info(dylib_path: &AbsPath) -> io::Result<RustCInfo> {
 
 /// This is used inside read_version() to locate the ".rustc" section
 /// from a proc macro crate's binary file.
-fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&'a [u8]> {
-    BinaryFile::parse(dylib_binary)
-        .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?
-        .section_by_name(section_name)
+fn read_section<'a>(obj: &object::File<'a>, section_name: &str) -> io::Result<&'a [u8]> {
+    obj.section_by_name(section_name)
         .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "section read error"))?
         .data()
         .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
@@ -106,11 +99,8 @@ fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&'
 ///
 /// Check this issue for more about the bytes layout:
 /// <https://github.com/rust-lang/rust-analyzer/issues/6174>
-pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
-    let dylib_file = File::open(dylib_path)?;
-    let dylib_mmapped = unsafe { Mmap::map(&dylib_file) }?;
-
-    let dot_rustc = read_section(&dylib_mmapped, ".rustc")?;
+pub fn read_version(obj: &object::File<'_>) -> io::Result<String> {
+    let dot_rustc = read_section(obj, ".rustc")?;
 
     // check if magic is valid
     if &dot_rustc[0..4] != b"rust" {
@@ -159,8 +149,12 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
 
 #[test]
 fn test_version_check() {
-    let path = paths::AbsPathBuf::assert(crate::proc_macro_test_dylib_path());
-    let info = read_dylib_info(&path).unwrap();
+    let info = read_dylib_info(
+        &object::File::parse(&*std::fs::read(crate::proc_macro_test_dylib_path()).unwrap())
+            .unwrap(),
+    )
+    .unwrap();
+
     assert_eq!(
         info.version_string,
         crate::RUSTC_VERSION_STRING,
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
index f0aa6b3f93f..85833dab1b0 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
@@ -13,7 +13,7 @@
 #![cfg(any(feature = "sysroot-abi", rust_analyzer))]
 #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
 #![feature(proc_macro_internals, proc_macro_diagnostic, proc_macro_span)]
-#![allow(unreachable_pub, internal_features)]
+#![allow(unreachable_pub, internal_features, clippy::disallowed_types, clippy::print_stderr)]
 
 extern crate proc_macro;
 #[cfg(feature = "in-rust-tree")]
@@ -35,7 +35,6 @@ use std::{
     fs,
     path::{Path, PathBuf},
     thread,
-    time::SystemTime,
 };
 
 use paths::{Utf8Path, Utf8PathBuf};
@@ -53,7 +52,7 @@ use crate::server_impl::TokenStream;
 pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION");
 
 pub struct ProcMacroSrv<'env> {
-    expanders: HashMap<(Utf8PathBuf, SystemTime), dylib::Expander>,
+    expanders: HashMap<Utf8PathBuf, dylib::Expander>,
     span_mode: SpanMode,
     env: &'env EnvSnapshot,
 }
@@ -66,7 +65,7 @@ impl<'env> ProcMacroSrv<'env> {
 
 const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024;
 
-impl<'env> ProcMacroSrv<'env> {
+impl ProcMacroSrv<'_> {
     pub fn set_span_mode(&mut self, span_mode: SpanMode) {
         self.span_mode = span_mode;
     }
@@ -81,10 +80,9 @@ impl<'env> ProcMacroSrv<'env> {
     ) -> Result<(msg::FlatTree, Vec<u32>), msg::PanicMessage> {
         let span_mode = self.span_mode;
         let snapped_env = self.env;
-        let expander = self.expander(lib.as_ref()).map_err(|err| {
-            debug_assert!(false, "should list macros before asking to expand");
-            msg::PanicMessage(format!("failed to load macro: {err}"))
-        })?;
+        let expander = self
+            .expander(lib.as_ref())
+            .map_err(|err| msg::PanicMessage(format!("failed to load macro: {err}")))?;
 
         let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref));
 
@@ -107,16 +105,20 @@ impl<'env> ProcMacroSrv<'env> {
     }
 
     fn expander(&mut self, path: &Utf8Path) -> Result<&dylib::Expander, String> {
-        let time = fs::metadata(path)
-            .and_then(|it| it.modified())
-            .map_err(|err| format!("Failed to get file metadata for {path}: {err}",))?;
-
-        Ok(match self.expanders.entry((path.to_path_buf(), time)) {
-            Entry::Vacant(v) => v.insert(
-                dylib::Expander::new(path)
-                    .map_err(|err| format!("Cannot create expander for {path}: {err}",))?,
-            ),
-            Entry::Occupied(e) => e.into_mut(),
+        let expander = || {
+            dylib::Expander::new(path)
+                .map_err(|err| format!("Cannot create expander for {path}: {err}",))
+        };
+
+        Ok(match self.expanders.entry(path.to_path_buf()) {
+            Entry::Vacant(v) => v.insert(expander()?),
+            Entry::Occupied(mut e) => {
+                let time = fs::metadata(path).and_then(|it| it.modified()).ok();
+                if Some(e.get().modified_time()) != time {
+                    e.insert(expander()?);
+                }
+                e.into_mut()
+            }
         })
     }
 }
@@ -246,8 +248,8 @@ pub struct EnvSnapshot {
     vars: HashMap<OsString, OsString>,
 }
 
-impl EnvSnapshot {
-    pub fn new() -> EnvSnapshot {
+impl Default for EnvSnapshot {
+    fn default() -> EnvSnapshot {
         EnvSnapshot { vars: env::vars_os().collect() }
     }
 }
@@ -303,7 +305,7 @@ impl Drop for EnvChange<'_> {
         }
 
         if let Some(dir) = &self.prev_working_dir {
-            if let Err(err) = std::env::set_current_dir(&dir) {
+            if let Err(err) = std::env::set_current_dir(dir) {
                 eprintln!(
                     "Failed to set the current working dir to {}. Error: {:?}",
                     dir.display(),
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs
index d48c5b30dee..097b39a3f91 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs
@@ -13,7 +13,7 @@ pub(crate) struct ProcMacros {
 
 impl From<bridge::PanicMessage> for crate::PanicMessage {
     fn from(p: bridge::PanicMessage) -> Self {
-        Self { message: p.as_str().map(|s| s.to_string()) }
+        Self { message: p.as_str().map(|s| s.to_owned()) }
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
index d508c19dd71..1b535d2a1cc 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
@@ -498,7 +498,7 @@ mod tests {
                 })),
                 tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("T"),
-                    span: span,
+                    span,
                     is_raw: tt::IdentIsRaw::No,
                 })),
                 tt::TokenTree::Subtree(tt::Subtree {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs
index dbcb5a3143a..5649e60e0bb 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs
@@ -99,7 +99,7 @@ pub(super) struct TokenStreamBuilder<S> {
 }
 
 /// pub(super)lic implementation details for the `TokenStream` type, such as iterators.
-pub(super) mod token_stream {
+pub(super) mod token_stream_impls {
 
     use core::fmt;
 
@@ -137,6 +137,7 @@ pub(super) mod token_stream {
         }
     }
 
+    #[allow(clippy::to_string_trait_impl)]
     impl<S> ToString for TokenStream<S> {
         fn to_string(&self) -> String {
             ::tt::pretty(&self.token_trees)
@@ -150,7 +151,7 @@ impl<S> TokenStreamBuilder<S> {
     }
 
     pub(super) fn push(&mut self, stream: TokenStream<S>) {
-        self.acc.extend(stream.into_iter())
+        self.acc.extend(stream)
     }
 
     pub(super) fn build(self) -> TokenStream<S> {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
index 4f1a18c03fc..cc5d4a89131 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
@@ -97,7 +97,7 @@ fn assert_expand_impl(
 
 pub(crate) fn list() -> Vec<String> {
     let dylib_path = proc_macro_test_dylib_path();
-    let env = EnvSnapshot::new();
+    let env = EnvSnapshot::default();
     let mut srv = ProcMacroSrv::new(&env);
     let res = srv.list_macros(&dylib_path).unwrap();
     res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect()
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index cb5738a3b40..4ae3426ed97 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -33,6 +33,7 @@ pub struct CargoWorkspace {
     workspace_root: AbsPathBuf,
     target_directory: AbsPathBuf,
     manifest_path: ManifestPath,
+    is_virtual_workspace: bool,
 }
 
 impl ops::Index<Package> for CargoWorkspace {
@@ -384,13 +385,20 @@ impl CargoWorkspace {
         .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
     }
 
-    pub fn new(mut meta: cargo_metadata::Metadata, manifest_path: ManifestPath) -> CargoWorkspace {
+    pub fn new(
+        mut meta: cargo_metadata::Metadata,
+        ws_manifest_path: ManifestPath,
+    ) -> CargoWorkspace {
         let mut pkg_by_id = FxHashMap::default();
         let mut packages = Arena::default();
         let mut targets = Arena::default();
 
         let ws_members = &meta.workspace_members;
 
+        let workspace_root = AbsPathBuf::assert(meta.workspace_root);
+        let target_directory = AbsPathBuf::assert(meta.target_directory);
+        let mut is_virtual_workspace = true;
+
         meta.packages.sort_by(|a, b| a.id.cmp(&b.id));
         for meta_pkg in meta.packages {
             let cargo_metadata::Package {
@@ -429,12 +437,13 @@ impl CargoWorkspace {
             let is_local = source.is_none();
             let is_member = ws_members.contains(&id);
 
-            let manifest = AbsPathBuf::assert(manifest_path);
+            let manifest = ManifestPath::try_from(AbsPathBuf::assert(manifest_path)).unwrap();
+            is_virtual_workspace &= manifest != ws_manifest_path;
             let pkg = packages.alloc(PackageData {
                 id: id.repr.clone(),
                 name,
                 version,
-                manifest: manifest.clone().try_into().unwrap(),
+                manifest: manifest.clone(),
                 targets: Vec::new(),
                 is_local,
                 is_member,
@@ -468,7 +477,7 @@ impl CargoWorkspace {
                         // modified manifest file into a special target dir which is then used as
                         // the source path. We don't want that, we want the original here so map it
                         // back
-                        manifest.clone()
+                        manifest.clone().into()
                     } else {
                         AbsPathBuf::assert(src_path)
                     },
@@ -493,11 +502,14 @@ impl CargoWorkspace {
             packages[source].active_features.extend(node.features);
         }
 
-        let workspace_root = AbsPathBuf::assert(meta.workspace_root);
-
-        let target_directory = AbsPathBuf::assert(meta.target_directory);
-
-        CargoWorkspace { packages, targets, workspace_root, target_directory, manifest_path }
+        CargoWorkspace {
+            packages,
+            targets,
+            workspace_root,
+            target_directory,
+            manifest_path: ws_manifest_path,
+            is_virtual_workspace,
+        }
     }
 
     pub fn packages(&self) -> impl ExactSizeIterator<Item = Package> + '_ {
@@ -579,6 +591,10 @@ impl CargoWorkspace {
     fn is_unique(&self, name: &str) -> bool {
         self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
     }
+
+    pub fn is_virtual_workspace(&self) -> bool {
+        self.is_virtual_workspace
+    }
 }
 
 fn find_list_of_build_targets(
diff --git a/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs b/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs
index a8be5dff7b6..a72dab60752 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs
@@ -29,6 +29,12 @@ impl TryFrom<AbsPathBuf> for ManifestPath {
     }
 }
 
+impl From<ManifestPath> for AbsPathBuf {
+    fn from(it: ManifestPath) -> Self {
+        it.file
+    }
+}
+
 impl ManifestPath {
     // Shadow `parent` from `Deref`.
     pub fn parent(&self) -> &AbsPath {
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index 988eff9be44..71ddee30910 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -11,8 +11,9 @@ use base_db::{
 };
 use cfg::{CfgAtom, CfgDiff, CfgOptions};
 use intern::{sym, Symbol};
+use itertools::Itertools;
 use paths::{AbsPath, AbsPathBuf};
-use rustc_hash::{FxHashMap, FxHashSet};
+use rustc_hash::FxHashMap;
 use semver::Version;
 use span::{Edition, FileId};
 use toolchain::Tool;
@@ -41,7 +42,9 @@ pub type FileLoader<'a> = &'a mut dyn for<'b> FnMut(&'b AbsPath) -> Option<FileI
 pub struct PackageRoot {
     /// Is from the local filesystem and may be edited
     pub is_local: bool,
+    /// Directories to include
     pub include: Vec<AbsPathBuf>,
+    /// Directories to exclude
     pub exclude: Vec<AbsPathBuf>,
 }
 
@@ -553,17 +556,6 @@ impl ProjectWorkspace {
         }
     }
 
-    pub fn buildfiles(&self) -> Vec<AbsPathBuf> {
-        match &self.kind {
-            ProjectWorkspaceKind::Json(project) => project
-                .crates()
-                .filter_map(|(_, krate)| krate.build.as_ref().map(|build| build.build_file.clone()))
-                .map(|build_file| self.workspace_root().join(build_file))
-                .collect(),
-            _ => vec![],
-        }
-    }
-
     pub fn find_sysroot_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> {
         self.sysroot.discover_proc_macro_srv()
     }
@@ -608,15 +600,25 @@ impl ProjectWorkspace {
         match &self.kind {
             ProjectWorkspaceKind::Json(project) => project
                 .crates()
-                .map(|(_, krate)| PackageRoot {
-                    is_local: krate.is_workspace_member,
-                    include: krate.include.clone(),
-                    exclude: krate.exclude.clone(),
+                .map(|(_, krate)| {
+                    let build_files = project
+                        .crates()
+                        .filter_map(|(_, krate)| {
+                            krate.build.as_ref().map(|build| build.build_file.clone())
+                        })
+                        // FIXME: PackageRoots dont allow specifying files, only directories
+                        .filter_map(|build_file| {
+                            self.workspace_root().join(build_file).parent().map(ToOwned::to_owned)
+                        });
+                    PackageRoot {
+                        is_local: krate.is_workspace_member,
+                        include: krate.include.iter().cloned().chain(build_files).collect(),
+                        exclude: krate.exclude.clone(),
+                    }
                 })
-                .collect::<FxHashSet<_>>()
-                .into_iter()
                 .chain(mk_sysroot())
-                .collect::<Vec<_>>(),
+                .unique()
+                .collect(),
             ProjectWorkspaceKind::Cargo {
                 cargo,
                 rustc,
@@ -671,6 +673,11 @@ impl ProjectWorkspace {
                             exclude: Vec::new(),
                         })
                     }))
+                    .chain(cargo.is_virtual_workspace().then(|| PackageRoot {
+                        is_local: true,
+                        include: vec![cargo.workspace_root().to_path_buf()],
+                        exclude: Vec::new(),
+                    }))
                     .collect()
             }
             ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => {
diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs
index 7b8e6840fc9..9116f1606fa 100644
--- a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs
+++ b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs
@@ -11,7 +11,7 @@
 /// case), and we know that the query only used inputs of medium
 /// durability or higher, then we can skip that enumeration.
 ///
-/// Typically, one assigns low durabilites to inputs that the user is
+/// Typically, one assigns low durabilities to inputs that the user is
 /// frequently editing. Medium or high durabilities are used for
 /// configuration, the source from library crates, or other things
 /// that are unlikely to be edited.
diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs
index bd1ab6971cb..8530521d915 100644
--- a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs
@@ -291,7 +291,7 @@ pub trait ParallelDatabase: Database + Send {
     /// # Panics
     ///
     /// It is not permitted to create a snapshot from inside of a
-    /// query. Attepting to do so will panic.
+    /// query. Attempting to do so will panic.
     ///
     /// # Deadlock warning
     ///
diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs
index 81136626551..3c3931e6585 100644
--- a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs
+++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs
@@ -255,7 +255,7 @@ fn cycle_revalidate_unchanged_twice() {
     db.set_b_invokes(CycleQuery::A);
 
     assert!(db.cycle_a().is_err());
-    db.set_c_invokes(CycleQuery::A); // force new revisi5on
+    db.set_c_invokes(CycleQuery::A); // force new revision
 
     // on this run
     expect![[r#"
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
index eac33be5664..a753621eca8 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
@@ -51,7 +51,9 @@ fn actual_main() -> anyhow::Result<ExitCode> {
         }
     }
 
-    setup_logging(flags.log_file.clone())?;
+    if let Err(e) = setup_logging(flags.log_file.clone()) {
+        eprintln!("Failed to setup logging: {e:#}");
+    }
 
     let verbosity = flags.verbosity();
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index e3ea441f3ab..66cd2e424e3 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -331,8 +331,8 @@ impl flags::AnalysisStats {
         let mut fail = 0;
         for &b in bodies {
             let res = match b {
-                DefWithBody::Const(c) => c.render_eval(db, Edition::LATEST),
-                DefWithBody::Static(s) => s.render_eval(db, Edition::LATEST),
+                DefWithBody::Const(c) => c.eval(db),
+                DefWithBody::Static(s) => s.eval(db),
                 _ => continue,
             };
             all += 1;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index bf7aca42faf..40fd294e72a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -827,6 +827,7 @@ impl Config {
         let mut should_update = false;
 
         if let Some(change) = change.user_config_change {
+            tracing::info!("updating config from user config toml: {:#}", change);
             if let Ok(table) = toml::from_str(&change) {
                 let mut toml_errors = vec![];
                 validate_toml_table(
@@ -919,7 +920,7 @@ impl Config {
                     RatomlFileKind::Crate => {
                         if let Some(text) = text {
                             let mut toml_errors = vec![];
-                            tracing::info!("updating ra-toml config: {:#}", text);
+                            tracing::info!("updating ra-toml crate config: {:#}", text);
                             match toml::from_str(&text) {
                                 Ok(table) => {
                                     validate_toml_table(
@@ -961,6 +962,7 @@ impl Config {
                     }
                     RatomlFileKind::Workspace => {
                         if let Some(text) = text {
+                            tracing::info!("updating ra-toml workspace config: {:#}", text);
                             let mut toml_errors = vec![];
                             match toml::from_str(&text) {
                                 Ok(table) => {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 5f835702840..29be53cee1d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -417,8 +417,10 @@ impl GlobalState {
                     })
                     .collect_vec();
 
-                for (file_id, (_change_kind, vfs_path)) in modified_ratoml_files {
+                for (file_id, (change_kind, vfs_path)) in modified_ratoml_files {
+                    tracing::info!(%vfs_path, ?change_kind, "Processing rust-analyzer.toml changes");
                     if vfs_path.as_path() == user_config_abs_path {
+                        tracing::info!(%vfs_path, ?change_kind, "Use config rust-analyzer.toml changes");
                         change.change_user_config(Some(db.file_text(file_id)));
                         continue;
                     }
@@ -430,12 +432,14 @@ impl GlobalState {
 
                     if !sr.is_library {
                         let entry = if workspace_ratoml_paths.contains(&vfs_path) {
+                            tracing::info!(%vfs_path, ?sr_id, "workspace rust-analyzer.toml changes");
                             change.change_workspace_ratoml(
                                 sr_id,
                                 vfs_path.clone(),
                                 Some(db.file_text(file_id)),
                             )
                         } else {
+                            tracing::info!(%vfs_path, ?sr_id, "crate rust-analyzer.toml changes");
                             change.change_ratoml(
                                 sr_id,
                                 vfs_path.clone(),
@@ -446,7 +450,7 @@ impl GlobalState {
                         if let Some((kind, old_path, old_text)) = entry {
                             // SourceRoot has more than 1 RATOML files. In this case lexicographically smaller wins.
                             if old_path < vfs_path {
-                                span!(Level::ERROR, "Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect.");
+                                tracing::error!("Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect.");
                                 // Put the old one back in.
                                 match kind {
                                     RatomlFileKind::Crate => {
@@ -459,8 +463,7 @@ impl GlobalState {
                             }
                         }
                     } else {
-                        // Mapping to a SourceRoot should always end up in `Ok`
-                        span!(Level::ERROR, "Mapping to SourceRootId failed.");
+                        tracing::info!(%vfs_path, "Ignoring library rust-analyzer.toml");
                     }
                 }
                 change.change_source_root_parent_map(self.local_roots_parent_map.clone());
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 05c2a8354da..eb96ab6ef59 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -895,7 +895,29 @@ pub fn item_const(
         None => String::new(),
         Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("{visibility} const {name}: {ty} = {expr};"))
+    ast_from_text(&format!("{visibility}const {name}: {ty} = {expr};"))
+}
+
+pub fn item_static(
+    visibility: Option<ast::Visibility>,
+    is_unsafe: bool,
+    is_mut: bool,
+    name: ast::Name,
+    ty: ast::Type,
+    expr: Option<ast::Expr>,
+) -> ast::Static {
+    let visibility = match visibility {
+        None => String::new(),
+        Some(it) => format!("{it} "),
+    };
+    let is_unsafe = if is_unsafe { "unsafe " } else { "" };
+    let is_mut = if is_mut { "mut " } else { "" };
+    let expr = match expr {
+        Some(it) => &format!(" = {it}"),
+        None => "",
+    };
+
+    ast_from_text(&format!("{visibility}{is_unsafe}static {is_mut}{name}: {ty}{expr};"))
 }
 
 pub fn unnamed_param(ty: ast::Type) -> ast::Param {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
index e86c291f76c..280c5c25cb9 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -188,6 +188,73 @@ impl SyntaxFactory {
         ast
     }
 
+    pub fn item_const(
+        &self,
+        visibility: Option<ast::Visibility>,
+        name: ast::Name,
+        ty: ast::Type,
+        expr: ast::Expr,
+    ) -> ast::Const {
+        let ast = make::item_const(visibility.clone(), name.clone(), ty.clone(), expr.clone())
+            .clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            if let Some(visibility) = visibility {
+                builder.map_node(
+                    visibility.syntax().clone(),
+                    ast.visibility().unwrap().syntax().clone(),
+                );
+            }
+            builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
+            builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
+            builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn item_static(
+        &self,
+        visibility: Option<ast::Visibility>,
+        is_unsafe: bool,
+        is_mut: bool,
+        name: ast::Name,
+        ty: ast::Type,
+        expr: Option<ast::Expr>,
+    ) -> ast::Static {
+        let ast = make::item_static(
+            visibility.clone(),
+            is_unsafe,
+            is_mut,
+            name.clone(),
+            ty.clone(),
+            expr.clone(),
+        )
+        .clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            if let Some(visibility) = visibility {
+                builder.map_node(
+                    visibility.syntax().clone(),
+                    ast.visibility().unwrap().syntax().clone(),
+                );
+            }
+
+            builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
+            builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
+
+            if let Some(expr) = expr {
+                builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone());
+            }
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn turbofish_generic_arg_list(
         &self,
         args: impl IntoIterator<Item = ast::GenericArg> + Clone,
diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc
index 246ebdab2c9..da2aa4eae4e 100644
--- a/src/tools/rust-analyzer/docs/user/manual.adoc
+++ b/src/tools/rust-analyzer/docs/user/manual.adoc
@@ -580,7 +580,7 @@ Unfortunately, it downloads an old version of `rust-analyzer`, but you can set t
 
 There is a package named `ra_ap_rust_analyzer` available on https://crates.io/crates/ra_ap_rust-analyzer[crates.io], for someone who wants to use it programmatically.
 
-For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/publish.yml[the publish workflow].
+For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/autopublish.yaml[the publish workflow].
 
 === Zed
 
diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts
index 4ce19f5c665..eac7b849fdb 100644
--- a/src/tools/rust-analyzer/editors/code/src/client.ts
+++ b/src/tools/rust-analyzer/editors/code/src/client.ts
@@ -324,7 +324,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
     }
     fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
         capabilities.experimental = {
-            snippetTextEdit: false,
+            snippetTextEdit: true,
             codeActionGroup: true,
             hoverActions: true,
             serverStatusNotification: true,
diff --git a/src/tools/rust-analyzer/xtask/Cargo.toml b/src/tools/rust-analyzer/xtask/Cargo.toml
index 4bc1821ee5e..01ad3336311 100644
--- a/src/tools/rust-analyzer/xtask/Cargo.toml
+++ b/src/tools/rust-analyzer/xtask/Cargo.toml
@@ -21,6 +21,7 @@ quote = "1.0.20"
 ungrammar = "1.16.1"
 either.workspace = true
 itertools.workspace = true
+edition.workspace = true
 # Avoid adding more dependencies to this crate
 
 [lints]
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs b/src/tools/rust-analyzer/xtask/src/codegen/lints.rs
index f097b5817be..b1a7c2fb27e 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/lints.rs
@@ -1,7 +1,15 @@
 //! Generates descriptor structures for unstable features from the unstable book
 //! and lints from rustc, rustdoc, and clippy.
-use std::{borrow::Cow, fs, path::Path};
+#![allow(clippy::disallowed_types)]
 
+use std::{
+    collections::{hash_map, HashMap},
+    fs,
+    path::Path,
+    str::FromStr,
+};
+
+use edition::Edition;
 use stdx::format_to;
 use xshell::{cmd, Shell};
 
@@ -36,10 +44,17 @@ pub(crate) fn generate(check: bool) {
 
     let mut contents = String::from(
         r"
+use span::Edition;
+
+use crate::Severity;
+
 #[derive(Clone)]
 pub struct Lint {
     pub label: &'static str,
     pub description: &'static str,
+    pub default_severity: Severity,
+    pub warn_since: Option<Edition>,
+    pub deny_since: Option<Edition>,
 }
 
 pub struct LintGroup {
@@ -68,7 +83,7 @@ pub struct LintGroup {
     let lints_json = project_root().join("./target/clippy_lints.json");
     cmd!(
         sh,
-        "curl https://rust-lang.github.io/rust-clippy/master/lints.json --output {lints_json}"
+        "curl https://rust-lang.github.io/rust-clippy/stable/lints.json --output {lints_json}"
     )
     .run()
     .unwrap();
@@ -85,6 +100,48 @@ pub struct LintGroup {
     );
 }
 
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
+enum Severity {
+    Allow,
+    Warn,
+    Deny,
+}
+
+impl std::fmt::Display for Severity {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(
+            f,
+            "Severity::{}",
+            match self {
+                Severity::Allow => "Allow",
+                Severity::Warn => "Warning",
+                Severity::Deny => "Error",
+            }
+        )
+    }
+}
+
+impl FromStr for Severity {
+    type Err = &'static str;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "allow" => Ok(Self::Allow),
+            "warn" => Ok(Self::Warn),
+            "deny" => Ok(Self::Deny),
+            _ => Err("invalid severity"),
+        }
+    }
+}
+
+#[derive(Debug)]
+struct Lint {
+    description: String,
+    default_severity: Severity,
+    warn_since: Option<Edition>,
+    deny_since: Option<Edition>,
+}
+
 /// Parses the output of `rustdoc -Whelp` and prints `Lint` and `LintGroup` constants into `buf`.
 ///
 /// As of writing, the output of `rustc -Whelp` (not rustdoc) has the following format:
@@ -108,52 +165,203 @@ pub struct LintGroup {
 /// `rustdoc -Whelp` (and any other custom `rustc` driver) adds another two
 /// tables after the `rustc` ones, with a different title but the same format.
 fn generate_lint_descriptor(sh: &Shell, buf: &mut String) {
-    let stdout = cmd!(sh, "rustdoc -Whelp").read().unwrap();
-    let lints_pat = "----  -------  -------\n";
-    let lint_groups_pat = "----  ---------\n";
-    let lints = find_and_slice(&stdout, lints_pat);
-    let lint_groups = find_and_slice(lints, lint_groups_pat);
-    let lints_rustdoc = find_and_slice(lint_groups, lints_pat);
-    let lint_groups_rustdoc = find_and_slice(lints_rustdoc, lint_groups_pat);
+    fn get_lints_as_text(
+        stdout: &str,
+    ) -> (
+        impl Iterator<Item = (String, &str, Severity)> + '_,
+        impl Iterator<Item = (String, Lint, impl Iterator<Item = String> + '_)> + '_,
+        impl Iterator<Item = (String, &str, Severity)> + '_,
+        impl Iterator<Item = (String, Lint, impl Iterator<Item = String> + '_)> + '_,
+    ) {
+        let lints_pat = "----  -------  -------\n";
+        let lint_groups_pat = "----  ---------\n";
+        let lints = find_and_slice(stdout, lints_pat);
+        let lint_groups = find_and_slice(lints, lint_groups_pat);
+        let lints_rustdoc = find_and_slice(lint_groups, lints_pat);
+        let lint_groups_rustdoc = find_and_slice(lints_rustdoc, lint_groups_pat);
+
+        let lints = lints.lines().take_while(|l| !l.is_empty()).map(|line| {
+            let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap();
+            let (severity, description) = rest.trim().split_once(char::is_whitespace).unwrap();
+            (name.trim().replace('-', "_"), description.trim(), severity.parse().unwrap())
+        });
+        let lint_groups = lint_groups.lines().take_while(|l| !l.is_empty()).map(|line| {
+            let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap();
+            let label = name.trim().replace('-', "_");
+            let lint = Lint {
+                description: format!("lint group for: {}", lints.trim()),
+                default_severity: Severity::Allow,
+                warn_since: None,
+                deny_since: None,
+            };
+            let children = lints
+                .split_ascii_whitespace()
+                .map(|s| s.trim().trim_matches(',').replace('-', "_"));
+            (label, lint, children)
+        });
 
-    buf.push_str(r#"pub const DEFAULT_LINTS: &[Lint] = &["#);
-    buf.push('\n');
+        let lints_rustdoc = lints_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| {
+            let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap();
+            let (severity, description) = rest.trim().split_once(char::is_whitespace).unwrap();
+            (name.trim().replace('-', "_"), description.trim(), severity.parse().unwrap())
+        });
+        let lint_groups_rustdoc =
+            lint_groups_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| {
+                let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap();
+                let label = name.trim().replace('-', "_");
+                let lint = Lint {
+                    description: format!("lint group for: {}", lints.trim()),
+                    default_severity: Severity::Allow,
+                    warn_since: None,
+                    deny_since: None,
+                };
+                let children = lints
+                    .split_ascii_whitespace()
+                    .map(|s| s.trim().trim_matches(',').replace('-', "_"));
+                (label, lint, children)
+            });
 
-    let lints = lints.lines().take_while(|l| !l.is_empty()).map(|line| {
-        let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap();
-        let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap();
-        (name.trim(), Cow::Borrowed(description.trim()), vec![])
-    });
-    let lint_groups = lint_groups.lines().take_while(|l| !l.is_empty()).map(|line| {
-        let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap();
-        (
-            name.trim(),
-            format!("lint group for: {}", lints.trim()).into(),
-            lints
-                .split_ascii_whitespace()
-                .map(|s| s.trim().trim_matches(',').replace('-', "_"))
-                .collect(),
-        )
-    });
+        (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc)
+    }
 
-    let mut lints = lints.chain(lint_groups).collect::<Vec<_>>();
-    lints.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2));
+    fn insert_lints<'a>(
+        edition: Edition,
+        lints_map: &mut HashMap<String, Lint>,
+        lint_groups_map: &mut HashMap<String, (Lint, Vec<String>)>,
+        lints: impl Iterator<Item = (String, &'a str, Severity)>,
+        lint_groups: impl Iterator<Item = (String, Lint, impl Iterator<Item = String>)>,
+    ) {
+        for (lint_name, lint_description, lint_severity) in lints {
+            let lint = lints_map.entry(lint_name).or_insert_with(|| Lint {
+                description: lint_description.to_owned(),
+                default_severity: Severity::Allow,
+                warn_since: None,
+                deny_since: None,
+            });
+            if lint_severity == Severity::Warn
+                && lint.warn_since.is_none()
+                && lint.default_severity < Severity::Warn
+            {
+                lint.warn_since = Some(edition);
+            }
+            if lint_severity == Severity::Deny
+                && lint.deny_since.is_none()
+                && lint.default_severity < Severity::Deny
+            {
+                lint.deny_since = Some(edition);
+            }
+        }
 
-    for (name, description, ..) in &lints {
-        push_lint_completion(buf, &name.replace('-', "_"), description);
+        for (group_name, lint, children) in lint_groups {
+            match lint_groups_map.entry(group_name) {
+                hash_map::Entry::Vacant(entry) => {
+                    entry.insert((lint, Vec::from_iter(children)));
+                }
+                hash_map::Entry::Occupied(mut entry) => {
+                    // Overwrite, because some groups (such as edition incompatibility) are changed.
+                    *entry.get_mut() = (lint, Vec::from_iter(children));
+                }
+            }
+        }
+    }
+
+    fn get_lints(
+        sh: &Shell,
+        edition: Edition,
+        lints_map: &mut HashMap<String, Lint>,
+        lint_groups_map: &mut HashMap<String, (Lint, Vec<String>)>,
+        lints_rustdoc_map: &mut HashMap<String, Lint>,
+        lint_groups_rustdoc_map: &mut HashMap<String, (Lint, Vec<String>)>,
+    ) {
+        let edition_str = edition.to_string();
+        let stdout = cmd!(sh, "rustdoc +nightly -Whelp -Zunstable-options --edition={edition_str}")
+            .read()
+            .unwrap();
+        let (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) = get_lints_as_text(&stdout);
+
+        insert_lints(edition, lints_map, lint_groups_map, lints, lint_groups);
+        insert_lints(
+            edition,
+            lints_rustdoc_map,
+            lint_groups_rustdoc_map,
+            lints_rustdoc,
+            lint_groups_rustdoc,
+        );
+    }
+
+    let basic_lints = cmd!(sh, "rustdoc +nightly -Whelp --edition=2015").read().unwrap();
+    let (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) = get_lints_as_text(&basic_lints);
+
+    let mut lints = lints
+        .map(|(label, description, severity)| {
+            (
+                label,
+                Lint {
+                    description: description.to_owned(),
+                    default_severity: severity,
+                    warn_since: None,
+                    deny_since: None,
+                },
+            )
+        })
+        .collect::<HashMap<_, _>>();
+    let mut lint_groups = lint_groups
+        .map(|(label, lint, children)| (label, (lint, Vec::from_iter(children))))
+        .collect::<HashMap<_, _>>();
+    let mut lints_rustdoc = lints_rustdoc
+        .map(|(label, description, severity)| {
+            (
+                label,
+                Lint {
+                    description: description.to_owned(),
+                    default_severity: severity,
+                    warn_since: None,
+                    deny_since: None,
+                },
+            )
+        })
+        .collect::<HashMap<_, _>>();
+    let mut lint_groups_rustdoc = lint_groups_rustdoc
+        .map(|(label, lint, children)| (label, (lint, Vec::from_iter(children))))
+        .collect::<HashMap<_, _>>();
+
+    for edition in Edition::iter().skip(1) {
+        get_lints(
+            sh,
+            edition,
+            &mut lints,
+            &mut lint_groups,
+            &mut lints_rustdoc,
+            &mut lint_groups_rustdoc,
+        );
+    }
+
+    let mut lints = Vec::from_iter(lints);
+    lints.sort_unstable_by(|a, b| a.0.cmp(&b.0));
+    let mut lint_groups = Vec::from_iter(lint_groups);
+    lint_groups.sort_unstable_by(|a, b| a.0.cmp(&b.0));
+    let mut lints_rustdoc = Vec::from_iter(lints_rustdoc);
+    lints_rustdoc.sort_unstable_by(|a, b| a.0.cmp(&b.0));
+    let mut lint_groups_rustdoc = Vec::from_iter(lint_groups_rustdoc);
+    lint_groups_rustdoc.sort_unstable_by(|a, b| a.0.cmp(&b.0));
+
+    buf.push_str(r#"pub const DEFAULT_LINTS: &[Lint] = &["#);
+    buf.push('\n');
+
+    for (name, lint) in &lints {
+        push_lint_completion(buf, name, lint);
+    }
+    for (name, (group, _)) in &lint_groups {
+        push_lint_completion(buf, name, group);
     }
     buf.push_str("];\n\n");
 
     buf.push_str(r#"pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &["#);
-    for (name, description, children) in &lints {
-        if !children.is_empty() {
-            // HACK: warnings is emitted with a general description, not with its members
-            if name == &"warnings" {
-                push_lint_group(buf, name, description, &Vec::new());
-                continue;
-            }
-            push_lint_group(buf, &name.replace('-', "_"), description, children);
+    for (name, (lint, children)) in &lint_groups {
+        if name == "warnings" {
+            continue;
         }
+        push_lint_group(buf, name, lint, children);
     }
     buf.push('\n');
     buf.push_str("];\n");
@@ -164,37 +372,17 @@ fn generate_lint_descriptor(sh: &Shell, buf: &mut String) {
     buf.push_str(r#"pub const RUSTDOC_LINTS: &[Lint] = &["#);
     buf.push('\n');
 
-    let lints_rustdoc = lints_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| {
-        let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap();
-        let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap();
-        (name.trim(), Cow::Borrowed(description.trim()), vec![])
-    });
-    let lint_groups_rustdoc =
-        lint_groups_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| {
-            let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap();
-            (
-                name.trim(),
-                format!("lint group for: {}", lints.trim()).into(),
-                lints
-                    .split_ascii_whitespace()
-                    .map(|s| s.trim().trim_matches(',').replace('-', "_"))
-                    .collect(),
-            )
-        });
-
-    let mut lints_rustdoc = lints_rustdoc.chain(lint_groups_rustdoc).collect::<Vec<_>>();
-    lints_rustdoc.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2));
-
-    for (name, description, ..) in &lints_rustdoc {
-        push_lint_completion(buf, &name.replace('-', "_"), description)
+    for (name, lint) in &lints_rustdoc {
+        push_lint_completion(buf, name, lint);
+    }
+    for (name, (group, _)) in &lint_groups_rustdoc {
+        push_lint_completion(buf, name, group);
     }
     buf.push_str("];\n\n");
 
     buf.push_str(r#"pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &["#);
-    for (name, description, children) in &lints_rustdoc {
-        if !children.is_empty() {
-            push_lint_group(buf, &name.replace('-', "_"), description, children);
-        }
+    for (name, (lint, children)) in &lint_groups_rustdoc {
+        push_lint_group(buf, name, lint, children);
     }
     buf.push('\n');
     buf.push_str("];\n");
@@ -228,13 +416,19 @@ fn generate_feature_descriptor(buf: &mut String, src_dir: &Path) {
 
     buf.push_str(r#"pub const FEATURES: &[Lint] = &["#);
     for (feature_ident, doc) in features.into_iter() {
-        push_lint_completion(buf, &feature_ident, &doc)
+        let lint = Lint {
+            description: doc,
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
+        };
+        push_lint_completion(buf, &feature_ident, &lint);
     }
     buf.push('\n');
     buf.push_str("];\n");
 }
 
-#[derive(Default)]
+#[derive(Debug, Default)]
 struct ClippyLint {
     help: String,
     id: String,
@@ -295,8 +489,14 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) {
     buf.push('\n');
     for clippy_lint in clippy_lints.into_iter() {
         let lint_ident = format!("clippy::{}", clippy_lint.id);
-        let doc = clippy_lint.help;
-        push_lint_completion(buf, &lint_ident, &doc);
+        let lint = Lint {
+            description: clippy_lint.help,
+            // Allow clippy lints by default, not all users want them.
+            default_severity: Severity::Allow,
+            warn_since: None,
+            deny_since: None,
+        };
+        push_lint_completion(buf, &lint_ident, &lint);
     }
     buf.push_str("];\n");
 
@@ -306,33 +506,59 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) {
         if !children.is_empty() {
             let lint_ident = format!("clippy::{id}");
             let description = format!("lint group for: {}", children.join(", "));
-            push_lint_group(buf, &lint_ident, &description, &children);
+            let lint = Lint {
+                description,
+                default_severity: Severity::Allow,
+                warn_since: None,
+                deny_since: None,
+            };
+            push_lint_group(buf, &lint_ident, &lint, &children);
         }
     }
     buf.push('\n');
     buf.push_str("];\n");
 }
 
-fn push_lint_completion(buf: &mut String, label: &str, description: &str) {
+fn push_lint_completion(buf: &mut String, name: &str, lint: &Lint) {
     format_to!(
         buf,
         r###"    Lint {{
         label: "{}",
         description: r##"{}"##,
-    }},"###,
-        label,
-        description,
+        default_severity: {},
+        warn_since: "###,
+        name,
+        lint.description,
+        lint.default_severity,
+    );
+    match lint.warn_since {
+        Some(edition) => format_to!(buf, "Some(Edition::Edition{edition})"),
+        None => buf.push_str("None"),
+    }
+    format_to!(
+        buf,
+        r###",
+        deny_since: "###
+    );
+    match lint.deny_since {
+        Some(edition) => format_to!(buf, "Some(Edition::Edition{edition})"),
+        None => buf.push_str("None"),
+    }
+    format_to!(
+        buf,
+        r###",
+    }},"###
     );
 }
 
-fn push_lint_group(buf: &mut String, label: &str, description: &str, children: &[String]) {
+fn push_lint_group(buf: &mut String, name: &str, lint: &Lint, children: &[String]) {
     buf.push_str(
         r###"    LintGroup {
         lint:
         "###,
     );
 
-    push_lint_completion(buf, label, description);
+    push_lint_completion(buf, name, lint);
 
     let children = format!(
         "&[{}]",
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 77c9818b66b..16b7e7aa709 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -413,7 +413,8 @@ pub(crate) fn format_expr(
         ast::ExprKind::FormatArgs(..)
         | ast::ExprKind::Type(..)
         | ast::ExprKind::IncludedBytes(..)
-        | ast::ExprKind::OffsetOf(..) => {
+        | ast::ExprKind::OffsetOf(..)
+        | ast::ExprKind::UnsafeBinderCast(..) => {
             // These don't normally occur in the AST because macros aren't expanded. However,
             // rustfmt tries to parse macro arguments when formatting macros, so it's not totally
             // impossible for rustfmt to come across one of these nodes when formatting a file.
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 18932587f1f..c3debc2f4f0 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -3597,7 +3597,7 @@ pub(crate) fn rewrite_extern_crate(
 pub(crate) fn is_mod_decl(item: &ast::Item) -> bool {
     !matches!(
         item.kind,
-        ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _))
+        ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _))
     )
 }
 
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index 493b04f16c6..a40ee7f66a9 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -316,12 +316,11 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
             self.directory = directory;
         }
         match (sub_mod.ast_mod_kind, sub_mod.items) {
-            (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => {
+            (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _, _))), _) => {
                 self.visit_mod_from_ast(items)
             }
-            (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => {
-                self.visit_mod_outside_ast(items)
-            }
+            (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _, _))), _)
+            | (_, Cow::Owned(items)) => self.visit_mod_outside_ast(items),
             (_, _) => Ok(()),
         }
     }
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index dd4a788c002..f8b713117f4 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -1016,6 +1016,31 @@ impl Rewrite for ast::Ty {
                 let pat = pat.rewrite_result(context, shape)?;
                 Ok(format!("{ty} is {pat}"))
             }
+            ast::TyKind::UnsafeBinder(ref binder) => {
+                let mut result = String::new();
+                if let Some(ref lifetime_str) =
+                    rewrite_bound_params(context, shape, &binder.generic_params)
+                {
+                    result.push_str("unsafe<");
+                    result.push_str(lifetime_str);
+                    result.push_str("> ");
+                }
+
+                let inner_ty_shape = if context.use_block_indent() {
+                    shape
+                        .offset_left(result.len())
+                        .max_width_error(shape.width, self.span())?
+                } else {
+                    shape
+                        .visual_indent(result.len())
+                        .sub_width(result.len())
+                        .max_width_error(shape.width, self.span())?
+                };
+
+                let rewrite = binder.inner_ty.rewrite_result(context, inner_ty_shape)?;
+                result.push_str(&rewrite);
+                Ok(result)
+            }
         }
     }
 }
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index 0ca34a79491..ba4a4c045f1 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -504,6 +504,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::IncludedBytes(..)
         | ast::ExprKind::InlineAsm(..)
         | ast::ExprKind::OffsetOf(..)
+        | ast::ExprKind::UnsafeBinderCast(..)
         | ast::ExprKind::Let(..)
         | ast::ExprKind::Path(..)
         | ast::ExprKind::Range(..)
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index 9b116b620b7..805e13b7803 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -927,7 +927,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         let ident_str = rewrite_ident(&self.get_context(), ident).to_owned();
         self.push_str(&ident_str);
 
-        if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans) = mod_kind {
+        if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans, _) = mod_kind {
             let ast::ModSpans {
                 inner_span,
                 inject_use_span: _,
diff --git a/src/tools/rustfmt/tests/source/unsafe-binders.rs b/src/tools/rustfmt/tests/source/unsafe-binders.rs
new file mode 100644
index 00000000000..ccf7c8bb9af
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/unsafe-binders.rs
@@ -0,0 +1,11 @@
+fn foo() -> unsafe<'a>
+&'a () {}
+
+struct Foo {
+    x: unsafe<'a>
+&'a (),
+}
+
+struct Bar(unsafe<'a> &'a ());
+
+impl Trait for unsafe<'a> &'a () {}
diff --git a/src/tools/rustfmt/tests/target/unsafe-binders.rs b/src/tools/rustfmt/tests/target/unsafe-binders.rs
new file mode 100644
index 00000000000..9d308f4a894
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/unsafe-binders.rs
@@ -0,0 +1,9 @@
+fn foo() -> unsafe<'a> &'a () {}
+
+struct Foo {
+    x: unsafe<'a> &'a (),
+}
+
+struct Bar(unsafe<'a> &'a ());
+
+impl Trait for unsafe<'a> &'a () {}
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/codegen/bounds-checking/gep-issue-133979.rs b/tests/codegen/bounds-checking/gep-issue-133979.rs
new file mode 100644
index 00000000000..876bdbfb0e1
--- /dev/null
+++ b/tests/codegen/bounds-checking/gep-issue-133979.rs
@@ -0,0 +1,22 @@
+//! Issue: <https://github.com/rust-lang/rust/issues/133979>
+//! Check that bounds checking are eliminated.
+
+//@ compile-flags: -Copt-level=2
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @test(
+#[no_mangle]
+fn test(a: &[&[u8]]) -> u32 {
+    // CHECK-NOT: panic_bounds_check
+    a.iter()
+        .enumerate()
+        .map(|(y, b)| {
+            b.iter()
+                .enumerate()
+                .filter(|(_, c)| **c == b'A')
+                .map(|(x, _)| a[y][x] as u32)
+                .sum::<u32>()
+        })
+        .sum()
+}
diff --git a/tests/codegen/gep-index.rs b/tests/codegen/gep-index.rs
new file mode 100644
index 00000000000..1f5e8855910
--- /dev/null
+++ b/tests/codegen/gep-index.rs
@@ -0,0 +1,37 @@
+//! Check that index and offset use the same getelementptr format.
+
+//@ revisions: NO-OPT OPT
+//@[NO-OPT] compile-flags: -Copt-level=0
+//@[OPT] compile-flags: -Copt-level=1
+
+#![crate_type = "lib"]
+
+struct Foo(i32, i32);
+
+// CHECK-LABEL: @index_on_struct(
+#[no_mangle]
+fn index_on_struct(a: &[Foo], index: usize) -> &Foo {
+    // CHECK: getelementptr inbounds %Foo, ptr %a.0, {{i64|i32}} %index
+    &a[index]
+}
+
+// CHECK-LABEL: @offset_on_struct(
+#[no_mangle]
+fn offset_on_struct(a: *const Foo, index: usize) -> *const Foo {
+    // CHECK: getelementptr inbounds %Foo, ptr %a, {{i64|i32}} %index
+    unsafe { a.add(index) }
+}
+
+// CHECK-LABEL: @index_on_i32(
+#[no_mangle]
+fn index_on_i32(a: &[i32], index: usize) -> &i32 {
+    // CHECK: getelementptr inbounds i32, ptr %a.0, {{i64|i32}} %index
+    &a[index]
+}
+
+// CHECK-LABEL: @offset_on_i32(
+#[no_mangle]
+fn offset_on_i32(a: *const i32, index: usize) -> *const i32 {
+    // CHECK: getelementptr inbounds i32, ptr %a, {{i64|i32}} %index
+    unsafe { a.add(index) }
+}
diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs
index e62adfa0ba6..0b2229ba7d1 100644
--- a/tests/codegen/mem-replace-big-type.rs
+++ b/tests/codegen/mem-replace-big-type.rs
@@ -25,9 +25,10 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
 // CHECK-NOT: call void @llvm.memcpy
 
 // For a large type, we expect exactly three `memcpy`s
-// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret([56 x i8])
+// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}(ptr
+// CHECK-SAME: sret([56 x i8]){{.+}}[[RESULT:%.+]], ptr{{.+}}%dest, ptr{{.+}}%src)
 // CHECK-NOT: call void @llvm.memcpy
-// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %result, ptr align 8 %dest, i{{.*}} 56, i1 false)
+// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 [[RESULT]], ptr align 8 %dest, i{{.*}} 56, i1 false)
 // CHECK-NOT: call void @llvm.memcpy
 // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %dest, ptr align 8 %src, i{{.*}} 56, i1 false)
 // CHECK-NOT: call void @llvm.memcpy
diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs
index bcaa60baeff..8efedab6ea5 100644
--- a/tests/codegen/naked-asan.rs
+++ b/tests/codegen/naked-asan.rs
@@ -8,14 +8,15 @@
 #![no_std]
 #![feature(abi_x86_interrupt, naked_functions)]
 
-// CHECK: define x86_intrcc void @page_fault_handler(ptr {{.*}}%0, i64 {{.*}}%1){{.*}}#[[ATTRS:[0-9]+]] {
-// CHECK-NOT: memcpy
+pub fn caller() {
+    page_fault_handler(1, 2);
+}
+
+// CHECK: declare x86_intrcc void @page_fault_handler(ptr {{.*}}, i64{{.*}}){{.*}}#[[ATTRS:[0-9]+]]
 #[naked]
 #[no_mangle]
 pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
-    unsafe {
-        core::arch::naked_asm!("ud2");
-    }
+    unsafe { core::arch::naked_asm!("ud2") };
 }
 
 // CHECK: #[[ATTRS]] =
diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs
index 3bbd67981e5..d9dcd7f6c3e 100644
--- a/tests/codegen/naked-fn/aligned.rs
+++ b/tests/codegen/naked-fn/aligned.rs
@@ -6,15 +6,12 @@
 #![feature(naked_functions, fn_align)]
 use std::arch::naked_asm;
 
-// CHECK: Function Attrs: naked
-// CHECK-NEXT: define{{.*}}void @naked_empty()
-// CHECK: align 16
+// CHECK: .balign 16
+// CHECK-LABEL: naked_empty:
 #[repr(align(16))]
 #[no_mangle]
 #[naked]
 pub unsafe extern "C" fn naked_empty() {
-    // CHECK-NEXT: start:
-    // CHECK-NEXT: call void asm
-    // CHECK-NEXT: unreachable
+    // CHECK: ret
     naked_asm!("ret");
 }
diff --git a/tests/codegen/naked-fn/generics.rs b/tests/codegen/naked-fn/generics.rs
new file mode 100644
index 00000000000..a33d213617a
--- /dev/null
+++ b/tests/codegen/naked-fn/generics.rs
@@ -0,0 +1,116 @@
+//@ compile-flags: -O
+//@ only-x86_64
+
+#![crate_type = "lib"]
+#![feature(naked_functions, asm_const)]
+
+use std::arch::naked_asm;
+
+#[no_mangle]
+fn test(x: u64) {
+    // just making sure these symbols get used
+    using_const_generics::<1>(x);
+    using_const_generics::<2>(x);
+
+    generic_function::<i64>(x as i64);
+
+    let foo = Foo(x);
+
+    foo.method();
+    foo.trait_method();
+}
+
+// CHECK: .balign 4
+// CHECK: add rax, 2
+// CHECK: add rax, 42
+
+// CHECK: .balign 4
+// CHECK: add rax, 1
+// CHECK: add rax, 42
+
+#[naked]
+pub extern "C" fn using_const_generics<const N: u64>(x: u64) -> u64 {
+    const M: u64 = 42;
+
+    unsafe {
+        naked_asm!(
+            "xor rax, rax",
+            "add rax, rdi",
+            "add rax, {}",
+            "add rax, {}",
+            "ret",
+            const N,
+            const M,
+        )
+    }
+}
+
+trait Invert {
+    fn invert(self) -> Self;
+}
+
+impl Invert for i64 {
+    fn invert(self) -> Self {
+        -1 * self
+    }
+}
+
+// CHECK: .balign 4
+// CHECK-LABEL: generic_function:
+// CHECK: call
+// CHECK: ret
+
+#[naked]
+#[no_mangle]
+pub extern "C" fn generic_function<T: Invert>(x: i64) -> i64 {
+    unsafe {
+        naked_asm!(
+            "call {}",
+            "ret",
+            sym <T as Invert>::invert,
+        )
+    }
+}
+
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+struct Foo(u64);
+
+// CHECK: .balign 4
+// CHECK-LABEL: method:
+// CHECK: mov rax, rdi
+
+impl Foo {
+    #[naked]
+    #[no_mangle]
+    extern "C" fn method(self) -> u64 {
+        unsafe { naked_asm!("mov rax, rdi", "ret") }
+    }
+}
+
+// CHECK: .balign 4
+// CHECK-LABEL: trait_method:
+// CHECK: mov rax, rdi
+
+trait Bar {
+    extern "C" fn trait_method(self) -> u64;
+}
+
+impl Bar for Foo {
+    #[naked]
+    #[no_mangle]
+    extern "C" fn trait_method(self) -> u64 {
+        unsafe { naked_asm!("mov rax, rdi", "ret") }
+    }
+}
+
+// CHECK: .balign 4
+// CHECK-LABEL: naked_with_args_and_return:
+// CHECK: lea rax, [rdi + rsi]
+
+// this previously ICE'd, see https://github.com/rust-lang/rust/issues/124375
+#[naked]
+#[no_mangle]
+pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
+    naked_asm!("lea rax, [rdi + rsi]", "ret");
+}
diff --git a/tests/codegen/naked-fn/instruction-set.rs b/tests/codegen/naked-fn/instruction-set.rs
new file mode 100644
index 00000000000..5b790b2034c
--- /dev/null
+++ b/tests/codegen/naked-fn/instruction-set.rs
@@ -0,0 +1,59 @@
+//@ revisions: arm-mode thumb-mode
+//@ [arm-mode] compile-flags: --target armv5te-none-eabi
+//@ [thumb-mode] compile-flags: --target thumbv5te-none-eabi
+//@ [arm-mode] needs-llvm-components: arm
+//@ [thumb-mode] needs-llvm-components: arm
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items, rustc_attrs, naked_functions)]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! naked_asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+// arm-mode: .arm
+// thumb-mode: .thumb
+// CHECK-LABEL: test_unspecified:
+// CHECK: bx lr
+// CHECK: .popsection
+// arm-mode: .arm
+// thumb-mode: .thumb
+#[no_mangle]
+#[naked]
+unsafe extern "C" fn test_unspecified() {
+    naked_asm!("bx lr");
+}
+
+// CHECK: .thumb
+// CHECK: .thumb_func
+// CHECK-LABEL: test_thumb:
+// CHECK: bx lr
+// CHECK: .popsection
+// arm-mode: .arm
+// thumb-mode: .thumb
+#[no_mangle]
+#[naked]
+#[instruction_set(arm::t32)]
+unsafe extern "C" fn test_thumb() {
+    naked_asm!("bx lr");
+}
+
+// CHECK: .arm
+// CHECK-LABEL: test_arm:
+// CHECK: bx lr
+// CHECK: .popsection
+// arm-mode: .arm
+// thumb-mode: .thumb
+#[no_mangle]
+#[naked]
+#[instruction_set(arm::a32)]
+unsafe extern "C" fn test_arm() {
+    naked_asm!("bx lr");
+}
diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs
index 3f7447af599..f505d27d48c 100644
--- a/tests/codegen/naked-fn/naked-functions.rs
+++ b/tests/codegen/naked-fn/naked-functions.rs
@@ -1,29 +1,147 @@
-//@ compile-flags: -C no-prepopulate-passes -Copt-level=0
-//@ needs-asm-support
-//@ only-x86_64
+//@ revisions: linux win macos thumb
+//
+//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
+//@[linux] needs-llvm-components: x86
+//@[win] compile-flags: --target x86_64-pc-windows-gnu
+//@[win] needs-llvm-components: x86
+//@[macos] compile-flags: --target aarch64-apple-darwin
+//@[macos] needs-llvm-components: arm
+//@[thumb] compile-flags: --target thumbv7em-none-eabi
+//@[thumb] needs-llvm-components: arm
 
 #![crate_type = "lib"]
-#![feature(naked_functions)]
-use std::arch::naked_asm;
+#![feature(no_core, lang_items, rustc_attrs, naked_functions)]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! naked_asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+// linux,win: .intel_syntax
+//
+// linux:   .pushsection .text.naked_empty,\22ax\22, @progbits
+// macos:   .pushsection __TEXT,__text,regular,pure_instructions
+// win: .pushsection .text.naked_empty,\22xr\22
+// thumb:   .pushsection .text.naked_empty,\22ax\22, %progbits
+//
+// CHECK: .balign 4
+//
+// linux,win,thumb: .globl naked_empty
+// macos: .globl _naked_empty
+//
+// CHECK-NOT: .private_extern
+// CHECK-NOT: .hidden
+//
+// linux: .type naked_empty, @function
+//
+// win: .def naked_empty
+// win: .scl 2
+// win: .type 32
+// win: .endef naked_empty
+//
+// thumb: .type naked_empty, %function
+// thumb: .thumb
+// thumb: .thumb_func
+//
+// CHECK-LABEL: naked_empty:
+//
+// linux,macos,win: ret
+// thumb: bx lr
+//
+// CHECK: .popsection
+//
+// thumb: .thumb
+//
+// linux,win: .att_syntax
 
-// CHECK: Function Attrs: naked
-// CHECK-NEXT: define{{.*}}void @naked_empty()
 #[no_mangle]
 #[naked]
 pub unsafe extern "C" fn naked_empty() {
-    // CHECK-NEXT: {{.+}}:
-    // CHECK-NEXT: call void asm
-    // CHECK-NEXT: unreachable
+    #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))]
     naked_asm!("ret");
+
+    #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))]
+    naked_asm!("bx lr");
 }
 
-// CHECK: Function Attrs: naked
-// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %0, i64 %1)
+// linux,win: .intel_syntax
+//
+// linux:   .pushsection .text.naked_with_args_and_return,\22ax\22, @progbits
+// macos:   .pushsection __TEXT,__text,regular,pure_instructions
+// win: .pushsection .text.naked_with_args_and_return,\22xr\22
+// thumb:   .pushsection .text.naked_with_args_and_return,\22ax\22, %progbits
+//
+// CHECK: .balign 4
+//
+// linux,win,thumb: .globl naked_with_args_and_return
+// macos: .globl _naked_with_args_and_return
+//
+// CHECK-NOT: .private_extern
+// CHECK-NOT: .hidden
+//
+// linux: .type naked_with_args_and_return, @function
+//
+// win: .def naked_with_args_and_return
+// win: .scl 2
+// win: .type 32
+// win: .endef naked_with_args_and_return
+//
+// thumb: .type naked_with_args_and_return, %function
+// thumb: .thumb
+// thumb: .thumb_func
+//
+// CHECK-LABEL: naked_with_args_and_return:
+//
+// linux, win: lea rax, [rdi + rsi]
+// macos: add x0, x0, x1
+// thumb: adds r0, r0, r1
+//
+// linux,macos,win: ret
+// thumb: bx lr
+//
+// CHECK: .popsection
+//
+// thumb: .thumb
+//
+// linux,win: .att_syntax
+
 #[no_mangle]
 #[naked]
 pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
-    // CHECK-NEXT: {{.+}}:
-    // CHECK-NEXT: call void asm
-    // CHECK-NEXT: unreachable
-    naked_asm!("lea rax, [rdi + rsi]", "ret");
+    #[cfg(any(target_os = "windows", target_os = "linux"))]
+    {
+        naked_asm!("lea rax, [rdi + rsi]", "ret")
+    }
+
+    #[cfg(target_os = "macos")]
+    {
+        naked_asm!("add x0, x0, x1", "ret")
+    }
+
+    #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))]
+    {
+        naked_asm!("adds r0, r0, r1", "bx lr")
+    }
+}
+
+// linux:   .pushsection .text.some_different_name,\22ax\22, @progbits
+// macos:   .pushsection .text.some_different_name,regular,pure_instructions
+// win: .pushsection .text.some_different_name,\22xr\22
+// thumb:   .pushsection .text.some_different_name,\22ax\22, %progbits
+// CHECK-LABEL: test_link_section:
+#[no_mangle]
+#[naked]
+#[link_section = ".text.some_different_name"]
+pub unsafe extern "C" fn test_link_section() {
+    #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))]
+    naked_asm!("ret");
+
+    #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))]
+    naked_asm!("bx lr");
 }
diff --git a/tests/codegen/naked-fn/naked-nocoverage.rs b/tests/codegen/naked-fn/naked-nocoverage.rs
deleted file mode 100644
index f63661bcd3a..00000000000
--- a/tests/codegen/naked-fn/naked-nocoverage.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Checks that naked functions are not instrumented by -Cinstrument-coverage.
-// Regression test for issue #105170.
-//
-//@ needs-asm-support
-//@ compile-flags: -Zno-profiler-runtime
-//@ compile-flags: -Cinstrument-coverage
-#![crate_type = "lib"]
-#![feature(naked_functions)]
-use std::arch::naked_asm;
-
-#[naked]
-#[no_mangle]
-pub unsafe extern "C" fn f() {
-    // CHECK:       define {{(dso_local )?}}void @f()
-    // CHECK-NEXT:  start:
-    // CHECK-NEXT:    call void asm
-    // CHECK-NEXT:    unreachable
-    naked_asm!("");
-}
diff --git a/tests/codegen/naked-fn/naked-noinline.rs b/tests/codegen/naked-fn/naked-noinline.rs
deleted file mode 100644
index 6ea36d96783..00000000000
--- a/tests/codegen/naked-fn/naked-noinline.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Checks that naked functions are never inlined.
-//@ compile-flags: -O -Zmir-opt-level=3
-//@ needs-asm-support
-//@ ignore-wasm32
-#![crate_type = "lib"]
-#![feature(naked_functions)]
-
-use std::arch::naked_asm;
-
-#[naked]
-#[no_mangle]
-pub unsafe extern "C" fn f() {
-    // Check that f has naked and noinline attributes.
-    //
-    // CHECK:       define {{(dso_local )?}}void @f() unnamed_addr [[ATTR:#[0-9]+]]
-    // CHECK-NEXT:  start:
-    // CHECK-NEXT:    call void asm
-    naked_asm!("");
-}
-
-#[no_mangle]
-pub unsafe fn g() {
-    // Check that call to f is not inlined.
-    //
-    // CHECK-LABEL: define {{(dso_local )?}}void @g()
-    // CHECK-NEXT:  start:
-    // CHECK-NEXT:    call void @f()
-    f();
-}
-
-// CHECK: attributes [[ATTR]] = { naked{{.*}}noinline{{.*}} }
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/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/124375.rs b/tests/crashes/124375.rs
deleted file mode 100644
index 1d877caeb8b..00000000000
--- a/tests/crashes/124375.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: #124375
-//@ compile-flags: -Zmir-opt-level=0
-//@ only-x86_64
-#![crate_type = "lib"]
-#![feature(naked_functions)]
-use std::arch::naked_asm;
-
-#[naked]
-pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
-    naked_asm!("lea rax, [rdi + rsi]", "ret");
-}
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/crashes/130797.rs b/tests/crashes/130797.rs
new file mode 100644
index 00000000000..e9c877d92a6
--- /dev/null
+++ b/tests/crashes/130797.rs
@@ -0,0 +1,23 @@
+//@ known-bug: #130797
+
+trait Transform {
+    type Output<'a>;
+}
+trait Propagate<O> {}
+trait AddChild<C> {
+    fn add_child(&self) {}
+}
+
+pub struct Node<T>(T);
+impl<T> AddChild<Box<dyn for<'b> Propagate<T::Output<'b>>>> for Node<T> where T: Transform {}
+
+fn make_graph_root() {
+    Node(Dummy).add_child()
+}
+
+struct Dummy;
+impl Transform for Dummy {
+    type Output<'a> = ();
+}
+
+pub fn main() {}
diff --git a/tests/crashes/132103.rs b/tests/crashes/132103.rs
new file mode 100644
index 00000000000..5bf4792c44c
--- /dev/null
+++ b/tests/crashes/132103.rs
@@ -0,0 +1,21 @@
+//@ known-bug: #132103
+//@compile-flags: -Zvalidate-mir --edition=2018 -Zinline-mir=yes
+use core::future::{async_drop_in_place, Future};
+use core::mem::{self};
+use core::pin::pin;
+use core::task::{Context, Waker};
+
+async fn test_async_drop<T>(x: T) {
+    let mut x = mem::MaybeUninit::new(x);
+    pin!(unsafe { async_drop_in_place(x.as_mut_ptr()) });
+}
+
+fn main() {
+    let waker = Waker::noop();
+    let mut cx = Context::from_waker(&waker);
+
+    let fut = pin!(async {
+        test_async_drop(test_async_drop(0)).await;
+    });
+    fut.poll(&mut cx);
+}
diff --git a/tests/crashes/132765.rs b/tests/crashes/132765.rs
new file mode 100644
index 00000000000..01e8fdaacff
--- /dev/null
+++ b/tests/crashes/132765.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #132765
+
+trait LendingIterator {
+    type Item<'q>;
+    fn for_each(&self, _f: Box<fn(Self::Item<'_>)>) {}
+}
+
+fn f(_: ()) {}
+
+fn main() {
+    LendingIterator::for_each(&(), f);
+}
diff --git a/tests/crashes/132766.rs b/tests/crashes/132766.rs
new file mode 100644
index 00000000000..5f5117d77a5
--- /dev/null
+++ b/tests/crashes/132766.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #132766
+
+trait Trait {}
+impl<'a> Trait for () {
+    fn pass2<'a>() -> impl Trait2 {}
+}
+
+trait Trait2 {}
+impl Trait2 for () {}
diff --git a/tests/crashes/132882.rs b/tests/crashes/132882.rs
new file mode 100644
index 00000000000..6b5e4dba803
--- /dev/null
+++ b/tests/crashes/132882.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #132882
+
+use std::ops::Add;
+
+pub trait Numoid
+where
+    for<N: Numoid> &'a Self: Add<Self>,
+{
+}
+
+pub fn compute<N: Numoid>(a: N) -> N {
+    &a + a
+}
diff --git a/tests/crashes/132960.rs b/tests/crashes/132960.rs
new file mode 100644
index 00000000000..87d0ee7dede
--- /dev/null
+++ b/tests/crashes/132960.rs
@@ -0,0 +1,36 @@
+//@ known-bug: #132960
+
+#![feature(adt_const_params, const_ptr_read, generic_const_exprs)]
+
+const fn concat_strs<const A: &'static str, const B: &'static str>() -> &'static str
+where
+    [(); A.len()]:,
+    [(); B.len()]:,
+    [(); A.len() + B.len()]:,
+{
+    #[repr(C)]
+    #[repr(C)]
+
+    const fn concat_arr<const M: usize, const N: usize>(a: [u8; M], b: [u8; N]) -> [u8; M + N] {}
+
+    struct Inner<const A: &'static str, const B: &'static str>;
+    impl<const A: &'static str, const B: &'static str> Inner<A, B>
+    where
+        [(); A.len()]:,
+        [(); B.len()]:,
+        [(); A.len() + B.len()]:,
+    {
+        const ABSTR: &'static str = unsafe {
+            std::str::from_utf8_unchecked(&concat_arr(
+                A.as_ptr().cast().read(),
+                B.as_ptr().cast().read(),
+            ))
+        };
+    }
+
+    Inner::<A, B>::ABSTR
+}
+
+const FOO: &str = "foo";
+const BAR: &str = "bar";
+const FOOBAR: &str = concat_strs::<FOO, BAR>();
diff --git a/tests/crashes/132981.rs b/tests/crashes/132981.rs
new file mode 100644
index 00000000000..8ff4fa36fd0
--- /dev/null
+++ b/tests/crashes/132981.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #132981
+//@compile-flags: -Clink-dead-code=true --crate-type lib
+//@ only-x86_64
+//@ ignore-windows
+
+#![feature(rust_cold_cc)]
+pub extern "rust-cold" fn foo(_: [usize; 3]) {}
diff --git a/tests/crashes/133063.rs b/tests/crashes/133063.rs
new file mode 100644
index 00000000000..132b5486170
--- /dev/null
+++ b/tests/crashes/133063.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #133063
+
+fn foo(x: !) {
+    match x {
+        (! | !) if false => {}
+        _ => {}
+    }
+}
diff --git a/tests/crashes/133066.rs b/tests/crashes/133066.rs
new file mode 100644
index 00000000000..732ebb7079f
--- /dev/null
+++ b/tests/crashes/133066.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #133066
+trait Owner {
+    const C<const N: u32>: u32;
+}
+
+impl Owner for () {;}
+
+fn take0<const N: u64>(_: impl Owner<C<N> = { N }>) {}
+
+fn main() {
+    take0::<f32, >(());
+}
diff --git a/tests/crashes/133117.rs b/tests/crashes/133117.rs
new file mode 100644
index 00000000000..751c82626d5
--- /dev/null
+++ b/tests/crashes/133117.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #133117
+
+fn main() {
+    match () {
+        (!|!) if true => {}
+        (!|!) if true => {}
+    }
+}
diff --git a/tests/crashes/133199.rs b/tests/crashes/133199.rs
new file mode 100644
index 00000000000..76535fa83a6
--- /dev/null
+++ b/tests/crashes/133199.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #133199
+//@ aux-build: aux133199.rs
+
+extern crate aux133199;
+
+use aux133199::FixedBitSet;
+
+fn main() {
+    FixedBitSet::<7>::new();
+    //~^ ERROR
+}
diff --git a/tests/crashes/133252.rs b/tests/crashes/133252.rs
new file mode 100644
index 00000000000..3cecf448287
--- /dev/null
+++ b/tests/crashes/133252.rs
@@ -0,0 +1,43 @@
+//@ known-bug: #133252
+//@ edition:2021
+use std::future::Future;
+
+trait Owned: 'static {}
+fn ice() -> impl Future<Output = &'static dyn Owned> {
+    async {
+        let not_static = 0;
+        force_send(async_load(&not_static));
+        loop {}
+    }
+}
+
+fn force_send<T: Send>(_: T) {}
+
+fn async_load<'a, T: LoadQuery<'a>>(this: T) -> impl Future {
+    async {
+        this.get_future().await;
+    }
+}
+
+trait LoadQuery<'a>: Sized {
+    type LoadFuture: Future;
+
+    fn get_future(self) -> Self::LoadFuture {
+        loop {}
+    }
+}
+
+impl<'a> LoadQuery<'a> for &'a u8 {
+    type LoadFuture = SimpleFuture;
+}
+
+struct SimpleFuture;
+impl Future for SimpleFuture {
+    type Output = ();
+    fn poll(
+        self: std::pin::Pin<&mut Self>,
+        _: &mut std::task::Context<'_>,
+    ) -> std::task::Poll<Self::Output> {
+        loop {}
+    }
+}
diff --git a/tests/crashes/133275-1.rs b/tests/crashes/133275-1.rs
new file mode 100644
index 00000000000..73c04f5d6e4
--- /dev/null
+++ b/tests/crashes/133275-1.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #133275
+#![feature(const_trait_impl)]
+#![feature(associated_type_defaults)]
+
+#[const_trait]
+trait Foo3<T>
+where
+    Self::Baz: Clone,
+{
+    type Baz = T;
+}
+
+pub fn main() {}
diff --git a/tests/crashes/133275-2.rs b/tests/crashes/133275-2.rs
new file mode 100644
index 00000000000..a774b3cdb69
--- /dev/null
+++ b/tests/crashes/133275-2.rs
@@ -0,0 +1,15 @@
+//@ known-bug: #133275
+#![feature(const_trait_impl)]
+#[const_trait]
+pub trait Owo<X = <IntEnum as Uwu>::T> {}
+
+#[const_trait]
+trait Foo3<T>
+where
+    Self::Bar: Clone,
+    Self::Baz: Clone,
+{
+    type Bar = Vec<Self::Baz>;
+    type Baz = T;
+    //~^ ERROR the trait bound `T: Clone` is not satisfied
+}
diff --git a/tests/crashes/133426.rs b/tests/crashes/133426.rs
new file mode 100644
index 00000000000..307a94c0f6c
--- /dev/null
+++ b/tests/crashes/133426.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #133426
+
+fn a(
+    _: impl Iterator<
+        Item = [(); {
+                   match *todo!() { ! };
+               }],
+    >,
+) {
+}
+
+fn b(_: impl Iterator<Item = { match 0 { ! } }>) {}
diff --git a/tests/crashes/133597.rs b/tests/crashes/133597.rs
new file mode 100644
index 00000000000..f716d5e7bc7
--- /dev/null
+++ b/tests/crashes/133597.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #133597
+
+pub trait Foo2 {
+    fn boxed<'a: 'a>() -> impl Sized + FnOnce<()>;
+}
+
+impl Foo2 for () {}
+
+
+fn f() -> impl FnOnce<()> { || () }
+fn main() { () = f(); }
diff --git a/tests/crashes/133613.rs b/tests/crashes/133613.rs
new file mode 100644
index 00000000000..f01780d7cf4
--- /dev/null
+++ b/tests/crashes/133613.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #133613
+
+struct Wrapper<'a>();
+
+trait IntFactory {
+    fn stream(&self) -> impl IntFactory<stream(..): IntFactory<stream(..): Send>>;
+}
diff --git a/tests/crashes/133639.rs b/tests/crashes/133639.rs
new file mode 100644
index 00000000000..d522b0730cf
--- /dev/null
+++ b/tests/crashes/133639.rs
@@ -0,0 +1,33 @@
+//@ known-bug: #133639
+
+#![feature(with_negative_coherence)]
+#![feature(min_specialization)]
+#![feature(generic_const_exprs)]
+
+#![crate_type = "lib"]
+use std::str::FromStr;
+
+struct a<const b: bool>;
+
+trait c {}
+
+impl<const d: u32> FromStr for e<d>
+where
+    a<{ d <= 2 }>: c,
+{
+    type Err = ();
+    fn from_str(f: &str) -> Result<Self, Self::Err> {
+        unimplemented!()
+    }
+}
+struct e<const d: u32>;
+
+impl<const d: u32> FromStr for e<d>
+where
+    a<{ d <= 2 }>: c,
+{
+    type Err = ();
+    fn from_str(f: &str) -> Result<Self, Self::Err> {
+        unimplemented!()
+    }
+}
diff --git a/tests/crashes/133808.rs b/tests/crashes/133808.rs
new file mode 100644
index 00000000000..9c6a23d1e35
--- /dev/null
+++ b/tests/crashes/133808.rs
@@ -0,0 +1,15 @@
+//@ known-bug: #133808
+
+#![feature(generic_const_exprs, transmutability)]
+
+mod assert {
+    use std::mem::TransmuteFrom;
+
+    pub fn is_transmutable<Src, Dst>()
+    where
+        Dst: TransmuteFrom<Src>,
+    {
+    }
+}
+
+pub fn main() {}
diff --git a/tests/crashes/133868.rs b/tests/crashes/133868.rs
new file mode 100644
index 00000000000..dc25cb9df28
--- /dev/null
+++ b/tests/crashes/133868.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #133868
+
+trait Foo {
+    type Assoc;
+}
+
+trait Bar {
+    fn method() -> impl Sized;
+}
+impl<T> Bar for T where <T as Foo>::Assoc: Sized
+{
+    fn method() {}
+}
diff --git a/tests/crashes/133965.rs b/tests/crashes/133965.rs
new file mode 100644
index 00000000000..69f533ccbe9
--- /dev/null
+++ b/tests/crashes/133965.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #133965
+//@ needs-rustc-debug-assertions
+
+struct NonGeneric {}
+
+#[derive(Default)]
+struct NonGeneric<'a, const N: usize> {}
+
+pub fn main() {}
diff --git a/tests/crashes/133966.rs b/tests/crashes/133966.rs
new file mode 100644
index 00000000000..25a881ae99b
--- /dev/null
+++ b/tests/crashes/133966.rs
@@ -0,0 +1,3 @@
+//@ known-bug: #133966
+pub struct Data([[&'static str]; 5_i32]);
+const _: &'static Data = unsafe { &*(&[] as *const Data) };
diff --git a/tests/crashes/134005.rs b/tests/crashes/134005.rs
new file mode 100644
index 00000000000..c1f4c758a14
--- /dev/null
+++ b/tests/crashes/134005.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #134005
+
+fn main() {
+    let _ = [std::ops::Add::add, std::ops::Mul::mul, main as fn(_, &_)];
+}
diff --git a/tests/crashes/134061.rs b/tests/crashes/134061.rs
new file mode 100644
index 00000000000..e00eb7603fe
--- /dev/null
+++ b/tests/crashes/134061.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #134061
+//@ needs-rustc-debug-assertions
+
+const x: () = |&'a
diff --git a/tests/crashes/134174.rs b/tests/crashes/134174.rs
new file mode 100644
index 00000000000..899cdc6faf3
--- /dev/null
+++ b/tests/crashes/134174.rs
@@ -0,0 +1,17 @@
+//@ known-bug: #134175
+//@compile-flags: -Zvalidate-mir -Zinline-mir=yes
+use std::vec::IntoIter;
+
+pub(crate) trait Foo: Iterator<Item = <Self as Foo>::Key> {
+    type Key;
+}
+
+impl Foo for IntoIter<i16> {}
+
+fn sum_foo<F: Foo<Key = i32>>(f: F) -> i32 {
+    f.fold(0, |a, b| a + b)
+}
+
+fn main() {
+    let x = sum_foo(vec![11, 10, 1].into_iter());
+}
diff --git a/tests/crashes/134217.rs b/tests/crashes/134217.rs
new file mode 100644
index 00000000000..1b14c660e8b
--- /dev/null
+++ b/tests/crashes/134217.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #134217
+
+impl<A> std::ops::CoerceUnsized<A> for A {}
+
+fn main() {
+    if let _ = true
+        && true
+    {}
+}
diff --git a/tests/crashes/134334.rs b/tests/crashes/134334.rs
new file mode 100644
index 00000000000..d99df7bdc1e
--- /dev/null
+++ b/tests/crashes/134334.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #134334
+//@ only-x86_64
+
+#[repr(simd)]
+struct A();
+
+fn main() {
+    std::arch::asm!("{}", in(xmm_reg) A());
+}
diff --git a/tests/crashes/134335.rs b/tests/crashes/134335.rs
new file mode 100644
index 00000000000..bee6686ff3f
--- /dev/null
+++ b/tests/crashes/134335.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #134335
+//@compile-flags: -Zunstable-options --edition=2024 --crate-type=lib
+pub async fn async_closure(x: &mut i32) {
+    let c = async move || {
+        *x += 1;
+    };
+    call_once(c).await;
+}
+
+fn call_once<T>(f: impl FnOnce() -> T) -> T {
+    f()
+}
diff --git a/tests/crashes/auxiliary/aux133199.rs b/tests/crashes/auxiliary/aux133199.rs
new file mode 100644
index 00000000000..40765d92fbf
--- /dev/null
+++ b/tests/crashes/auxiliary/aux133199.rs
@@ -0,0 +1,13 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+pub struct FixedBitSet<const N: usize>;
+
+impl<const N: usize> FixedBitSet<N>
+where
+    [u8; N.div_ceil(8)]: Sized,
+{
+    pub fn new() -> Self {
+        todo!()
+    }
+}
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
index a467987e886..8d9176ef301 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
@@ -7,8 +7,7 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: usize;
-    let mut _9: bool;
+    let mut _8: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -41,9 +40,8 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _8 = Len(_1);
-        _9 = Lt(copy _7, copy _8);
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
+        _8 = Lt(copy _7, const 3_usize);
+        assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind unreachable];
     }
 
     bb2: {
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
index bd7365543bd..e1df0e3e2a3 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
@@ -7,8 +7,7 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: usize;
-    let mut _9: bool;
+    let mut _8: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -41,9 +40,8 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _8 = Len(_1);
-        _9 = Lt(copy _7, copy _8);
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
+        _8 = Lt(copy _7, const 3_usize);
+        assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind continue];
     }
 
     bb2: {
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/mir-opt/building/index_array_and_slice.index_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir
new file mode 100644
index 00000000000..d28a2031013
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir
@@ -0,0 +1,31 @@
+// MIR for `index_array` after built
+
+fn index_array(_1: &[i32; 7], _2: usize) -> &i32 {
+    debug array => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        FakeRead(ForIndex, (*_1));
+        _5 = Lt(copy _4, const 7_usize);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", const 7_usize, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir
new file mode 100644
index 00000000000..e9627532c38
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir
@@ -0,0 +1,31 @@
+// MIR for `index_const_generic_array` after built
+
+fn index_const_generic_array(_1: &[i32; N], _2: usize) -> &i32 {
+    debug array => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        FakeRead(ForIndex, (*_1));
+        _5 = Lt(copy _4, const N);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", const N, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir
new file mode 100644
index 00000000000..00f2b7e07d5
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir
@@ -0,0 +1,34 @@
+// MIR for `index_custom` after built
+
+fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 {
+    debug custom => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: *const [i32];
+    let mut _6: usize;
+    let mut _7: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        _5 = &raw const ((*_1).1: [i32]);
+        _6 = PtrMetadata(move _5);
+        _7 = Lt(copy _4, copy _6);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &((*_1).1: [i32])[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir
new file mode 100644
index 00000000000..cb0b2f600c8
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir
@@ -0,0 +1,34 @@
+// MIR for `index_mut_slice` after built
+
+fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 {
+    debug slice => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: *const [i32];
+    let mut _6: usize;
+    let mut _7: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        _5 = &raw const (*_1);
+        _6 = PtrMetadata(move _5);
+        _7 = Lt(copy _4, copy _6);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir
new file mode 100644
index 00000000000..0911df59049
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir
@@ -0,0 +1,32 @@
+// MIR for `index_slice` after built
+
+fn index_slice(_1: &[i32], _2: usize) -> &i32 {
+    debug slice => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: usize;
+    let mut _6: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        _5 = PtrMetadata(copy _1);
+        _6 = Lt(copy _4, copy _5);
+        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.rs b/tests/mir-opt/building/index_array_and_slice.rs
new file mode 100644
index 00000000000..16d0b983132
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.rs
@@ -0,0 +1,71 @@
+//@ compile-flags: -C opt-level=0
+
+// EMIT_MIR index_array_and_slice.index_array.built.after.mir
+fn index_array(array: &[i32; 7], index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[LT:_.+]] = Lt(copy _2, const 7_usize);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const 7_usize, copy _2) -> [success: bb1, unwind
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &array[index]
+}
+
+// EMIT_MIR index_array_and_slice.index_const_generic_array.built.after.mir
+fn index_const_generic_array<const N: usize>(array: &[i32; N], index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[LT:_.+]] = Lt(copy _2, const N);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const N, copy _2) -> [success: bb1, unwind
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &array[index]
+}
+
+// EMIT_MIR index_array_and_slice.index_slice.built.after.mir
+fn index_slice(slice: &[i32], index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
+    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &slice[index]
+}
+
+// EMIT_MIR index_array_and_slice.index_mut_slice.built.after.mir
+fn index_mut_slice(slice: &mut [i32], index: usize) -> &i32 {
+    // While the filecheck here is identical to the above test, the emitted MIR is different.
+    // This cannot `copy _1` in the *built* MIR, only in the *runtime* MIR.
+
+    // CHECK: bb0:
+    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
+    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &slice[index]
+}
+
+struct WithSliceTail(f64, [i32]);
+
+// EMIT_MIR index_array_and_slice.index_custom.built.after.mir
+fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[PTR:_.+]] = &raw const ((*_1).1: [i32]);
+    // CHECK: [[LEN:_.+]] = PtrMetadata(move [[PTR]]);
+    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
+
+    // CHECK: bb1:
+    // CHECK: _0 = &((*_1).1: [i32])[_2];
+    &custom.1[index]
+}
+
+fn main() {
+    index_array(&[1, 2, 3, 4, 5, 6, 7], 3);
+    index_slice(&[1, 2, 3, 4, 5, 6, 7][..], 3);
+    _ = index_custom;
+}
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
index e754af95ce3..3a5a8d00991 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
index e15a35c7fe9..62d6e6007e5 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
index e754af95ce3..3a5a8d00991 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
index e15a35c7fe9..62d6e6007e5 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
index 15d30140367..be42c4d60c8 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
@@ -30,19 +30,22 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
-          StorageLive(_6);
+-         StorageLive(_6);
++         nop;
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
+-         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-          StorageDead(_6);
++         nop;
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
index dd411d84f9f..b51d0c0845f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
@@ -30,19 +30,22 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
-          StorageLive(_6);
+-         StorageLive(_6);
++         nop;
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
+-         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-          StorageDead(_6);
++         nop;
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
index 15d30140367..be42c4d60c8 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
@@ -30,19 +30,22 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
-          StorageLive(_6);
+-         StorageLive(_6);
++         nop;
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
+-         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-          StorageDead(_6);
++         nop;
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
index dd411d84f9f..b51d0c0845f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
@@ -30,19 +30,22 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
-          StorageLive(_6);
+-         StorageLive(_6);
++         nop;
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
+-         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-          StorageDead(_6);
++         nop;
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
index 49ea51deed6..3569998b13f 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
index 103bfbcaf64..50b31c9ac13 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
index 49ea51deed6..3569998b13f 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
index 103bfbcaf64..50b31c9ac13 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
index f7c1c2da01f..a41668b6fa3 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
index 436773c8556..2313084b49e 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
index f7c1c2da01f..a41668b6fa3 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
index 436773c8556..2313084b49e 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
index 8a8ea5b7e20..0798b303929 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
index f0c844884f6..c0b3d4d3219 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
index 8a8ea5b7e20..0798b303929 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
index f0c844884f6..c0b3d4d3219 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
index 6d967257df1..689083dfc1d 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
@@ -18,8 +18,7 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: usize;
-      let mut _20: bool;
+      let mut _19: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -92,11 +91,10 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
-          _19 = Len(_2);
--         _20 = Lt(copy _18, copy _19);
--         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind unreachable];
-+         _20 = Lt(copy _16, copy _19);
-+         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind unreachable];
+-         _19 = Lt(copy _18, const 4_usize);
+-         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind unreachable];
++         _19 = Lt(copy _16, const 4_usize);
++         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind unreachable];
       }
   
       bb7: {
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
index 3580c87c469..7f768a9f834 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
@@ -18,8 +18,7 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: usize;
-      let mut _20: bool;
+      let mut _19: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -92,11 +91,10 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
-          _19 = Len(_2);
--         _20 = Lt(copy _18, copy _19);
--         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind continue];
-+         _20 = Lt(copy _16, copy _19);
-+         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind continue];
+-         _19 = Lt(copy _18, const 4_usize);
+-         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind continue];
++         _19 = Lt(copy _16, const 4_usize);
++         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind continue];
       }
   
       bb7: {
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
index a46daef435f..0275d7e8a0d 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
index 1a4e15b45fa..490ed4b55a1 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
index a46daef435f..0275d7e8a0d 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
index 1a4e15b45fa..490ed4b55a1 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs
index e442ef99f79..1aa8dcd28f4 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.rs
+++ b/tests/mir-opt/dataflow-const-prop/array_index.rs
@@ -11,9 +11,10 @@ fn main() {
 
     // CHECK:       [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
     // CHECK-NOT:   {{_.*}} = Len(
+    // CHECK-NOT:   {{_.*}} = PtrMetadata(
     // CHECK-NOT:   {{_.*}} = Lt(
     // CHECK-NOT:   assert(move _
-    // CHECK:       {{_.*}} = const 4_usize;
+    // CHECK:       {{_.*}} = const 2_usize;
     // CHECK:       {{_.*}} = const true;
     // CHECK:       assert(const true
     // CHECK:       [[x]] = copy [[array_lit]][2 of 3];
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
index b7ff0b671f7..f0d59ef5923 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
index af6e3626142..959c3e75214 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
index b7ff0b671f7..f0d59ef5923 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
index af6e3626142..959c3e75214 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs
index e9f2fa2badf..e490cfde247 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs
@@ -10,7 +10,7 @@ fn main() {
 
     // CHECK: debug x => [[x:_.*]];
     // CHECK: [[array_lit:_.*]] = [const 0_u8; 5000];
-    // CHECK: {{_.*}} = const 5000_usize;
+    // CHECK: {{_.*}} = const 2_usize;
     // CHECK: {{_.*}} = const true;
     // CHECK: assert(const true
     // CHECK: [[x]] = copy [[array_lit]][2 of 3];
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
index dfa541b1200..618121ea632 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
index 9ede3c5f7ac..1788f58432b 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
index dfa541b1200..618121ea632 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
index 9ede3c5f7ac..1788f58432b 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs
index 2067aa3d709..1bc2cb82a60 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.rs
+++ b/tests/mir-opt/dataflow-const-prop/repeat.rs
@@ -9,8 +9,9 @@ fn main() {
 
     // CHECK: [[array_lit:_.*]] = [const 42_u32; 8];
     // CHECK-NOT: {{_.*}} = Len(
+    // CHECK-NOT: {{_.*}} = PtrMetadata(
     // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK: {{_.*}} = const 8_usize;
+    // CHECK: {{_.*}} = const 2_usize;
     // CHECK: {{_.*}} = const true;
     // CHECK: assert(const true
 
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff
deleted file mode 100644
index e71992316dc..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff
deleted file mode 100644
index 26de8595768..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff
deleted file mode 100644
index e71992316dc..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff
deleted file mode 100644
index 26de8595768..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs
deleted file mode 100644
index e0e68f9fde5..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
-//@ test-mir-pass: DataflowConstProp
-//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
-
-// EMIT_MIR slice_len.main.DataflowConstProp.diff
-
-// CHECK-LABEL: fn main(
-fn main() {
-    // CHECK: debug local => [[local:_.*]];
-    // CHECK: debug constant => [[constant:_.*]];
-
-    // CHECK-NOT: {{_.*}} = Len(
-    // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK-NOT: assert(move _
-    // CHECK: {{_.*}} = const 3_usize;
-    // CHECK: {{_.*}} = const true;
-    // CHECK: assert(const true,
-
-    // CHECK: [[local]] = copy (*{{_.*}})[1 of 2];
-    let local = (&[1u32, 2, 3] as &[u32])[1];
-
-    // CHECK-NOT: {{_.*}} = Len(
-    // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK-NOT: assert(move _
-    const SLICE: &[u32] = &[1, 2, 3];
-    // CHECK: {{_.*}} = const 3_usize;
-    // CHECK: {{_.*}} = const true;
-    // CHECK: assert(const true,
-
-    // CHECK-NOT: [[constant]] = {{copy|move}} (*{{_.*}})[_
-    // CHECK: [[constant]] = copy (*{{_.*}})[1 of 2];
-    let constant = SLICE[1];
-}
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
index 3f052ee19fd..183b4d2599f 100644
--- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
@@ -53,7 +53,7 @@
           StorageLive(_8);
 -         _8 = copy _2;
 +         _8 = const usize::MAX;
-          _9 = Len((*_1));
+          _9 = PtrMetadata(copy _1);
 -         _10 = Lt(copy _8, copy _9);
 -         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = Len((*_1));
+          _12 = PtrMetadata(copy _1);
 -         _13 = Lt(copy _11, copy _12);
 -         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
 +         _13 = Lt(const 0_usize, copy _12);
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
index 84b738c7804..03e8aa3bd9b 100644
--- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
@@ -53,7 +53,7 @@
           StorageLive(_8);
 -         _8 = copy _2;
 +         _8 = const usize::MAX;
-          _9 = Len((*_1));
+          _9 = PtrMetadata(copy _1);
 -         _10 = Lt(copy _8, copy _9);
 -         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = Len((*_1));
+          _12 = PtrMetadata(copy _1);
 -         _13 = Lt(copy _11, copy _12);
 -         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
 +         _13 = Lt(const 0_usize, copy _12);
diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff
new file mode 100644
index 00000000000..4b077f580f1
--- /dev/null
+++ b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff
@@ -0,0 +1,72 @@
+- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
++ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
+  
+  fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
+      debug x => _1;
+      let mut _0: [i32; 3];
+      let mut _2: i32;
+      let _3: usize;
+      let mut _4: usize;
+      let mut _5: bool;
+      let mut _6: i32;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let mut _10: i32;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 42_usize;
+          _4 = PtrMetadata(copy _1);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _5 = Lt(const 42_usize, copy _4);
++         assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+-         _2 = copy (*_1)[_3];
++         _2 = copy (*_1)[42 of 43];
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 13_usize;
+-         _8 = PtrMetadata(copy _1);
+-         _9 = Lt(copy _7, copy _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
++         _8 = copy _4;
++         _9 = Lt(const 13_usize, copy _4);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         _6 = copy (*_1)[_7];
++         _6 = copy (*_1)[13 of 14];
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = const 7_usize;
+-         _12 = PtrMetadata(copy _1);
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind unreachable];
++         _12 = copy _4;
++         _13 = Lt(const 7_usize, copy _4);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+-         _10 = copy (*_1)[_11];
++         _10 = copy (*_1)[7 of 8];
+          _0 = [move _2, move _6, move _10];
+          StorageDead(_10);
+          StorageDead(_6);
+          StorageDead(_2);
+          StorageDead(_11);
+          StorageDead(_7);
+          StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..87e69d44006
--- /dev/null
+++ b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff
@@ -0,0 +1,72 @@
+- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
++ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
+  
+  fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
+      debug x => _1;
+      let mut _0: [i32; 3];
+      let mut _2: i32;
+      let _3: usize;
+      let mut _4: usize;
+      let mut _5: bool;
+      let mut _6: i32;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let mut _10: i32;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 42_usize;
+          _4 = PtrMetadata(copy _1);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _5 = Lt(const 42_usize, copy _4);
++         assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+-         _2 = copy (*_1)[_3];
++         _2 = copy (*_1)[42 of 43];
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 13_usize;
+-         _8 = PtrMetadata(copy _1);
+-         _9 = Lt(copy _7, copy _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
++         _8 = copy _4;
++         _9 = Lt(const 13_usize, copy _4);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind continue];
+      }
+  
+      bb2: {
+-         _6 = copy (*_1)[_7];
++         _6 = copy (*_1)[13 of 14];
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = const 7_usize;
+-         _12 = PtrMetadata(copy _1);
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind continue];
++         _12 = copy _4;
++         _13 = Lt(const 7_usize, copy _4);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind continue];
+      }
+  
+      bb3: {
+-         _10 = copy (*_1)[_11];
++         _10 = copy (*_1)[7 of 8];
+          _0 = [move _2, move _6, move _10];
+          StorageDead(_10);
+          StorageDead(_6);
+          StorageDead(_2);
+          StorageDead(_11);
+          StorageDead(_7);
+          StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
index d4b22d05f6c..7f44176b756 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
@@ -10,13 +10,11 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let _10: ();
-      let mut _11: T;
-      let _12: usize;
-      let mut _13: usize;
-      let mut _14: bool;
+      let mut _8: bool;
+      let _9: ();
+      let mut _10: T;
+      let _11: usize;
+      let mut _12: bool;
       scope 1 {
           debug a => _3;
       }
@@ -32,12 +30,10 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _8 = Len(_3);
--         _9 = Lt(copy _7, copy _8);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind unreachable];
-+         _8 = const N;
-+         _9 = Lt(const 0_usize, const N);
-+         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
+-         _8 = Lt(copy _7, const N);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 0_usize, const N);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
@@ -51,29 +47,27 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
+          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          StorageLive(_12);
-          _12 = copy _2;
--         _13 = Len(_3);
--         _14 = Lt(copy _12, copy _13);
--         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind unreachable];
-+         _13 = const N;
-+         _14 = Lt(copy _2, const N);
-+         assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
+          _11 = copy _2;
+-         _12 = Lt(copy _11, const N);
+-         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind unreachable];
++         _12 = Lt(copy _2, const N);
++         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
       }
   
       bb3: {
--         _11 = copy _3[_12];
--         _10 = opaque::<T>(move _11) -> [return: bb4, unwind unreachable];
-+         _11 = copy _1;
-+         _10 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
+-         _10 = copy _3[_11];
+-         _9 = opaque::<T>(move _10) -> [return: bb4, unwind unreachable];
++         _10 = copy _1;
++         _9 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_11);
-          StorageDead(_12);
           StorageDead(_10);
+          StorageDead(_11);
+          StorageDead(_9);
           _0 = const ();
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
index 708c0f92e54..d34882d725f 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
@@ -10,13 +10,11 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let _10: ();
-      let mut _11: T;
-      let _12: usize;
-      let mut _13: usize;
-      let mut _14: bool;
+      let mut _8: bool;
+      let _9: ();
+      let mut _10: T;
+      let _11: usize;
+      let mut _12: bool;
       scope 1 {
           debug a => _3;
       }
@@ -32,12 +30,10 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _8 = Len(_3);
--         _9 = Lt(copy _7, copy _8);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind continue];
-+         _8 = const N;
-+         _9 = Lt(const 0_usize, const N);
-+         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
+-         _8 = Lt(copy _7, const N);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind continue];
++         _8 = Lt(const 0_usize, const N);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -51,29 +47,27 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
+          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          StorageLive(_12);
-          _12 = copy _2;
--         _13 = Len(_3);
--         _14 = Lt(copy _12, copy _13);
--         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind continue];
-+         _13 = const N;
-+         _14 = Lt(copy _2, const N);
-+         assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
+          _11 = copy _2;
+-         _12 = Lt(copy _11, const N);
+-         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind continue];
++         _12 = Lt(copy _2, const N);
++         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
       }
   
       bb3: {
--         _11 = copy _3[_12];
--         _10 = opaque::<T>(move _11) -> [return: bb4, unwind continue];
-+         _11 = copy _1;
-+         _10 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
+-         _10 = copy _3[_11];
+-         _9 = opaque::<T>(move _10) -> [return: bb4, unwind continue];
++         _10 = copy _1;
++         _9 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
       }
   
       bb4: {
-          StorageDead(_11);
-          StorageDead(_12);
           StorageDead(_10);
+          StorageDead(_11);
+          StorageDead(_9);
           _0 = const ();
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index 97513248e23..19b58a917f8 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -835,6 +835,25 @@ fn array_len(x: &mut [i32; 42]) -> usize {
     std::intrinsics::ptr_metadata(x)
 }
 
+// Check that we only load the length once, rather than all 3 times.
+fn dedup_multiple_bounds_checks_lengths(x: &[i32]) -> [i32; 3] {
+    // CHECK-LABEL: fn dedup_multiple_bounds_checks_lengths
+    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
+    // CHECK: Lt(const 42_usize, copy [[LEN]]);
+    // CHECK: assert{{.+}}copy [[LEN]]
+    // CHECK: [[A:_.+]] = copy (*_1)[42 of 43];
+    // CHECK-NOT: PtrMetadata
+    // CHECK: Lt(const 13_usize, copy [[LEN]]);
+    // CHECK: assert{{.+}}copy [[LEN]]
+    // CHECK: [[B:_.+]] = copy (*_1)[13 of 14];
+    // CHECK-NOT: PtrMetadata
+    // CHECK: Lt(const 7_usize, copy [[LEN]]);
+    // CHECK: assert{{.+}}copy [[LEN]]
+    // CHECK: [[C:_.+]] = copy (*_1)[7 of 8];
+    // CHECK: _0 = [move [[A]], move [[B]], move [[C]]]
+    [x[42], x[13], x[7]]
+}
+
 #[custom_mir(dialect = "runtime")]
 fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, pb: *const B) {
     // CHECK-LABEL: fn generic_cast_metadata
@@ -1012,6 +1031,7 @@ fn identity<T>(x: T) -> T {
 // EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff
 // EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
 // EMIT_MIR gvn.array_len.GVN.diff
+// EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff
 // EMIT_MIR gvn.generic_cast_metadata.GVN.diff
 // EMIT_MIR gvn.cast_pointer_eq.GVN.diff
 // EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff
diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
index 6b6152c1117..1b305e746f5 100644
--- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
@@ -10,62 +10,60 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let mut _12: *const dyn std::marker::Send;
-      let _13: &dyn std::marker::Send;
-      let mut _14: &i32;
-      let _15: &i32;
-      let _16: usize;
-      let mut _17: usize;
+      let mut _9: bool;
+      let mut _11: *const dyn std::marker::Send;
+      let _12: &dyn std::marker::Send;
+      let mut _13: &i32;
+      let _14: &i32;
+      let _15: usize;
+      let mut _16: bool;
+      let _17: ();
       let mut _18: bool;
-      let _19: ();
-      let mut _20: bool;
+      let mut _19: *const dyn std::marker::Send;
+      let mut _20: *const dyn std::marker::Send;
       let mut _21: *const dyn std::marker::Send;
-      let mut _22: *const dyn std::marker::Send;
-      let mut _23: *const dyn std::marker::Send;
-      let _24: ();
-      let mut _25: bool;
+      let _22: ();
+      let mut _23: bool;
+      let mut _24: *const dyn std::marker::Send;
+      let mut _25: *const dyn std::marker::Send;
       let mut _26: *const dyn std::marker::Send;
-      let mut _27: *const dyn std::marker::Send;
-      let mut _28: *const dyn std::marker::Send;
-      let _29: ();
-      let mut _30: bool;
+      let _27: ();
+      let mut _28: bool;
+      let mut _29: *const dyn std::marker::Send;
+      let mut _30: *const dyn std::marker::Send;
       let mut _31: *const dyn std::marker::Send;
-      let mut _32: *const dyn std::marker::Send;
-      let mut _33: *const dyn std::marker::Send;
-      let _34: ();
-      let mut _35: bool;
+      let _32: ();
+      let mut _33: bool;
+      let mut _34: *const dyn std::marker::Send;
+      let mut _35: *const dyn std::marker::Send;
       let mut _36: *const dyn std::marker::Send;
-      let mut _37: *const dyn std::marker::Send;
-      let mut _38: *const dyn std::marker::Send;
-      let _39: ();
-      let mut _40: bool;
+      let _37: ();
+      let mut _38: bool;
+      let mut _39: *const dyn std::marker::Send;
+      let mut _40: *const dyn std::marker::Send;
       let mut _41: *const dyn std::marker::Send;
-      let mut _42: *const dyn std::marker::Send;
-      let mut _43: *const dyn std::marker::Send;
-      let _44: ();
-      let mut _45: bool;
+      let _42: ();
+      let mut _43: bool;
+      let mut _44: *const dyn std::marker::Send;
+      let mut _45: *const dyn std::marker::Send;
       let mut _46: *const dyn std::marker::Send;
-      let mut _47: *const dyn std::marker::Send;
-      let mut _48: *const dyn std::marker::Send;
-      let mut _49: &[i32; 2];
+      let mut _47: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _11: *const dyn std::marker::Send;
+              let _10: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _11;
+                  debug b => _10;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _49 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_49);
+          _47 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_47);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -74,11 +72,9 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _9 = Len((*_1));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind unreachable];
-+         _9 = const 2_usize;
-+         _10 = const true;
+-         _9 = Lt(copy _8, const 2_usize);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind unreachable];
++         _9 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind unreachable];
       }
   
@@ -95,170 +91,168 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_11);
--         StorageLive(_12);
+          StorageLive(_10);
+-         StorageLive(_11);
 +         nop;
+          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          StorageLive(_16);
-          _16 = const 1_usize;
--         _17 = Len((*_1));
--         _18 = Lt(copy _16, copy _17);
--         assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind unreachable];
-+         _17 = const 2_usize;
-+         _18 = const true;
+          _15 = const 1_usize;
+-         _16 = Lt(copy _15, const 2_usize);
+-         assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind unreachable];
++         _16 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
--         _15 = &(*_1)[_16];
-+         _15 = &(*_1)[1 of 2];
-          _14 = &(*_15);
-          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
-          StorageDead(_14);
-          _12 = &raw const (*_13);
--         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
--         StorageDead(_12);
-+         _11 = copy _12;
-+         nop;
-          StorageDead(_15);
+-         _14 = &(*_1)[_15];
++         _14 = &(*_1)[1 of 2];
+          _13 = &(*_14);
+          _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_13);
+          _11 = &raw const (*_12);
+-         _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_11);
++         _10 = copy _11;
++         nop;
+          StorageDead(_14);
+          StorageDead(_12);
+          StorageLive(_17);
+          StorageLive(_18);
           StorageLive(_19);
+-         _19 = copy _3;
++         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _3;
-+         _21 = copy _4;
-          StorageLive(_22);
-          StorageLive(_23);
--         _23 = copy _11;
--         _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _23 = copy _12;
-+         _22 = copy _12;
-          StorageDead(_23);
--         _20 = Eq(move _21, move _22);
-+         _20 = Eq(copy _4, copy _12);
-          StorageDead(_22);
+-         _21 = copy _10;
+-         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _21 = copy _11;
++         _20 = copy _11;
           StorageDead(_21);
-          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind unreachable];
+-         _18 = Eq(move _19, move _20);
++         _18 = Eq(copy _4, copy _11);
+          StorageDead(_20);
+          StorageDead(_19);
+          _17 = opaque::<bool>(move _18) -> [return: bb3, unwind unreachable];
       }
   
       bb3: {
-          StorageDead(_20);
-          StorageDead(_19);
+          StorageDead(_18);
+          StorageDead(_17);
+          StorageLive(_22);
+          StorageLive(_23);
           StorageLive(_24);
+-         _24 = copy _3;
++         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _3;
-+         _26 = copy _4;
-          StorageLive(_27);
-          StorageLive(_28);
--         _28 = copy _11;
--         _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _28 = copy _12;
-+         _27 = copy _12;
-          StorageDead(_28);
--         _25 = Ne(move _26, move _27);
-+         _25 = Ne(copy _4, copy _12);
-          StorageDead(_27);
+-         _26 = copy _10;
+-         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _26 = copy _11;
++         _25 = copy _11;
           StorageDead(_26);
-          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind unreachable];
+-         _23 = Ne(move _24, move _25);
++         _23 = Ne(copy _4, copy _11);
+          StorageDead(_25);
+          StorageDead(_24);
+          _22 = opaque::<bool>(move _23) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_25);
-          StorageDead(_24);
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_27);
+          StorageLive(_28);
           StorageLive(_29);
+-         _29 = copy _3;
++         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _3;
-+         _31 = copy _4;
-          StorageLive(_32);
-          StorageLive(_33);
--         _33 = copy _11;
--         _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _33 = copy _12;
-+         _32 = copy _12;
-          StorageDead(_33);
--         _30 = Lt(move _31, move _32);
-+         _30 = Lt(copy _4, copy _12);
-          StorageDead(_32);
+-         _31 = copy _10;
+-         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _31 = copy _11;
++         _30 = copy _11;
           StorageDead(_31);
-          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind unreachable];
+-         _28 = Lt(move _29, move _30);
++         _28 = Lt(copy _4, copy _11);
+          StorageDead(_30);
+          StorageDead(_29);
+          _27 = opaque::<bool>(move _28) -> [return: bb5, unwind unreachable];
       }
   
       bb5: {
-          StorageDead(_30);
-          StorageDead(_29);
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_32);
+          StorageLive(_33);
           StorageLive(_34);
+-         _34 = copy _3;
++         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _3;
-+         _36 = copy _4;
-          StorageLive(_37);
-          StorageLive(_38);
--         _38 = copy _11;
--         _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _38 = copy _12;
-+         _37 = copy _12;
-          StorageDead(_38);
--         _35 = Le(move _36, move _37);
-+         _35 = Le(copy _4, copy _12);
-          StorageDead(_37);
+-         _36 = copy _10;
+-         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _36 = copy _11;
++         _35 = copy _11;
           StorageDead(_36);
-          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind unreachable];
+-         _33 = Le(move _34, move _35);
++         _33 = Le(copy _4, copy _11);
+          StorageDead(_35);
+          StorageDead(_34);
+          _32 = opaque::<bool>(move _33) -> [return: bb6, unwind unreachable];
       }
   
       bb6: {
-          StorageDead(_35);
-          StorageDead(_34);
+          StorageDead(_33);
+          StorageDead(_32);
+          StorageLive(_37);
+          StorageLive(_38);
           StorageLive(_39);
+-         _39 = copy _3;
++         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _3;
-+         _41 = copy _4;
-          StorageLive(_42);
-          StorageLive(_43);
--         _43 = copy _11;
--         _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _43 = copy _12;
-+         _42 = copy _12;
-          StorageDead(_43);
--         _40 = Gt(move _41, move _42);
-+         _40 = Gt(copy _4, copy _12);
-          StorageDead(_42);
+-         _41 = copy _10;
+-         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _41 = copy _11;
++         _40 = copy _11;
           StorageDead(_41);
-          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind unreachable];
+-         _38 = Gt(move _39, move _40);
++         _38 = Gt(copy _4, copy _11);
+          StorageDead(_40);
+          StorageDead(_39);
+          _37 = opaque::<bool>(move _38) -> [return: bb7, unwind unreachable];
       }
   
       bb7: {
-          StorageDead(_40);
-          StorageDead(_39);
+          StorageDead(_38);
+          StorageDead(_37);
+          StorageLive(_42);
+          StorageLive(_43);
           StorageLive(_44);
+-         _44 = copy _3;
++         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _3;
-+         _46 = copy _4;
-          StorageLive(_47);
-          StorageLive(_48);
--         _48 = copy _11;
--         _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _48 = copy _12;
-+         _47 = copy _12;
-          StorageDead(_48);
--         _45 = Ge(move _46, move _47);
-+         _45 = Ge(copy _4, copy _12);
-          StorageDead(_47);
+-         _46 = copy _10;
+-         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _46 = copy _11;
++         _45 = copy _11;
           StorageDead(_46);
-          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind unreachable];
+-         _43 = Ge(move _44, move _45);
++         _43 = Ge(copy _4, copy _11);
+          StorageDead(_45);
+          StorageDead(_44);
+          _42 = opaque::<bool>(move _43) -> [return: bb8, unwind unreachable];
       }
   
       bb8: {
-          StorageDead(_45);
-          StorageDead(_44);
+          StorageDead(_43);
+          StorageDead(_42);
           _0 = const ();
-          StorageDead(_16);
-          StorageDead(_11);
+          StorageDead(_15);
+          StorageDead(_10);
           StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
index 093c1ec6ce3..e418ecf25bd 100644
--- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
@@ -10,62 +10,60 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let mut _12: *const dyn std::marker::Send;
-      let _13: &dyn std::marker::Send;
-      let mut _14: &i32;
-      let _15: &i32;
-      let _16: usize;
-      let mut _17: usize;
+      let mut _9: bool;
+      let mut _11: *const dyn std::marker::Send;
+      let _12: &dyn std::marker::Send;
+      let mut _13: &i32;
+      let _14: &i32;
+      let _15: usize;
+      let mut _16: bool;
+      let _17: ();
       let mut _18: bool;
-      let _19: ();
-      let mut _20: bool;
+      let mut _19: *const dyn std::marker::Send;
+      let mut _20: *const dyn std::marker::Send;
       let mut _21: *const dyn std::marker::Send;
-      let mut _22: *const dyn std::marker::Send;
-      let mut _23: *const dyn std::marker::Send;
-      let _24: ();
-      let mut _25: bool;
+      let _22: ();
+      let mut _23: bool;
+      let mut _24: *const dyn std::marker::Send;
+      let mut _25: *const dyn std::marker::Send;
       let mut _26: *const dyn std::marker::Send;
-      let mut _27: *const dyn std::marker::Send;
-      let mut _28: *const dyn std::marker::Send;
-      let _29: ();
-      let mut _30: bool;
+      let _27: ();
+      let mut _28: bool;
+      let mut _29: *const dyn std::marker::Send;
+      let mut _30: *const dyn std::marker::Send;
       let mut _31: *const dyn std::marker::Send;
-      let mut _32: *const dyn std::marker::Send;
-      let mut _33: *const dyn std::marker::Send;
-      let _34: ();
-      let mut _35: bool;
+      let _32: ();
+      let mut _33: bool;
+      let mut _34: *const dyn std::marker::Send;
+      let mut _35: *const dyn std::marker::Send;
       let mut _36: *const dyn std::marker::Send;
-      let mut _37: *const dyn std::marker::Send;
-      let mut _38: *const dyn std::marker::Send;
-      let _39: ();
-      let mut _40: bool;
+      let _37: ();
+      let mut _38: bool;
+      let mut _39: *const dyn std::marker::Send;
+      let mut _40: *const dyn std::marker::Send;
       let mut _41: *const dyn std::marker::Send;
-      let mut _42: *const dyn std::marker::Send;
-      let mut _43: *const dyn std::marker::Send;
-      let _44: ();
-      let mut _45: bool;
+      let _42: ();
+      let mut _43: bool;
+      let mut _44: *const dyn std::marker::Send;
+      let mut _45: *const dyn std::marker::Send;
       let mut _46: *const dyn std::marker::Send;
-      let mut _47: *const dyn std::marker::Send;
-      let mut _48: *const dyn std::marker::Send;
-      let mut _49: &[i32; 2];
+      let mut _47: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _11: *const dyn std::marker::Send;
+              let _10: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _11;
+                  debug b => _10;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _49 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_49);
+          _47 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_47);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -74,11 +72,9 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _9 = Len((*_1));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind continue];
-+         _9 = const 2_usize;
-+         _10 = const true;
+-         _9 = Lt(copy _8, const 2_usize);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind continue];
++         _9 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind continue];
       }
   
@@ -95,170 +91,168 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_11);
--         StorageLive(_12);
+          StorageLive(_10);
+-         StorageLive(_11);
 +         nop;
+          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          StorageLive(_16);
-          _16 = const 1_usize;
--         _17 = Len((*_1));
--         _18 = Lt(copy _16, copy _17);
--         assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind continue];
-+         _17 = const 2_usize;
-+         _18 = const true;
+          _15 = const 1_usize;
+-         _16 = Lt(copy _15, const 2_usize);
+-         assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind continue];
++         _16 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind continue];
       }
   
       bb2: {
--         _15 = &(*_1)[_16];
-+         _15 = &(*_1)[1 of 2];
-          _14 = &(*_15);
-          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
-          StorageDead(_14);
-          _12 = &raw const (*_13);
--         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
--         StorageDead(_12);
-+         _11 = copy _12;
-+         nop;
-          StorageDead(_15);
+-         _14 = &(*_1)[_15];
++         _14 = &(*_1)[1 of 2];
+          _13 = &(*_14);
+          _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_13);
+          _11 = &raw const (*_12);
+-         _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_11);
++         _10 = copy _11;
++         nop;
+          StorageDead(_14);
+          StorageDead(_12);
+          StorageLive(_17);
+          StorageLive(_18);
           StorageLive(_19);
+-         _19 = copy _3;
++         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _3;
-+         _21 = copy _4;
-          StorageLive(_22);
-          StorageLive(_23);
--         _23 = copy _11;
--         _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _23 = copy _12;
-+         _22 = copy _12;
-          StorageDead(_23);
--         _20 = Eq(move _21, move _22);
-+         _20 = Eq(copy _4, copy _12);
-          StorageDead(_22);
+-         _21 = copy _10;
+-         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _21 = copy _11;
++         _20 = copy _11;
           StorageDead(_21);
-          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind continue];
+-         _18 = Eq(move _19, move _20);
++         _18 = Eq(copy _4, copy _11);
+          StorageDead(_20);
+          StorageDead(_19);
+          _17 = opaque::<bool>(move _18) -> [return: bb3, unwind continue];
       }
   
       bb3: {
-          StorageDead(_20);
-          StorageDead(_19);
+          StorageDead(_18);
+          StorageDead(_17);
+          StorageLive(_22);
+          StorageLive(_23);
           StorageLive(_24);
+-         _24 = copy _3;
++         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _3;
-+         _26 = copy _4;
-          StorageLive(_27);
-          StorageLive(_28);
--         _28 = copy _11;
--         _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _28 = copy _12;
-+         _27 = copy _12;
-          StorageDead(_28);
--         _25 = Ne(move _26, move _27);
-+         _25 = Ne(copy _4, copy _12);
-          StorageDead(_27);
+-         _26 = copy _10;
+-         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _26 = copy _11;
++         _25 = copy _11;
           StorageDead(_26);
-          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind continue];
+-         _23 = Ne(move _24, move _25);
++         _23 = Ne(copy _4, copy _11);
+          StorageDead(_25);
+          StorageDead(_24);
+          _22 = opaque::<bool>(move _23) -> [return: bb4, unwind continue];
       }
   
       bb4: {
-          StorageDead(_25);
-          StorageDead(_24);
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_27);
+          StorageLive(_28);
           StorageLive(_29);
+-         _29 = copy _3;
++         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _3;
-+         _31 = copy _4;
-          StorageLive(_32);
-          StorageLive(_33);
--         _33 = copy _11;
--         _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _33 = copy _12;
-+         _32 = copy _12;
-          StorageDead(_33);
--         _30 = Lt(move _31, move _32);
-+         _30 = Lt(copy _4, copy _12);
-          StorageDead(_32);
+-         _31 = copy _10;
+-         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _31 = copy _11;
++         _30 = copy _11;
           StorageDead(_31);
-          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind continue];
+-         _28 = Lt(move _29, move _30);
++         _28 = Lt(copy _4, copy _11);
+          StorageDead(_30);
+          StorageDead(_29);
+          _27 = opaque::<bool>(move _28) -> [return: bb5, unwind continue];
       }
   
       bb5: {
-          StorageDead(_30);
-          StorageDead(_29);
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_32);
+          StorageLive(_33);
           StorageLive(_34);
+-         _34 = copy _3;
++         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _3;
-+         _36 = copy _4;
-          StorageLive(_37);
-          StorageLive(_38);
--         _38 = copy _11;
--         _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _38 = copy _12;
-+         _37 = copy _12;
-          StorageDead(_38);
--         _35 = Le(move _36, move _37);
-+         _35 = Le(copy _4, copy _12);
-          StorageDead(_37);
+-         _36 = copy _10;
+-         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _36 = copy _11;
++         _35 = copy _11;
           StorageDead(_36);
-          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind continue];
+-         _33 = Le(move _34, move _35);
++         _33 = Le(copy _4, copy _11);
+          StorageDead(_35);
+          StorageDead(_34);
+          _32 = opaque::<bool>(move _33) -> [return: bb6, unwind continue];
       }
   
       bb6: {
-          StorageDead(_35);
-          StorageDead(_34);
+          StorageDead(_33);
+          StorageDead(_32);
+          StorageLive(_37);
+          StorageLive(_38);
           StorageLive(_39);
+-         _39 = copy _3;
++         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _3;
-+         _41 = copy _4;
-          StorageLive(_42);
-          StorageLive(_43);
--         _43 = copy _11;
--         _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _43 = copy _12;
-+         _42 = copy _12;
-          StorageDead(_43);
--         _40 = Gt(move _41, move _42);
-+         _40 = Gt(copy _4, copy _12);
-          StorageDead(_42);
+-         _41 = copy _10;
+-         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _41 = copy _11;
++         _40 = copy _11;
           StorageDead(_41);
-          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind continue];
+-         _38 = Gt(move _39, move _40);
++         _38 = Gt(copy _4, copy _11);
+          StorageDead(_40);
+          StorageDead(_39);
+          _37 = opaque::<bool>(move _38) -> [return: bb7, unwind continue];
       }
   
       bb7: {
-          StorageDead(_40);
-          StorageDead(_39);
+          StorageDead(_38);
+          StorageDead(_37);
+          StorageLive(_42);
+          StorageLive(_43);
           StorageLive(_44);
+-         _44 = copy _3;
++         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _3;
-+         _46 = copy _4;
-          StorageLive(_47);
-          StorageLive(_48);
--         _48 = copy _11;
--         _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _48 = copy _12;
-+         _47 = copy _12;
-          StorageDead(_48);
--         _45 = Ge(move _46, move _47);
-+         _45 = Ge(copy _4, copy _12);
-          StorageDead(_47);
+-         _46 = copy _10;
+-         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _46 = copy _11;
++         _45 = copy _11;
           StorageDead(_46);
-          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind continue];
+-         _43 = Ge(move _44, move _45);
++         _43 = Ge(copy _4, copy _11);
+          StorageDead(_45);
+          StorageDead(_44);
+          _42 = opaque::<bool>(move _43) -> [return: bb8, unwind continue];
       }
   
       bb8: {
-          StorageDead(_45);
-          StorageDead(_44);
+          StorageDead(_43);
+          StorageDead(_42);
           _0 = const ();
-          StorageDead(_16);
-          StorageDead(_11);
+          StorageDead(_15);
+          StorageDead(_10);
           StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
index 94017f028cc..56d4d50e967 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
@@ -16,7 +16,6 @@
 +     scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new) {
 +         debug pointer => _3;
 +         scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new_unchecked) {
-+             debug pointer => _3;
 +         }
 +     }
 +     scope 5 (inlined g::{closure#0}) {
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
index 858f9ace9b4..751916a00f1 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
@@ -16,7 +16,6 @@
 +     scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new) {
 +         debug pointer => _3;
 +         scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new_unchecked) {
-+             debug pointer => _3;
 +         }
 +     }
 +     scope 5 (inlined g::{closure#0}) {
diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
deleted file mode 100644
index f39df7ffca0..00000000000
--- a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `norm2` before InstSimplify-after-simplifycfg
-+ // MIR for `norm2` after InstSimplify-after-simplifycfg
-  
-  fn norm2(_1: [f32; 2]) -> f32 {
-      debug x => _1;
-      let mut _0: f32;
-      let _2: f32;
-      let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
-      let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let mut _10: f32;
-      let mut _11: f32;
-      let mut _12: f32;
-      let mut _13: f32;
-      let mut _14: f32;
-      let mut _15: f32;
-      scope 1 {
-          debug a => _2;
-          let _6: f32;
-          scope 2 {
-              debug b => _6;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_2);
-          StorageLive(_3);
-          _3 = const 0_usize;
--         _4 = Len(_1);
-+         _4 = const 2_usize;
-          _5 = Lt(copy _3, copy _4);
-          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          _2 = copy _1[_3];
-          StorageDead(_3);
-          StorageLive(_6);
-          StorageLive(_7);
-          _7 = const 1_usize;
--         _8 = Len(_1);
-+         _8 = const 2_usize;
-          _9 = Lt(copy _7, copy _8);
-          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          _6 = copy _1[_7];
-          StorageDead(_7);
-          StorageLive(_10);
-          StorageLive(_11);
-          _11 = copy _2;
-          StorageLive(_12);
-          _12 = copy _2;
-          _10 = Mul(move _11, move _12);
-          StorageDead(_12);
-          StorageDead(_11);
-          StorageLive(_13);
-          StorageLive(_14);
-          _14 = copy _6;
-          StorageLive(_15);
-          _15 = copy _6;
-          _13 = Mul(move _14, move _15);
-          StorageDead(_15);
-          StorageDead(_14);
-          _0 = Add(move _10, move _13);
-          StorageDead(_13);
-          StorageDead(_10);
-          StorageDead(_6);
-          StorageDead(_2);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
deleted file mode 100644
index 0e7d5653c68..00000000000
--- a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `norm2` before InstSimplify-after-simplifycfg
-+ // MIR for `norm2` after InstSimplify-after-simplifycfg
-  
-  fn norm2(_1: [f32; 2]) -> f32 {
-      debug x => _1;
-      let mut _0: f32;
-      let _2: f32;
-      let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
-      let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let mut _10: f32;
-      let mut _11: f32;
-      let mut _12: f32;
-      let mut _13: f32;
-      let mut _14: f32;
-      let mut _15: f32;
-      scope 1 {
-          debug a => _2;
-          let _6: f32;
-          scope 2 {
-              debug b => _6;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_2);
-          StorageLive(_3);
-          _3 = const 0_usize;
--         _4 = Len(_1);
-+         _4 = const 2_usize;
-          _5 = Lt(copy _3, copy _4);
-          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-      }
-  
-      bb1: {
-          _2 = copy _1[_3];
-          StorageDead(_3);
-          StorageLive(_6);
-          StorageLive(_7);
-          _7 = const 1_usize;
--         _8 = Len(_1);
-+         _8 = const 2_usize;
-          _9 = Lt(copy _7, copy _8);
-          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
-      }
-  
-      bb2: {
-          _6 = copy _1[_7];
-          StorageDead(_7);
-          StorageLive(_10);
-          StorageLive(_11);
-          _11 = copy _2;
-          StorageLive(_12);
-          _12 = copy _2;
-          _10 = Mul(move _11, move _12);
-          StorageDead(_12);
-          StorageDead(_11);
-          StorageLive(_13);
-          StorageLive(_14);
-          _14 = copy _6;
-          StorageLive(_15);
-          _15 = copy _6;
-          _13 = Mul(move _14, move _15);
-          StorageDead(_15);
-          StorageDead(_14);
-          _0 = Add(move _10, move _13);
-          StorageDead(_13);
-          StorageDead(_10);
-          StorageDead(_6);
-          StorageDead(_2);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.rs b/tests/mir-opt/instsimplify/combine_array_len.rs
deleted file mode 100644
index 91f43f75689..00000000000
--- a/tests/mir-opt/instsimplify/combine_array_len.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
-//@ test-mir-pass: InstSimplify-after-simplifycfg
-
-// EMIT_MIR combine_array_len.norm2.InstSimplify-after-simplifycfg.diff
-fn norm2(x: [f32; 2]) -> f32 {
-    // CHECK-LABEL: fn norm2(
-    // CHECK-NOT: Len(
-    let a = x[0];
-    let b = x[1];
-    a * a + b * b
-}
-
-fn main() {
-    assert_eq!(norm2([3.0, 4.0]), 5.0 * 5.0);
-}
diff --git a/tests/mir-opt/issue_72181.foo.built.after.mir b/tests/mir-opt/issue_72181.foo.built.after.mir
index 314cf8b367f..7593b795432 100644
--- a/tests/mir-opt/issue_72181.foo.built.after.mir
+++ b/tests/mir-opt/issue_72181.foo.built.after.mir
@@ -4,15 +4,14 @@ fn foo(_1: [(Never, u32); 1]) -> u32 {
     debug xs => _1;
     let mut _0: u32;
     let _2: usize;
-    let mut _3: usize;
-    let mut _4: bool;
+    let mut _3: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = const 0_usize;
-        _3 = Len(_1);
-        _4 = Lt(copy _2, copy _3);
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind: bb2];
+        FakeRead(ForIndex, _1);
+        _3 = Lt(copy _2, const 1_usize);
+        assert(move _3, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _2) -> [success: bb1, unwind: bb2];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
index aade84a6dd2..9f3803f5407 100644
--- a/tests/mir-opt/issue_72181.main.built.after.mir
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -7,8 +7,7 @@ fn main() -> () {
     let mut _4: Foo;
     let mut _5: u64;
     let _6: usize;
-    let mut _7: usize;
-    let mut _8: bool;
+    let mut _7: bool;
     scope 1 {
         let _2: [Foo; 2];
         scope 2 {
@@ -38,9 +37,9 @@ fn main() -> () {
         StorageLive(_5);
         StorageLive(_6);
         _6 = const 0_usize;
-        _7 = Len(_2);
-        _8 = Lt(copy _6, copy _7);
-        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb3, unwind: bb5];
+        FakeRead(ForIndex, _2);
+        _7 = Lt(copy _6, const 2_usize);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _6) -> [success: bb3, unwind: bb5];
     }
 
     bb2: {
diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir
index 50fdf08375a..bf65b5b4a8c 100644
--- a/tests/mir-opt/issue_91633.foo.built.after.mir
+++ b/tests/mir-opt/issue_91633.foo.built.after.mir
@@ -6,8 +6,9 @@ fn foo(_1: Box<[T]>) -> T {
     let _2: T;
     let mut _3: &T;
     let _4: usize;
-    let mut _5: usize;
-    let mut _6: bool;
+    let mut _5: *const [T];
+    let mut _6: usize;
+    let mut _7: bool;
     scope 1 {
         debug f => _2;
     }
@@ -17,9 +18,10 @@ fn foo(_1: Box<[T]>) -> T {
         StorageLive(_3);
         StorageLive(_4);
         _4 = const 0_usize;
-        _5 = Len((*_1));
-        _6 = Lt(copy _4, copy _5);
-        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb5];
+        _5 = &raw const (*_1);
+        _6 = PtrMetadata(move _5);
+        _7 = Lt(copy _4, copy _6);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb5];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir
index 5b41b376719..d2fc438d3e8 100644
--- a/tests/mir-opt/issue_91633.fun.built.after.mir
+++ b/tests/mir-opt/issue_91633.fun.built.after.mir
@@ -15,7 +15,7 @@ fn fun(_1: &[T]) -> &T {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const 0_usize;
-        _4 = Len((*_1));
+        _4 = PtrMetadata(copy _1);
         _5 = Lt(copy _3, copy _4);
         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb2];
     }
diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
index f052c8f63dc..98c5e868046 100644
--- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
@@ -11,16 +11,14 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
+      let mut _9: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,16 +38,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -61,8 +56,7 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
index 3299e300431..72c73137869 100644
--- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
@@ -11,16 +11,14 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
+      let mut _9: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,16 +38,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -61,8 +56,7 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
index 329eb80b3c4..9ffaf44c02b 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
@@ -11,19 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
+      let mut _9: bool;
+      let _10: usize;
+      let mut _11: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -43,16 +40,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -64,23 +58,20 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_11);
-          _11 = const 0_usize;
--         _12 = Len((*_2));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
-+         _12 = const N;
-+         _13 = Lt(const 0_usize, const N);
-+         assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
+          StorageLive(_10);
+          _10 = const 0_usize;
+-         _11 = Lt(copy _10, const N);
+-         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind unreachable];
++         _11 = Lt(const 0_usize, const N);
++         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
       }
   
       bb5: {
--         (*_2)[_11] = const 42_u8;
+-         (*_2)[_10] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_11);
+          StorageDead(_10);
           _0 = const 42_u8;
           goto -> bb6;
       }
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
index ab007e133ec..08008e46335 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
@@ -11,19 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
+      let mut _9: bool;
+      let _10: usize;
+      let mut _11: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -43,16 +40,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -64,23 +58,20 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_11);
-          _11 = const 0_usize;
--         _12 = Len((*_2));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
-+         _12 = const N;
-+         _13 = Lt(const 0_usize, const N);
-+         assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
+          StorageLive(_10);
+          _10 = const 0_usize;
+-         _11 = Lt(copy _10, const N);
+-         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind continue];
++         _11 = Lt(const 0_usize, const N);
++         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
       }
   
       bb5: {
--         (*_2)[_11] = const 42_u8;
+-         (*_2)[_10] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_11);
+          StorageDead(_10);
           _0 = const 42_u8;
           goto -> bb6;
       }
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
index 20001f1248e..4b39e18d16c 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
@@ -36,7 +36,7 @@
           StorageDead(_4);
           StorageLive(_7);
           _7 = copy _1;
-          _8 = Len((*_2));
+          _8 = PtrMetadata(copy _2);
           _9 = Lt(copy _7, copy _8);
           assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind unreachable];
       }
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
index ca8f92df5de..f0d4afa21ae 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
@@ -36,7 +36,7 @@
           StorageDead(_4);
           StorageLive(_7);
           _7 = copy _1;
-          _8 = Len((*_2));
+          _8 = PtrMetadata(copy _2);
           _9 = Lt(copy _7, copy _8);
           assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind continue];
       }
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
index 7294302609a..35e44b2314a 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -27,20 +27,19 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x00000003): usize)];
     let _3: usize;
-    let mut _4: usize;
-    let mut _5: bool;
-    let mut _7: bool;
-    let _8: bool;
-    let mut _9: usize;
-    let _10: bool;
+    let mut _4: bool;
+    let mut _6: bool;
+    let _7: bool;
+    let mut _8: usize;
+    let _9: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _6: &'?4 usize;
+            let _5: &'?4 usize;
             scope 3 {
-                debug q => _6;
+                debug q => _5;
             }
         }
     }
@@ -52,50 +51,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x00000000): usize);
-        _4 = Len(_1);
-        _5 = Lt(copy _3, copy _4);
-        assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
+        FakeRead(ForIndex, _1);
+        _4 = Lt(copy _3, const ConstValue(Scalar(0x00000003): usize));
+        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb7];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
+        StorageLive(_5);
+        _5 = copy _2;
+        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = copy _2;
-        FakeRead(ForLet(None), _6);
-        StorageLive(_7);
-        _7 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _7) -> [0: bb4, otherwise: bb2];
+        _6 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _6) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
+        StorageLive(_7);
         StorageLive(_8);
-        StorageLive(_9);
-        _9 = copy (*_6);
-        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
+        _8 = copy (*_5);
+        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
-        StorageDead(_9);
         StorageDead(_8);
+        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_10);
-        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_9);
+        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_10);
+        StorageDead(_9);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb6: {
-        StorageDead(_7);
         StorageDead(_6);
+        StorageDead(_5);
         StorageDead(_3);
         StorageDead(_2);
         StorageDead(_1);
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
index 85b89a013c4..6d415f42d06 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -27,20 +27,19 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x0000000000000003): usize)];
     let _3: usize;
-    let mut _4: usize;
-    let mut _5: bool;
-    let mut _7: bool;
-    let _8: bool;
-    let mut _9: usize;
-    let _10: bool;
+    let mut _4: bool;
+    let mut _6: bool;
+    let _7: bool;
+    let mut _8: usize;
+    let _9: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _6: &'?4 usize;
+            let _5: &'?4 usize;
             scope 3 {
-                debug q => _6;
+                debug q => _5;
             }
         }
     }
@@ -52,50 +51,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x0000000000000000): usize);
-        _4 = Len(_1);
-        _5 = Lt(copy _3, copy _4);
-        assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
+        FakeRead(ForIndex, _1);
+        _4 = Lt(copy _3, const ConstValue(Scalar(0x0000000000000003): usize));
+        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb7];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
+        StorageLive(_5);
+        _5 = copy _2;
+        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = copy _2;
-        FakeRead(ForLet(None), _6);
-        StorageLive(_7);
-        _7 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _7) -> [0: bb4, otherwise: bb2];
+        _6 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _6) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
+        StorageLive(_7);
         StorageLive(_8);
-        StorageLive(_9);
-        _9 = copy (*_6);
-        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
+        _8 = copy (*_5);
+        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
-        StorageDead(_9);
         StorageDead(_8);
+        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_10);
-        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_9);
+        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_10);
+        StorageDead(_9);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb6: {
-        StorageDead(_7);
         StorageDead(_6);
+        StorageDead(_5);
         StorageDead(_3);
         StorageDead(_2);
         StorageDead(_1);
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
index 6575610727b..5b39e45806e 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
index 1a4ed5767fe..ea2742a6471 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
index 6575610727b..5b39e45806e 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
index 1a4ed5767fe..ea2742a6471 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
index e2420a341e0..f7fe08831b9 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
index a2fb3b979e6..6e36386bea6 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
index e2420a341e0..f7fe08831b9 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
index a2fb3b979e6..6e36386bea6 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs
index 574062d6c35..5dac535d195 100644
--- a/tests/mir-opt/pre-codegen/slice_index.rs
+++ b/tests/mir-opt/pre-codegen/slice_index.rs
@@ -9,7 +9,7 @@ use std::ops::Range;
 // EMIT_MIR slice_index.slice_index_usize.PreCodegen.after.mir
 pub fn slice_index_usize(slice: &[u32], index: usize) -> u32 {
     // CHECK-LABEL: slice_index_usize
-    // CHECK: [[LEN:_[0-9]+]] = Len((*_1))
+    // CHECK: [[LEN:_[0-9]+]] = PtrMetadata(copy _1)
     // CHECK: Lt(copy _2, copy [[LEN]])
     // CHECK-NOT: precondition_check
     // CHECK: _0 = copy (*_1)[_2];
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
index cc1034229fc..81e60b8ec2c 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
@@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 {
     let mut _4: bool;
 
     bb0: {
-        _3 = Len((*_1));
+        _3 = PtrMetadata(copy _1);
         _4 = Lt(copy _2, copy _3);
         assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind unreachable];
     }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
index 358226fb529..c0fdc839608 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
@@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 {
     let mut _4: bool;
 
     bb0: {
-        _3 = Len((*_1));
+        _3 = PtrMetadata(copy _1);
         _4 = Lt(copy _2, copy _3);
         assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind continue];
     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
index ecac03ad0f9..151783969dd 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
@@ -7,20 +7,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     let mut _3: usize;
     let mut _4: usize;
     let mut _9: std::option::Option<usize>;
-    let mut _11: usize;
-    let mut _12: bool;
-    let mut _14: &impl Fn(usize, &T);
-    let mut _15: (usize, &T);
-    let _16: ();
+    let mut _11: bool;
+    let mut _13: &impl Fn(usize, &T);
+    let mut _14: (usize, &T);
+    let _15: ();
     scope 1 {
         debug ((iter: std::ops::Range<usize>).0: usize) => _4;
         debug ((iter: std::ops::Range<usize>).1: usize) => _3;
         let _10: usize;
         scope 2 {
             debug i => _10;
-            let _13: &T;
+            let _12: &T;
             scope 3 {
-                debug x => _13;
+                debug x => _12;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -82,23 +81,22 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _11 = Len((*_1));
-        _12 = Lt(copy _10, copy _11);
-        assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind unreachable];
+        _11 = Lt(copy _10, copy _3);
+        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind unreachable];
     }
 
     bb6: {
-        _13 = &(*_1)[_10];
+        _12 = &(*_1)[_10];
+        StorageLive(_13);
+        _13 = &_2;
         StorageLive(_14);
-        _14 = &_2;
-        StorageLive(_15);
-        _15 = (copy _10, copy _13);
-        _16 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _14, move _15) -> [return: bb7, unwind unreachable];
+        _14 = (copy _10, copy _12);
+        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind unreachable];
     }
 
     bb7: {
-        StorageDead(_15);
         StorageDead(_14);
+        StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index 1032473b9b2..006329dc20d 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -7,20 +7,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     let mut _3: usize;
     let mut _4: usize;
     let mut _9: std::option::Option<usize>;
-    let mut _11: usize;
-    let mut _12: bool;
-    let mut _14: &impl Fn(usize, &T);
-    let mut _15: (usize, &T);
-    let _16: ();
+    let mut _11: bool;
+    let mut _13: &impl Fn(usize, &T);
+    let mut _14: (usize, &T);
+    let _15: ();
     scope 1 {
         debug ((iter: std::ops::Range<usize>).0: usize) => _4;
         debug ((iter: std::ops::Range<usize>).1: usize) => _3;
         let _10: usize;
         scope 2 {
             debug i => _10;
-            let _13: &T;
+            let _12: &T;
             scope 3 {
-                debug x => _13;
+                debug x => _12;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -82,23 +81,22 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _11 = Len((*_1));
-        _12 = Lt(copy _10, copy _11);
-        assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind: bb8];
+        _11 = Lt(copy _10, copy _3);
+        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind: bb8];
     }
 
     bb6: {
-        _13 = &(*_1)[_10];
+        _12 = &(*_1)[_10];
+        StorageLive(_13);
+        _13 = &_2;
         StorageLive(_14);
-        _14 = &_2;
-        StorageLive(_15);
-        _15 = (copy _10, copy _13);
-        _16 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _14, move _15) -> [return: bb7, unwind: bb8];
+        _14 = (copy _10, copy _12);
+        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind: bb8];
     }
 
     bb7: {
-        StorageDead(_15);
         StorageDead(_14);
+        StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
index 2efbb6d9904..3f0d60b46f4 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
@@ -7,48 +7,36 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _9: *const u8;
-            let mut _10: usize;
+            let mut _7: *const u8;
+            let mut _8: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
-                let mut _2: &alloc::raw_vec::RawVec<u8>;
-                let mut _8: *mut u8;
+                let mut _6: *mut u8;
                 scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
-                    debug self => _2;
-                    let mut _3: &alloc::raw_vec::RawVecInner;
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                        debug self => _3;
-                        let mut _7: std::ptr::NonNull<u8>;
+                        let mut _5: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
-                            debug self => _3;
-                            let mut _4: std::ptr::NonNull<u8>;
+                            let mut _2: std::ptr::NonNull<u8>;
                             scope 7 (inlined Unique::<u8>::cast::<u8>) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                                 scope 8 (inlined NonNull::<u8>::cast::<u8>) {
-                                    debug self => _4;
-                                    let mut _5: *mut u8;
-                                    let mut _6: *const u8;
+                                    let mut _3: *mut u8;
+                                    let mut _4: *const u8;
                                     scope 9 (inlined NonNull::<u8>::as_ptr) {
-                                        debug self => _4;
                                     }
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
-                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::as_ptr) {
-                            debug self => _7;
                         }
                     }
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
-                debug data => _9;
-                debug len => _10;
-                let _11: *const [u8];
+                debug data => _7;
+                debug len => _8;
+                let _9: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -58,11 +46,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 scope 16 (inlined align_of::<u8>) {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
-                    debug data => _9;
-                    debug len => _10;
+                    debug data => _7;
+                    debug len => _8;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                        debug data_pointer => _9;
-                        debug metadata => _10;
+                        debug data_pointer => _7;
                     }
                 }
             }
@@ -70,37 +57,31 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     }
 
     bb0: {
-        StorageLive(_8);
-        StorageLive(_9);
+        StorageLive(_6);
+        StorageLive(_7);
+        StorageLive(_5);
         StorageLive(_2);
-        _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
+        _2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         StorageLive(_3);
-        _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
-        StorageLive(_7);
         StorageLive(_4);
-        _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
-        StorageLive(_5);
-        StorageLive(_6);
-        _5 = copy _4 as *mut u8 (Transmute);
-        _6 = copy _5 as *const u8 (PtrToPtr);
-        _7 = NonNull::<u8> { pointer: move _6 };
-        StorageDead(_6);
-        StorageDead(_5);
+        _3 = copy _2 as *mut u8 (Transmute);
+        _4 = copy _3 as *const u8 (PtrToPtr);
+        _5 = NonNull::<u8> { pointer: move _4 };
         StorageDead(_4);
-        _8 = copy _7 as *mut u8 (Transmute);
-        StorageDead(_7);
         StorageDead(_3);
-        _9 = copy _8 as *const u8 (PtrToPtr);
         StorageDead(_2);
-        StorageLive(_10);
-        _10 = copy ((*_1).1: usize);
-        StorageLive(_11);
-        _11 = *const [u8] from (copy _9, copy _10);
-        _0 = &(*_11);
-        StorageDead(_11);
-        StorageDead(_10);
+        _6 = copy _5 as *mut u8 (Transmute);
+        StorageDead(_5);
+        _7 = copy _6 as *const u8 (PtrToPtr);
+        StorageLive(_8);
+        _8 = copy ((*_1).1: usize);
+        StorageLive(_9);
+        _9 = *const [u8] from (copy _7, copy _8);
+        _0 = &(*_9);
         StorageDead(_9);
         StorageDead(_8);
+        StorageDead(_7);
+        StorageDead(_6);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
index 2efbb6d9904..3f0d60b46f4 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
@@ -7,48 +7,36 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _9: *const u8;
-            let mut _10: usize;
+            let mut _7: *const u8;
+            let mut _8: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
-                let mut _2: &alloc::raw_vec::RawVec<u8>;
-                let mut _8: *mut u8;
+                let mut _6: *mut u8;
                 scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
-                    debug self => _2;
-                    let mut _3: &alloc::raw_vec::RawVecInner;
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                        debug self => _3;
-                        let mut _7: std::ptr::NonNull<u8>;
+                        let mut _5: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
-                            debug self => _3;
-                            let mut _4: std::ptr::NonNull<u8>;
+                            let mut _2: std::ptr::NonNull<u8>;
                             scope 7 (inlined Unique::<u8>::cast::<u8>) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                                 scope 8 (inlined NonNull::<u8>::cast::<u8>) {
-                                    debug self => _4;
-                                    let mut _5: *mut u8;
-                                    let mut _6: *const u8;
+                                    let mut _3: *mut u8;
+                                    let mut _4: *const u8;
                                     scope 9 (inlined NonNull::<u8>::as_ptr) {
-                                        debug self => _4;
                                     }
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
-                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::as_ptr) {
-                            debug self => _7;
                         }
                     }
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
-                debug data => _9;
-                debug len => _10;
-                let _11: *const [u8];
+                debug data => _7;
+                debug len => _8;
+                let _9: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -58,11 +46,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 scope 16 (inlined align_of::<u8>) {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
-                    debug data => _9;
-                    debug len => _10;
+                    debug data => _7;
+                    debug len => _8;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                        debug data_pointer => _9;
-                        debug metadata => _10;
+                        debug data_pointer => _7;
                     }
                 }
             }
@@ -70,37 +57,31 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     }
 
     bb0: {
-        StorageLive(_8);
-        StorageLive(_9);
+        StorageLive(_6);
+        StorageLive(_7);
+        StorageLive(_5);
         StorageLive(_2);
-        _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
+        _2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         StorageLive(_3);
-        _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
-        StorageLive(_7);
         StorageLive(_4);
-        _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
-        StorageLive(_5);
-        StorageLive(_6);
-        _5 = copy _4 as *mut u8 (Transmute);
-        _6 = copy _5 as *const u8 (PtrToPtr);
-        _7 = NonNull::<u8> { pointer: move _6 };
-        StorageDead(_6);
-        StorageDead(_5);
+        _3 = copy _2 as *mut u8 (Transmute);
+        _4 = copy _3 as *const u8 (PtrToPtr);
+        _5 = NonNull::<u8> { pointer: move _4 };
         StorageDead(_4);
-        _8 = copy _7 as *mut u8 (Transmute);
-        StorageDead(_7);
         StorageDead(_3);
-        _9 = copy _8 as *const u8 (PtrToPtr);
         StorageDead(_2);
-        StorageLive(_10);
-        _10 = copy ((*_1).1: usize);
-        StorageLive(_11);
-        _11 = *const [u8] from (copy _9, copy _10);
-        _0 = &(*_11);
-        StorageDead(_11);
-        StorageDead(_10);
+        _6 = copy _5 as *mut u8 (Transmute);
+        StorageDead(_5);
+        _7 = copy _6 as *const u8 (PtrToPtr);
+        StorageLive(_8);
+        _8 = copy ((*_1).1: usize);
+        StorageLive(_9);
+        _9 = *const [u8] from (copy _7, copy _8);
+        _0 = &(*_9);
         StorageDead(_9);
         StorageDead(_8);
+        StorageDead(_7);
+        StorageDead(_6);
         return;
     }
 }
diff --git a/tests/mir-opt/strip_debuginfo.rs b/tests/mir-opt/strip_debuginfo.rs
new file mode 100644
index 00000000000..310609e1e9d
--- /dev/null
+++ b/tests/mir-opt/strip_debuginfo.rs
@@ -0,0 +1,39 @@
+//@ revisions: NONE TINY ALL
+//@[NONE] compile-flags: -Zmir_strip_debuginfo=none
+//@[TINY] compile-flags: -Zmir_strip_debuginfo=locals-in-tiny-functions
+//@[ALL] compile-flags: -Zmir_strip_debuginfo=all-locals
+
+// CHECK: fn tiny_function
+fn tiny_function(end: u32) -> u32 {
+    // CHECK: debug end => _1;
+    // NONE: debug a =>
+    // NONE: debug b =>
+    // TINY-NOT: debug a =>
+    // TINY-NOT: debug b =>
+    // ALL-NOT: debug a =>
+    // ALL-NOT: debug b =>
+    let a = !end;
+    let b = a ^ 1;
+    b
+}
+
+#[inline(never)]
+fn opaque(_: u32) {}
+
+// CHECK: fn looping_function
+fn looping_function(end: u32) {
+    // CHECK: debug end => _1;
+    // NONE: debug i =>
+    // NONE: debug x =>
+    // TINY: debug i =>
+    // TINY: debug x =>
+    // ALL-NOT: debug i =>
+    // ALL-NOT: debug x =>
+    let mut i = 0;
+    while i < end {
+        let x = i ^ 1;
+        opaque(x);
+    }
+}
+
+fn main() {}
diff --git a/tests/run-make/link-args-order/rmake.rs b/tests/run-make/link-args-order/rmake.rs
index b7ef8333267..fe0d02926ef 100644
--- a/tests/run-make/link-args-order/rmake.rs
+++ b/tests/run-make/link-args-order/rmake.rs
@@ -15,8 +15,9 @@ fn main() {
         .link_args("b c")
         .link_args("d e")
         .link_arg("f")
+        .arg("--print=link-args")
         .run_fail()
-        .assert_stderr_contains(r#""a" "b" "c" "d" "e" "f""#);
+        .assert_stdout_contains(r#""a" "b" "c" "d" "e" "f""#);
     rustc()
         .input("empty.rs")
         .linker_flavor(linker)
@@ -24,6 +25,7 @@ fn main() {
         .arg("-Zpre-link-args=b c")
         .arg("-Zpre-link-args=d e")
         .arg("-Zpre-link-arg=f")
+        .arg("--print=link-args")
         .run_fail()
-        .assert_stderr_contains(r#""a" "b" "c" "d" "e" "f""#);
+        .assert_stdout_contains(r#""a" "b" "c" "d" "e" "f""#);
 }
diff --git a/tests/run-make/link-dedup/rmake.rs b/tests/run-make/link-dedup/rmake.rs
index 6075f310954..f38603dee8c 100644
--- a/tests/run-make/link-dedup/rmake.rs
+++ b/tests/run-make/link-dedup/rmake.rs
@@ -14,13 +14,13 @@ fn main() {
     rustc().input("depb.rs").run();
     rustc().input("depc.rs").run();
 
-    let output = rustc().input("empty.rs").cfg("bar").run_fail();
-    output.assert_stderr_contains(needle_from_libs(&["testa", "testb", "testa"]));
+    let output = rustc().input("empty.rs").cfg("bar").arg("--print=link-args").run_fail();
+    output.assert_stdout_contains(needle_from_libs(&["testa", "testb", "testa"]));
 
-    let output = rustc().input("empty.rs").run_fail();
-    output.assert_stderr_contains(needle_from_libs(&["testa"]));
-    output.assert_stderr_not_contains(needle_from_libs(&["testb"]));
-    output.assert_stderr_not_contains(needle_from_libs(&["testa", "testa", "testa"]));
+    let output = rustc().input("empty.rs").arg("--print=link-args").run_fail();
+    output.assert_stdout_contains(needle_from_libs(&["testa"]));
+    output.assert_stdout_not_contains(needle_from_libs(&["testb"]));
+    output.assert_stdout_not_contains(needle_from_libs(&["testa", "testa", "testa"]));
     // Adjacent identical native libraries are no longer deduplicated if
     // they come from different crates (https://github.com/rust-lang/rust/pull/103311)
     // so the following will fail:
diff --git a/tests/run-make/linker-warning/fake-linker.rs b/tests/run-make/linker-warning/fake-linker.rs
new file mode 100644
index 00000000000..30497eea2cc
--- /dev/null
+++ b/tests/run-make/linker-warning/fake-linker.rs
@@ -0,0 +1,13 @@
+fn main() {
+    for arg in std::env::args() {
+        match &*arg {
+            "run_make_info" => println!("foo"),
+            "run_make_warn" => eprintln!("warning: bar"),
+            "run_make_error" => {
+                eprintln!("error: baz");
+                std::process::exit(1);
+            }
+            _ => (),
+        }
+    }
+}
diff --git a/tests/run-make/linker-warning/main.rs b/tests/run-make/linker-warning/main.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/tests/run-make/linker-warning/main.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
new file mode 100644
index 00000000000..4d21c5ea569
--- /dev/null
+++ b/tests/run-make/linker-warning/rmake.rs
@@ -0,0 +1,28 @@
+use run_make_support::{Rustc, rustc};
+
+fn run_rustc() -> Rustc {
+    let mut rustc = rustc();
+    rustc.arg("main.rs").output("main").linker("./fake-linker");
+    rustc
+}
+
+fn main() {
+    // first, compile our linker
+    rustc().arg("fake-linker.rs").output("fake-linker").run();
+
+    // Make sure we don't show the linker args unless `--verbose` is passed
+    run_rustc()
+        .link_arg("run_make_error")
+        .verbose()
+        .run_fail()
+        .assert_stderr_contains_regex("fake-linker.*run_make_error")
+        .assert_stderr_not_contains("object files omitted")
+        .assert_stderr_contains_regex(r"lib(/|\\\\)libstd");
+    run_rustc()
+        .link_arg("run_make_error")
+        .run_fail()
+        .assert_stderr_contains("fake-linker")
+        .assert_stderr_contains("object files omitted")
+        .assert_stderr_contains_regex(r"\{")
+        .assert_stderr_not_contains_regex(r"lib(/|\\\\)libstd");
+}
diff --git a/tests/run-make/musl-default-linking/rmake.rs b/tests/run-make/musl-default-linking/rmake.rs
new file mode 100644
index 00000000000..b6d428d3f27
--- /dev/null
+++ b/tests/run-make/musl-default-linking/rmake.rs
@@ -0,0 +1,62 @@
+use run_make_support::{rustc, serde_json};
+
+// Please do NOT add more targets to this list!
+// Per https://github.com/rust-lang/compiler-team/issues/422,
+// we should be trying to move these targets to dynamically link
+// musl libc by default.
+static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[
+    "aarch64-unknown-linux-musl",
+    "arm-unknown-linux-musleabi",
+    "arm-unknown-linux-musleabihf",
+    "armv5te-unknown-linux-musleabi",
+    "armv7-unknown-linux-musleabi",
+    "armv7-unknown-linux-musleabihf",
+    "i586-unknown-linux-musl",
+    "i686-unknown-linux-musl",
+    "mips64-unknown-linux-musl",
+    "mips64-unknown-linux-muslabi64",
+    "mips64el-unknown-linux-muslabi64",
+    "powerpc-unknown-linux-musl",
+    "powerpc-unknown-linux-muslspe",
+    "powerpc64-unknown-linux-musl",
+    "powerpc64le-unknown-linux-musl",
+    "riscv32gc-unknown-linux-musl",
+    "s390x-unknown-linux-musl",
+    "thumbv7neon-unknown-linux-musleabihf",
+    "x86_64-unknown-linux-musl",
+];
+
+fn main() {
+    let targets = rustc().print("target-list").run().stdout_utf8();
+
+    for target in targets.lines() {
+        let abi = target.split('-').last().unwrap();
+
+        if !abi.starts_with("musl") {
+            continue;
+        }
+
+        let target_spec_json = rustc()
+            .print("target-spec-json")
+            .target(target)
+            .arg("-Zunstable-options")
+            .run()
+            .stdout_utf8();
+
+        let target_spec: serde_json::Value =
+            serde_json::from_str(&target_spec_json).expect("failed to parse target-spec-json");
+        let default = &target_spec["crt-static-default"];
+
+        // If the value is `null`, then the default to dynamically link from
+        // musl_base was not overriden.
+        if default.is_null() {
+            continue;
+        }
+
+        if default.as_bool().expect("wasn't a boolean")
+            && !LEGACY_STATIC_LINKING_TARGETS.contains(&target)
+        {
+            panic!("{target} statically links musl libc when it should dynamically link it");
+        }
+    }
+}
diff --git a/tests/rustdoc-js-std/osstring-to-string.js b/tests/rustdoc-js-std/osstring-to-string.js
index 3fdc0b9f24a..17bb602a502 100644
--- a/tests/rustdoc-js-std/osstring-to-string.js
+++ b/tests/rustdoc-js-std/osstring-to-string.js
@@ -4,6 +4,6 @@
 const EXPECTED = {
     'query': 'OsString -> String',
     'others': [
-        { 'path': 'std::ffi::os_str::OsString', 'name': 'into_string' },
+        { 'path': 'std::ffi::OsString', 'name': 'into_string' },
     ]
 };
diff --git a/tests/rustdoc-js/impl-trait-inlining.js b/tests/rustdoc-js/impl-trait-inlining.js
new file mode 100644
index 00000000000..e97669c7b30
--- /dev/null
+++ b/tests/rustdoc-js/impl-trait-inlining.js
@@ -0,0 +1,35 @@
+// exact-check
+// ignore-order
+
+const EXPECTED = [
+    {
+        'query': 'tyctxt, symbol -> bool',
+        'others': [
+            {
+                'path': 'foo::TyCtxt',
+                'name': 'has_attr',
+                'displayType': "`TyCtxt`, Into<DefId>, `Symbol` -> `bool`",
+            },
+        ],
+    },
+    {
+        'query': 'tyctxt, into<defid>, symbol -> bool',
+        'others': [
+            {
+                'path': 'foo::TyCtxt',
+                'name': 'has_attr',
+                'displayType': "`TyCtxt`, `Into`<`DefId`>, `Symbol` -> `bool`",
+            },
+        ],
+    },
+    {
+        'query': 'tyctxt, defid, symbol -> bool',
+        'others': [
+            {
+                'path': 'foo::TyCtxt',
+                'name': 'has_attr',
+                'displayType': "`TyCtxt`, Into<`DefId`>, `Symbol` -> `bool`",
+            },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/impl-trait-inlining.rs b/tests/rustdoc-js/impl-trait-inlining.rs
new file mode 100644
index 00000000000..f90fb72659a
--- /dev/null
+++ b/tests/rustdoc-js/impl-trait-inlining.rs
@@ -0,0 +1,11 @@
+#![crate_name = "foo"]
+
+pub struct TyCtxt;
+pub struct DefId;
+pub struct Symbol;
+
+impl TyCtxt {
+    pub fn has_attr(self, _did: impl Into<DefId>, _attr: Symbol) -> bool {
+        unimplemented!();
+    }
+}
diff --git a/tests/rustdoc-js/reexport.js b/tests/rustdoc-js/reexport.js
index 9021cc2e90f..0b9415dd3e4 100644
--- a/tests/rustdoc-js/reexport.js
+++ b/tests/rustdoc-js/reexport.js
@@ -14,4 +14,13 @@ const EXPECTED = [
             { 'path': 'reexport', 'name': 'AnotherOne' },
         ],
     },
+    {
+        'query': 'fn:Equivalent::equivalent',
+        'others': [
+            // These results must never contain `reexport::equivalent::NotEquivalent`,
+            // since that path does not exist.
+            { 'path': 'equivalent::Equivalent', 'name': 'equivalent' },
+            { 'path': 'reexport::NotEquivalent', 'name': 'equivalent' },
+        ],
+    },
 ];
diff --git a/tests/rustdoc-js/reexport.rs b/tests/rustdoc-js/reexport.rs
index 0b3718cd9a3..ecbbeca5ea8 100644
--- a/tests/rustdoc-js/reexport.rs
+++ b/tests/rustdoc-js/reexport.rs
@@ -2,6 +2,15 @@
 // This is a DWIM case, since renaming the export probably means the intent is also different.
 // For the de-duplication case of exactly the same name, see reexport-dedup
 
+//@ aux-crate:equivalent=equivalent.rs
+//@ compile-flags: --extern equivalent
+//@ aux-build:equivalent.rs
+//@ build-aux-docs
+#[doc(inline)]
+pub extern crate equivalent;
+#[doc(inline)]
+pub use equivalent::Equivalent as NotEquivalent;
+
 pub mod fmt {
     pub struct Subscriber;
 }
diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr
index fc47404734e..385b2ccacc1 100644
--- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr
+++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr
@@ -4,7 +4,6 @@ error: unclosed quote string `"`
 LL | / /// ```{class="}
 LL | | /// main;
 LL | | /// ```
-LL | |
 ...  |
 LL | | /// main;
 LL | | /// ```
@@ -23,7 +22,6 @@ error: unclosed quote string `"`
 LL | / /// ```{class="}
 LL | | /// main;
 LL | | /// ```
-LL | |
 ...  |
 LL | | /// main;
 LL | | /// ```
diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs
new file mode 100644
index 00000000000..8cdd665ff69
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs
@@ -0,0 +1,15 @@
+//@ compile-flags:--test --test-args --test-threads=1
+//@ failure-status: 101
+//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
+
+//! ```
+#![doc = "#![all\
+ow(unused)]"]
+//! ```
+//!
+//! ```
+#![doc = r#"#![all\
+ow(unused)]"#]
+//! ```
diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout
new file mode 100644
index 00000000000..0baff3df144
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout
@@ -0,0 +1,31 @@
+
+running 2 tests
+test $DIR/comment-in-attr-134221-2.rs - (line 11) ... FAILED
+test $DIR/comment-in-attr-134221-2.rs - (line 7) ... ok
+
+failures:
+
+---- $DIR/comment-in-attr-134221-2.rs - (line 11) stdout ----
+error: unknown start of token: \
+  --> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL
+   |
+LL | #![all\
+   |       ^
+
+error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `ow`
+  --> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL
+   |
+LL | #![all\
+   |       - expected one of `(`, `::`, `=`, `[`, `]`, or `{`
+LL | ow(unused)]
+   | ^^ unexpected token
+
+error: aborting due to 2 previous errors
+
+Couldn't compile the test.
+
+failures:
+    $DIR/comment-in-attr-134221-2.rs - (line 11)
+
+test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs
new file mode 100644
index 00000000000..3689ebe166a
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs
@@ -0,0 +1,27 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/134221>.
+// It checks that even if there are comments in the attributes, the attributes
+// will still be generated correctly (and therefore fail in this test).
+
+//@ compile-flags:--test --test-args --test-threads=1
+//@ failure-status: 101
+//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
+
+/*!
+```rust
+#![feature(
+  foo, //
+)]
+```
+
+```rust
+#![feature(
+  foo,
+)]
+```
+
+```rust
+#![
+```
+*/
diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout
new file mode 100644
index 00000000000..aa1b27d1f0b
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout
@@ -0,0 +1,50 @@
+
+running 3 tests
+test $DIR/comment-in-attr-134221.rs - (line 11) ... FAILED
+test $DIR/comment-in-attr-134221.rs - (line 17) ... FAILED
+test $DIR/comment-in-attr-134221.rs - (line 23) ... FAILED
+
+failures:
+
+---- $DIR/comment-in-attr-134221.rs - (line 11) stdout ----
+error[E0635]: unknown feature `foo`
+  --> $DIR/comment-in-attr-134221.rs:$LINE:$COL
+   |
+LL |   foo, //
+   |   ^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0635`.
+Couldn't compile the test.
+---- $DIR/comment-in-attr-134221.rs - (line 17) stdout ----
+error[E0635]: unknown feature `foo`
+  --> $DIR/comment-in-attr-134221.rs:$LINE:$COL
+   |
+LL |   foo,
+   |   ^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0635`.
+Couldn't compile the test.
+---- $DIR/comment-in-attr-134221.rs - (line 23) stdout ----
+error: this file contains an unclosed delimiter
+  --> $DIR/comment-in-attr-134221.rs:$LINE:$COL
+   |
+LL | #![
+   |   -^
+   |   |
+   |   unclosed delimiter
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+
+failures:
+    $DIR/comment-in-attr-134221.rs - (line 11)
+    $DIR/comment-in-attr-134221.rs - (line 17)
+    $DIR/comment-in-attr-134221.rs - (line 23)
+
+test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
index 06a1cf6b118..f9080bf0785 100644
--- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
+++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
@@ -308,19 +308,12 @@ LL |    pub trait SVec: Index<
    | |            |
    | |            this trait cannot be made into an object...
 LL | |      <Self as SVec>::Item,
-LL | |
-LL | |
 ...  |
 LL | |/     Output = <Index<<Self as SVec>::Item,
-LL | ||
-LL | ||
-LL | ||
 ...  ||
-LL | ||
 LL | ||     Output = <Self as SVec>::Item> as SVec>::Item,
    | ||_________________________________________________^ ...because it uses `Self` as a type parameter
 ...  |
-LL | |
 LL | |  > {
    | |__^ ...because it uses `Self` as a type parameter
 help: consider using an opaque type instead
diff --git a/tests/rustdoc-ui/lints/check-attr.stderr b/tests/rustdoc-ui/lints/check-attr.stderr
index e23806e0bab..3366c021727 100644
--- a/tests/rustdoc-ui/lints/check-attr.stderr
+++ b/tests/rustdoc-ui/lints/check-attr.stderr
@@ -2,9 +2,6 @@ error: unknown attribute `compile-fail`
   --> $DIR/check-attr.rs:3:1
    |
 LL | / /// foo
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -22,9 +19,6 @@ error: unknown attribute `compilefail`
   --> $DIR/check-attr.rs:3:1
    |
 LL | / /// foo
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -37,9 +31,6 @@ error: unknown attribute `comPile_fail`
   --> $DIR/check-attr.rs:3:1
    |
 LL | / /// foo
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -52,9 +43,6 @@ error: unknown attribute `should-panic`
   --> $DIR/check-attr.rs:13:1
    |
 LL | / /// bar
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -67,9 +55,6 @@ error: unknown attribute `shouldpanic`
   --> $DIR/check-attr.rs:13:1
    |
 LL | / /// bar
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -82,9 +67,6 @@ error: unknown attribute `sHould_panic`
   --> $DIR/check-attr.rs:13:1
    |
 LL | / /// bar
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -97,9 +79,6 @@ error: unknown attribute `no-run`
   --> $DIR/check-attr.rs:23:1
    |
 LL | / /// foobar
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -112,9 +91,6 @@ error: unknown attribute `norun`
   --> $DIR/check-attr.rs:23:1
    |
 LL | / /// foobar
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -127,9 +103,6 @@ error: unknown attribute `no_Run`
   --> $DIR/check-attr.rs:23:1
    |
 LL | / /// foobar
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -142,9 +115,6 @@ error: unknown attribute `test-harness`
   --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -157,9 +127,6 @@ error: unknown attribute `testharness`
   --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
@@ -172,9 +139,6 @@ error: unknown attribute `teSt_harness`
   --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | /// boo
 LL | | /// ```
diff --git a/tests/rustdoc-ui/lints/check.stderr b/tests/rustdoc-ui/lints/check.stderr
index f1f36e8830d..dcdf25dda64 100644
--- a/tests/rustdoc-ui/lints/check.stderr
+++ b/tests/rustdoc-ui/lints/check.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |
 LL | | #![warn(missing_docs)]
 ...  |
-LL | |
 LL | | pub fn foo() {}
    | |_______________^
    |
diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr
index 1e2b3528d4a..d93aaf5f3ca 100644
--- a/tests/rustdoc-ui/unescaped_backticks.stderr
+++ b/tests/rustdoc-ui/unescaped_backticks.stderr
@@ -271,9 +271,6 @@ error: unescaped backtick
   --> $DIR/unescaped_backticks.rs:323:5
    |
 LL | /     /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
 LL | |     /// level changes.
@@ -290,9 +287,6 @@ error: unescaped backtick
   --> $DIR/unescaped_backticks.rs:323:5
    |
 LL | /     /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
 LL | |     /// level changes.
@@ -307,9 +301,6 @@ error: unescaped backtick
   --> $DIR/unescaped_backticks.rs:323:5
    |
 LL | /     /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
 LL | |     /// level changes.
@@ -326,9 +317,6 @@ error: unescaped backtick
   --> $DIR/unescaped_backticks.rs:323:5
    |
 LL | /     /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
 LL | |     /// level changes.
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/alias-uninit-value.rs b/tests/ui/alias-uninit-value.rs
deleted file mode 100644
index 0084a98e627..00000000000
--- a/tests/ui/alias-uninit-value.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//@ run-pass
-
-#![allow(non_camel_case_types)]
-#![allow(dead_code)]
-
-
-
-// Regression test for issue #374
-
-
-enum sty { ty_nil, }
-
-struct RawT {struct_: sty, cname: Option<String>, hash: usize}
-
-fn mk_raw_ty(st: sty, cname: Option<String>) -> RawT {
-    return RawT {struct_: st, cname: cname, hash: 0};
-}
-
-pub fn main() { mk_raw_ty(sty::ty_nil, None::<String>); }
diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr
index de92841d7f1..80ff10e13d8 100644
--- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr
+++ b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr
@@ -7,8 +7,7 @@ LL | // fn oom(
 LL | ||     info: &Layout,
 LL | || ) -> ()
    | ||_______- arguments to this function are incorrect
-LL | |  {
-LL | |      loop {}
+...  |
 LL | |  }
    | |__^ expected `&Layout`, found `Layout`
    |
@@ -30,8 +29,7 @@ LL | // fn oom(
 LL | ||     info: &Layout,
 LL | || ) -> ()
    | ||_______^ expected `!`, found `()`
-LL | |  {
-LL | |      loop {}
+...  |
 LL | |  }
    | |__- expected `!` because of return type
    |
diff --git a/tests/ui/allow-non-lint-warnings.rs b/tests/ui/allow-non-lint-warnings.rs
deleted file mode 100644
index f8f5a78ebff..00000000000
--- a/tests/ui/allow-non-lint-warnings.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ compile-flags: -Awarnings
-//@ check-pass
-
-#[derive()]
-#[derive(Copy, Clone)]
-pub struct Foo;
-
-pub fn main() {}
diff --git a/tests/ui/artificial-block.rs b/tests/ui/artificial-block.rs
deleted file mode 100644
index 037163b4174..00000000000
--- a/tests/ui/artificial-block.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ run-pass
-
-fn f() -> isize { { return 3; } }
-
-pub fn main() { assert_eq!(f(), 3); }
diff --git a/tests/ui/as-precedence.rs b/tests/ui/as-precedence.rs
deleted file mode 100644
index 5021a3b677f..00000000000
--- a/tests/ui/as-precedence.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-pass
-
-#[allow(unused_parens)]
-fn main() {
-    assert_eq!(3 as usize * 3, 9);
-    assert_eq!(3 as (usize) * 3, 9);
-    assert_eq!(3 as (usize) / 3, 1);
-    assert_eq!(3 as usize + 3, 6);
-    assert_eq!(3 as (usize) + 3, 6);
-}
diff --git a/tests/ui/asm/aarch64/srcloc.new.stderr b/tests/ui/asm/aarch64/srcloc.new.stderr
new file mode 100644
index 00000000000..b92a07e5fb1
--- /dev/null
+++ b/tests/ui/asm/aarch64/srcloc.new.stderr
@@ -0,0 +1,320 @@
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:15:15
+   |
+LL |         asm!("invalid_instruction");
+   |               ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:19:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:24:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:30:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:37:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:42:14
+   |
+LL |         asm!(concat!("invalid", "_", "instruction"));
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:46:14
+   |
+LL |             "invalid_instruction",
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:52:14
+   |
+LL |             "invalid_instruction",
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:59:14
+   |
+LL |             "invalid_instruction",
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:66:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:73:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:80:14
+   |
+LL |             "invalid_instruction1",
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:81:14
+   |
+LL |             "invalid_instruction2",
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:87:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:87:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:96:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:96:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:100:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction3
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:100:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction4
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:111:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:111:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:115:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction3
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:115:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:5:1
+   |
+LL | invalid_instruction4
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:128:14
+   |
+LL |             "invalid_instruction"
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: aborting due to 24 previous errors
+
diff --git a/tests/ui/asm/aarch64/srcloc.stderr b/tests/ui/asm/aarch64/srcloc.old.stderr
index 2e17b60b912..2a15e48f025 100644
--- a/tests/ui/asm/aarch64/srcloc.stderr
+++ b/tests/ui/asm/aarch64/srcloc.old.stderr
@@ -1,5 +1,5 @@
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:12:15
+  --> $DIR/srcloc.rs:15:15
    |
 LL |         asm!("invalid_instruction");
    |               ^
@@ -11,7 +11,7 @@ LL |     invalid_instruction
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:16:13
+  --> $DIR/srcloc.rs:19:13
    |
 LL |             invalid_instruction
    |             ^
@@ -23,7 +23,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:21:13
+  --> $DIR/srcloc.rs:24:13
    |
 LL |             invalid_instruction
    |             ^
@@ -35,7 +35,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:27:13
+  --> $DIR/srcloc.rs:30:13
    |
 LL |             invalid_instruction
    |             ^
@@ -47,7 +47,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:34:13
+  --> $DIR/srcloc.rs:37:13
    |
 LL |             invalid_instruction
    |             ^
@@ -59,7 +59,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:39:14
+  --> $DIR/srcloc.rs:42:14
    |
 LL |         asm!(concat!("invalid", "_", "instruction"));
    |              ^
@@ -71,7 +71,7 @@ LL |     invalid_instruction
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:43:14
+  --> $DIR/srcloc.rs:46:14
    |
 LL |             "invalid_instruction",
    |              ^
@@ -83,7 +83,7 @@ LL |     invalid_instruction
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:49:14
+  --> $DIR/srcloc.rs:52:14
    |
 LL |             "invalid_instruction",
    |              ^
@@ -95,7 +95,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:56:14
+  --> $DIR/srcloc.rs:59:14
    |
 LL |             "invalid_instruction",
    |              ^
@@ -107,7 +107,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:63:13
+  --> $DIR/srcloc.rs:66:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^
@@ -119,7 +119,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:70:13
+  --> $DIR/srcloc.rs:73:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^
@@ -131,7 +131,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:77:14
+  --> $DIR/srcloc.rs:80:14
    |
 LL |             "invalid_instruction1",
    |              ^
@@ -143,7 +143,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:78:14
+  --> $DIR/srcloc.rs:81:14
    |
 LL |             "invalid_instruction2",
    |              ^
@@ -155,7 +155,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:84:13
+  --> $DIR/srcloc.rs:87:13
    |
 LL |             concat!(
    |             ^
@@ -167,7 +167,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:84:13
+  --> $DIR/srcloc.rs:87:13
    |
 LL |             concat!(
    |             ^
@@ -179,7 +179,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:93:13
+  --> $DIR/srcloc.rs:96:13
    |
 LL |             concat!(
    |             ^
@@ -191,7 +191,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:93:13
+  --> $DIR/srcloc.rs:96:13
    |
 LL |             concat!(
    |             ^
@@ -203,7 +203,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:97:13
+  --> $DIR/srcloc.rs:100:13
    |
 LL |             concat!(
    |             ^
@@ -215,7 +215,7 @@ LL | invalid_instruction3
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:97:13
+  --> $DIR/srcloc.rs:100:13
    |
 LL |             concat!(
    |             ^
@@ -227,7 +227,7 @@ LL | invalid_instruction4
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:108:13
+  --> $DIR/srcloc.rs:111:13
    |
 LL |             concat!(
    |             ^
@@ -239,7 +239,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:108:13
+  --> $DIR/srcloc.rs:111:13
    |
 LL |             concat!(
    |             ^
@@ -251,7 +251,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:112:13
+  --> $DIR/srcloc.rs:115:13
    |
 LL |             concat!(
    |             ^
@@ -263,7 +263,7 @@ LL | invalid_instruction3
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:112:13
+  --> $DIR/srcloc.rs:115:13
    |
 LL |             concat!(
    |             ^
@@ -275,7 +275,7 @@ LL | invalid_instruction4
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:125:14
+  --> $DIR/srcloc.rs:128:14
    |
 LL |             "invalid_instruction"
    |              ^
diff --git a/tests/ui/asm/aarch64/srcloc.rs b/tests/ui/asm/aarch64/srcloc.rs
index c635fa6ba70..9b92dfef056 100644
--- a/tests/ui/asm/aarch64/srcloc.rs
+++ b/tests/ui/asm/aarch64/srcloc.rs
@@ -1,7 +1,10 @@
+//@ revisions: old new
 //@ only-aarch64
 //@ build-fail
 //@ needs-asm-support
 //@ compile-flags: -Ccodegen-units=1
+//@[old] ignore-llvm-version: 19 - 99
+//@[new] min-llvm-version: 19
 
 use std::arch::asm;
 
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/inline-syntax.arm.stderr b/tests/ui/asm/inline-syntax.arm.stderr
index 61e5078d6d9..e36ec125d13 100644
--- a/tests/ui/asm/inline-syntax.arm.stderr
+++ b/tests/ui/asm/inline-syntax.arm.stderr
@@ -15,10 +15,10 @@ LL | .intel_syntax noprefix
    | ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:29:15
+  --> $DIR/inline-syntax.rs:35:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
-   |               ^
+   |               ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:2
@@ -27,10 +27,10 @@ LL |     .intel_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:32:15
+  --> $DIR/inline-syntax.rs:39:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
-   |               ^
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:2
@@ -39,10 +39,10 @@ LL |     .intel_syntax aaa noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:35:15
+  --> $DIR/inline-syntax.rs:43:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
-   |               ^
+   |               ^^^^^^^^^^^^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:2
@@ -51,10 +51,10 @@ LL |     .att_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:38:15
+  --> $DIR/inline-syntax.rs:47:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
-   |               ^
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:2
@@ -63,10 +63,10 @@ LL |     .att_syntax bbb noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:41:15
+  --> $DIR/inline-syntax.rs:51:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
-   |               ^
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:2
@@ -75,10 +75,10 @@ LL |     .intel_syntax noprefix; nop
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:47:13
+  --> $DIR/inline-syntax.rs:58:13
    |
 LL |             .intel_syntax noprefix
-   |             ^
+   |             ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:2:13
diff --git a/tests/ui/asm/inline-syntax.arm_llvm_18.stderr b/tests/ui/asm/inline-syntax.arm_llvm_18.stderr
new file mode 100644
index 00000000000..ada3f4891d3
--- /dev/null
+++ b/tests/ui/asm/inline-syntax.arm_llvm_18.stderr
@@ -0,0 +1,90 @@
+error: unknown directive
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:1
+   |
+LL | .intel_syntax noprefix
+   | ^
+
+error: unknown directive
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:1
+   |
+LL | .intel_syntax noprefix
+   | ^
+
+error: unknown directive
+  --> $DIR/inline-syntax.rs:35:15
+   |
+LL |         asm!(".intel_syntax noprefix", "nop");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     .intel_syntax noprefix
+   |     ^
+
+error: unknown directive
+  --> $DIR/inline-syntax.rs:39:15
+   |
+LL |         asm!(".intel_syntax aaa noprefix", "nop");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     .intel_syntax aaa noprefix
+   |     ^
+
+error: unknown directive
+  --> $DIR/inline-syntax.rs:43:15
+   |
+LL |         asm!(".att_syntax noprefix", "nop");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     .att_syntax noprefix
+   |     ^
+
+error: unknown directive
+  --> $DIR/inline-syntax.rs:47:15
+   |
+LL |         asm!(".att_syntax bbb noprefix", "nop");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     .att_syntax bbb noprefix
+   |     ^
+
+error: unknown directive
+  --> $DIR/inline-syntax.rs:51:15
+   |
+LL |         asm!(".intel_syntax noprefix; nop");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     .intel_syntax noprefix; nop
+   |     ^
+
+error: unknown directive
+  --> $DIR/inline-syntax.rs:58:13
+   |
+LL |             .intel_syntax noprefix
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:13
+   |
+LL |             .intel_syntax noprefix
+   |             ^
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/asm/inline-syntax.rs b/tests/ui/asm/inline-syntax.rs
index b8486527e6f..fda79b2afa3 100644
--- a/tests/ui/asm/inline-syntax.rs
+++ b/tests/ui/asm/inline-syntax.rs
@@ -1,10 +1,16 @@
-//@ revisions: x86_64 arm
+//@ revisions: x86_64 arm_llvm_18 arm
 //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
 //@[x86_64] check-pass
 //@[x86_64] needs-llvm-components: x86
+//@[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
+//@[arm_llvm_18] build-fail
+//@[arm_llvm_18] needs-llvm-components: arm
+//@[arm_llvm_18] ignore-llvm-version: 19 - 99
+// LLVM 19+ has full support for 64-bit cookies.
 //@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
 //@[arm] build-fail
 //@[arm] needs-llvm-components: arm
+//@[arm] min-llvm-version: 19
 //@ needs-asm-support
 
 #![feature(no_core, lang_items, rustc_attrs)]
@@ -29,18 +35,23 @@ pub fn main() {
         asm!(".intel_syntax noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
+        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".intel_syntax aaa noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
+        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".att_syntax noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.att_syntax`
         //[arm]~^^ ERROR unknown directive
+        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".att_syntax bbb noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.att_syntax`
         //[arm]~^^ ERROR unknown directive
+        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".intel_syntax noprefix; nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
+        //[arm_llvm_18]~^^^ ERROR unknown directive
 
         asm!(
             r"
@@ -49,9 +60,10 @@ pub fn main() {
         );
         //[x86_64]~^^^ WARN avoid using `.intel_syntax`
         //[arm]~^^^^ ERROR unknown directive
+        //[arm_llvm_18]~^^^^^ ERROR unknown directive
     }
 }
 
 global_asm!(".intel_syntax noprefix", "nop");
 //[x86_64]~^ WARN avoid using `.intel_syntax`
-// Assembler errors don't have line numbers, so no error on ARM
+// Global assembly errors don't have line numbers, so no error on ARM.
diff --git a/tests/ui/asm/inline-syntax.x86_64.stderr b/tests/ui/asm/inline-syntax.x86_64.stderr
index 59c95194322..66dc37f3089 100644
--- a/tests/ui/asm/inline-syntax.x86_64.stderr
+++ b/tests/ui/asm/inline-syntax.x86_64.stderr
@@ -1,5 +1,5 @@
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:55:14
+  --> $DIR/inline-syntax.rs:67:14
    |
 LL | global_asm!(".intel_syntax noprefix", "nop");
    |              ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop");
    = note: `#[warn(bad_asm_style)]` on by default
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:29:15
+  --> $DIR/inline-syntax.rs:35:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:32:15
+  --> $DIR/inline-syntax.rs:39:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:35:15
+  --> $DIR/inline-syntax.rs:43:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:38:15
+  --> $DIR/inline-syntax.rs:47:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:41:15
+  --> $DIR/inline-syntax.rs:51:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:47:13
+  --> $DIR/inline-syntax.rs:58:13
    |
 LL |             .intel_syntax noprefix
    |             ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs
index 37c7b52c191..3a6e7a46ce5 100644
--- a/tests/ui/asm/naked-functions-instruction-set.rs
+++ b/tests/ui/asm/naked-functions-instruction-set.rs
@@ -24,7 +24,7 @@ unsafe extern "C" fn test_thumb() {
 
 #[no_mangle]
 #[naked]
-#[instruction_set(arm::t32)]
+#[instruction_set(arm::a32)]
 unsafe extern "C" fn test_arm() {
     naked_asm!("bx lr");
 }
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/asm/riscv/riscv32e-registers.riscv32e.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr
index e7a86805b26..ac1373f0e2d 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr
@@ -1,8 +1,8 @@
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:46:11
+  --> $DIR/riscv32e-registers.rs:58:11
    |
 LL |     asm!("li x16, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -11,10 +11,10 @@ LL |     li x16, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:49:11
+  --> $DIR/riscv32e-registers.rs:61:11
    |
 LL |     asm!("li x17, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -23,10 +23,10 @@ LL |     li x17, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:52:11
+  --> $DIR/riscv32e-registers.rs:64:11
    |
 LL |     asm!("li x18, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -35,10 +35,10 @@ LL |     li x18, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:55:11
+  --> $DIR/riscv32e-registers.rs:67:11
    |
 LL |     asm!("li x19, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -47,10 +47,10 @@ LL |     li x19, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:58:11
+  --> $DIR/riscv32e-registers.rs:70:11
    |
 LL |     asm!("li x20, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -59,10 +59,10 @@ LL |     li x20, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:61:11
+  --> $DIR/riscv32e-registers.rs:73:11
    |
 LL |     asm!("li x21, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -71,10 +71,10 @@ LL |     li x21, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:64:11
+  --> $DIR/riscv32e-registers.rs:76:11
    |
 LL |     asm!("li x22, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -83,10 +83,10 @@ LL |     li x22, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:67:11
+  --> $DIR/riscv32e-registers.rs:79:11
    |
 LL |     asm!("li x23, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -95,10 +95,10 @@ LL |     li x23, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:70:11
+  --> $DIR/riscv32e-registers.rs:82:11
    |
 LL |     asm!("li x24, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -107,10 +107,10 @@ LL |     li x24, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:73:11
+  --> $DIR/riscv32e-registers.rs:85:11
    |
 LL |     asm!("li x25, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -119,10 +119,10 @@ LL |     li x25, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:76:11
+  --> $DIR/riscv32e-registers.rs:88:11
    |
 LL |     asm!("li x26, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -131,10 +131,10 @@ LL |     li x26, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:79:11
+  --> $DIR/riscv32e-registers.rs:91:11
    |
 LL |     asm!("li x27, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -143,10 +143,10 @@ LL |     li x27, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:82:11
+  --> $DIR/riscv32e-registers.rs:94:11
    |
 LL |     asm!("li x28, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -155,10 +155,10 @@ LL |     li x28, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:85:11
+  --> $DIR/riscv32e-registers.rs:97:11
    |
 LL |     asm!("li x29, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -167,10 +167,10 @@ LL |     li x29, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:88:11
+  --> $DIR/riscv32e-registers.rs:100:11
    |
 LL |     asm!("li x30, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -179,10 +179,10 @@ LL |     li x30, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:91:11
+  --> $DIR/riscv32e-registers.rs:103:11
    |
 LL |     asm!("li x31, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr
new file mode 100644
index 00000000000..f140f54adc5
--- /dev/null
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr
@@ -0,0 +1,194 @@
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:58:11
+   |
+LL |     asm!("li x16, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x16, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:61:11
+   |
+LL |     asm!("li x17, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x17, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:64:11
+   |
+LL |     asm!("li x18, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x18, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:67:11
+   |
+LL |     asm!("li x19, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x19, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:70:11
+   |
+LL |     asm!("li x20, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x20, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:73:11
+   |
+LL |     asm!("li x21, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x21, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:76:11
+   |
+LL |     asm!("li x22, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x22, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:79:11
+   |
+LL |     asm!("li x23, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x23, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:82:11
+   |
+LL |     asm!("li x24, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x24, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:85:11
+   |
+LL |     asm!("li x25, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x25, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:88:11
+   |
+LL |     asm!("li x26, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x26, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:91:11
+   |
+LL |     asm!("li x27, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x27, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:94:11
+   |
+LL |     asm!("li x28, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x28, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:97:11
+   |
+LL |     asm!("li x29, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x29, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:100:11
+   |
+LL |     asm!("li x30, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x30, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:103:11
+   |
+LL |     asm!("li x31, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x31, 0
+   |        ^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr
index e7a86805b26..ac1373f0e2d 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr
@@ -1,8 +1,8 @@
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:46:11
+  --> $DIR/riscv32e-registers.rs:58:11
    |
 LL |     asm!("li x16, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -11,10 +11,10 @@ LL |     li x16, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:49:11
+  --> $DIR/riscv32e-registers.rs:61:11
    |
 LL |     asm!("li x17, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -23,10 +23,10 @@ LL |     li x17, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:52:11
+  --> $DIR/riscv32e-registers.rs:64:11
    |
 LL |     asm!("li x18, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -35,10 +35,10 @@ LL |     li x18, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:55:11
+  --> $DIR/riscv32e-registers.rs:67:11
    |
 LL |     asm!("li x19, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -47,10 +47,10 @@ LL |     li x19, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:58:11
+  --> $DIR/riscv32e-registers.rs:70:11
    |
 LL |     asm!("li x20, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -59,10 +59,10 @@ LL |     li x20, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:61:11
+  --> $DIR/riscv32e-registers.rs:73:11
    |
 LL |     asm!("li x21, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -71,10 +71,10 @@ LL |     li x21, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:64:11
+  --> $DIR/riscv32e-registers.rs:76:11
    |
 LL |     asm!("li x22, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -83,10 +83,10 @@ LL |     li x22, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:67:11
+  --> $DIR/riscv32e-registers.rs:79:11
    |
 LL |     asm!("li x23, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -95,10 +95,10 @@ LL |     li x23, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:70:11
+  --> $DIR/riscv32e-registers.rs:82:11
    |
 LL |     asm!("li x24, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -107,10 +107,10 @@ LL |     li x24, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:73:11
+  --> $DIR/riscv32e-registers.rs:85:11
    |
 LL |     asm!("li x25, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -119,10 +119,10 @@ LL |     li x25, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:76:11
+  --> $DIR/riscv32e-registers.rs:88:11
    |
 LL |     asm!("li x26, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -131,10 +131,10 @@ LL |     li x26, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:79:11
+  --> $DIR/riscv32e-registers.rs:91:11
    |
 LL |     asm!("li x27, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -143,10 +143,10 @@ LL |     li x27, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:82:11
+  --> $DIR/riscv32e-registers.rs:94:11
    |
 LL |     asm!("li x28, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -155,10 +155,10 @@ LL |     li x28, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:85:11
+  --> $DIR/riscv32e-registers.rs:97:11
    |
 LL |     asm!("li x29, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -167,10 +167,10 @@ LL |     li x29, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:88:11
+  --> $DIR/riscv32e-registers.rs:100:11
    |
 LL |     asm!("li x30, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -179,10 +179,10 @@ LL |     li x30, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:91:11
+  --> $DIR/riscv32e-registers.rs:103:11
    |
 LL |     asm!("li x31, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr
new file mode 100644
index 00000000000..f140f54adc5
--- /dev/null
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr
@@ -0,0 +1,194 @@
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:58:11
+   |
+LL |     asm!("li x16, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x16, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:61:11
+   |
+LL |     asm!("li x17, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x17, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:64:11
+   |
+LL |     asm!("li x18, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x18, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:67:11
+   |
+LL |     asm!("li x19, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x19, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:70:11
+   |
+LL |     asm!("li x20, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x20, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:73:11
+   |
+LL |     asm!("li x21, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x21, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:76:11
+   |
+LL |     asm!("li x22, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x22, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:79:11
+   |
+LL |     asm!("li x23, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x23, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:82:11
+   |
+LL |     asm!("li x24, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x24, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:85:11
+   |
+LL |     asm!("li x25, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x25, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:88:11
+   |
+LL |     asm!("li x26, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x26, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:91:11
+   |
+LL |     asm!("li x27, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x27, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:94:11
+   |
+LL |     asm!("li x28, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x28, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:97:11
+   |
+LL |     asm!("li x29, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x29, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:100:11
+   |
+LL |     asm!("li x30, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x30, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:103:11
+   |
+LL |     asm!("li x31, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x31, 0
+   |        ^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr
index e7a86805b26..ac1373f0e2d 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr
@@ -1,8 +1,8 @@
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:46:11
+  --> $DIR/riscv32e-registers.rs:58:11
    |
 LL |     asm!("li x16, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -11,10 +11,10 @@ LL |     li x16, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:49:11
+  --> $DIR/riscv32e-registers.rs:61:11
    |
 LL |     asm!("li x17, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -23,10 +23,10 @@ LL |     li x17, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:52:11
+  --> $DIR/riscv32e-registers.rs:64:11
    |
 LL |     asm!("li x18, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -35,10 +35,10 @@ LL |     li x18, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:55:11
+  --> $DIR/riscv32e-registers.rs:67:11
    |
 LL |     asm!("li x19, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -47,10 +47,10 @@ LL |     li x19, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:58:11
+  --> $DIR/riscv32e-registers.rs:70:11
    |
 LL |     asm!("li x20, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -59,10 +59,10 @@ LL |     li x20, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:61:11
+  --> $DIR/riscv32e-registers.rs:73:11
    |
 LL |     asm!("li x21, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -71,10 +71,10 @@ LL |     li x21, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:64:11
+  --> $DIR/riscv32e-registers.rs:76:11
    |
 LL |     asm!("li x22, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -83,10 +83,10 @@ LL |     li x22, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:67:11
+  --> $DIR/riscv32e-registers.rs:79:11
    |
 LL |     asm!("li x23, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -95,10 +95,10 @@ LL |     li x23, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:70:11
+  --> $DIR/riscv32e-registers.rs:82:11
    |
 LL |     asm!("li x24, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -107,10 +107,10 @@ LL |     li x24, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:73:11
+  --> $DIR/riscv32e-registers.rs:85:11
    |
 LL |     asm!("li x25, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -119,10 +119,10 @@ LL |     li x25, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:76:11
+  --> $DIR/riscv32e-registers.rs:88:11
    |
 LL |     asm!("li x26, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -131,10 +131,10 @@ LL |     li x26, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:79:11
+  --> $DIR/riscv32e-registers.rs:91:11
    |
 LL |     asm!("li x27, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -143,10 +143,10 @@ LL |     li x27, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:82:11
+  --> $DIR/riscv32e-registers.rs:94:11
    |
 LL |     asm!("li x28, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -155,10 +155,10 @@ LL |     li x28, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:85:11
+  --> $DIR/riscv32e-registers.rs:97:11
    |
 LL |     asm!("li x29, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -167,10 +167,10 @@ LL |     li x29, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:88:11
+  --> $DIR/riscv32e-registers.rs:100:11
    |
 LL |     asm!("li x30, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
@@ -179,10 +179,10 @@ LL |     li x30, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:91:11
+  --> $DIR/riscv32e-registers.rs:103:11
    |
 LL |     asm!("li x31, 0");
-   |           ^
+   |           ^^^^^^^^^
    |
 note: instantiated into assembly here
   --> <inline asm>:1:5
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr
new file mode 100644
index 00000000000..f140f54adc5
--- /dev/null
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr
@@ -0,0 +1,194 @@
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:58:11
+   |
+LL |     asm!("li x16, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x16, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:61:11
+   |
+LL |     asm!("li x17, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x17, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:64:11
+   |
+LL |     asm!("li x18, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x18, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:67:11
+   |
+LL |     asm!("li x19, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x19, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:70:11
+   |
+LL |     asm!("li x20, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x20, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:73:11
+   |
+LL |     asm!("li x21, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x21, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:76:11
+   |
+LL |     asm!("li x22, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x22, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:79:11
+   |
+LL |     asm!("li x23, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x23, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:82:11
+   |
+LL |     asm!("li x24, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x24, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:85:11
+   |
+LL |     asm!("li x25, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x25, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:88:11
+   |
+LL |     asm!("li x26, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x26, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:91:11
+   |
+LL |     asm!("li x27, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x27, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:94:11
+   |
+LL |     asm!("li x28, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x28, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:97:11
+   |
+LL |     asm!("li x29, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x29, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:100:11
+   |
+LL |     asm!("li x30, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x30, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:103:11
+   |
+LL |     asm!("li x31, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x31, 0
+   |        ^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/asm/riscv/riscv32e-registers.rs b/tests/ui/asm/riscv/riscv32e-registers.rs
index 57b1e169a04..c3fe19991b0 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.rs
+++ b/tests/ui/asm/riscv/riscv32e-registers.rs
@@ -1,15 +1,27 @@
 // Test that loads into registers x16..=x31 are never generated for riscv32{e,em,emc} targets
 //
 //@ build-fail
-//@ revisions: riscv32e riscv32em riscv32emc
+//@ revisions: riscv32e riscv32em riscv32emc riscv32e_llvm_18 riscv32em_llvm_18 riscv32emc_llvm_18
 //
 //@ compile-flags: --crate-type=rlib
 //@ [riscv32e] needs-llvm-components: riscv
 //@ [riscv32e] compile-flags: --target=riscv32e-unknown-none-elf
+//@ [riscv32e] min-llvm-version: 19
 //@ [riscv32em] needs-llvm-components: riscv
 //@ [riscv32em] compile-flags: --target=riscv32em-unknown-none-elf
+//@ [riscv32em] min-llvm-version: 19
 //@ [riscv32emc] needs-llvm-components: riscv
 //@ [riscv32emc] compile-flags: --target=riscv32emc-unknown-none-elf
+//@ [riscv32emc] min-llvm-version: 19
+//@ [riscv32e_llvm_18] needs-llvm-components: riscv
+//@ [riscv32e_llvm_18] compile-flags: --target=riscv32e-unknown-none-elf
+//@ [riscv32e_llvm_18] ignore-llvm-version: 19 - 99
+//@ [riscv32em_llvm_18] needs-llvm-components: riscv
+//@ [riscv32em_llvm_18] compile-flags: --target=riscv32em-unknown-none-elf
+//@ [riscv32em_llvm_18] ignore-llvm-version: 19 - 99
+//@ [riscv32emc_llvm_18] needs-llvm-components: riscv
+//@ [riscv32emc_llvm_18] compile-flags: --target=riscv32emc-unknown-none-elf
+//@ [riscv32emc_llvm_18] ignore-llvm-version: 19 - 99
 
 // Unlike bad-reg.rs, this tests if the assembler can reject invalid registers
 // usage in assembly code.
diff --git a/tests/ui/asm/x86_64/srcloc.new.stderr b/tests/ui/asm/x86_64/srcloc.new.stderr
new file mode 100644
index 00000000000..7211f1ab69d
--- /dev/null
+++ b/tests/ui/asm/x86_64/srcloc.new.stderr
@@ -0,0 +1,332 @@
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:14:15
+   |
+LL |         asm!("invalid_instruction");
+   |               ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:18:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:23:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:29:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:36:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:41:14
+   |
+LL |         asm!(concat!("invalid", "_", "instruction"));
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+warning: scale factor without index register is ignored
+  --> $DIR/srcloc.rs:44:15
+   |
+LL |         asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
+   |               ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:23
+   |
+LL |     movaps %xmm3, (%esi, 2)
+   |                          ^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:48:14
+   |
+LL |             "invalid_instruction",
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:54:14
+   |
+LL |             "invalid_instruction",
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:61:14
+   |
+LL |             "invalid_instruction",
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:68:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:75:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:82:14
+   |
+LL |             "invalid_instruction1",
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:83:14
+   |
+LL |             "invalid_instruction2",
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:89:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:89:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:98:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:98:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction3'
+  --> $DIR/srcloc.rs:102:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction3
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction4'
+  --> $DIR/srcloc.rs:102:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:5:1
+   |
+LL | invalid_instruction4
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:113:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:113:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction1", "\n",
+LL | |                 "invalid", "_", "instruction2", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction3'
+  --> $DIR/srcloc.rs:117:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:5:1
+   |
+LL | invalid_instruction3
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction4'
+  --> $DIR/srcloc.rs:117:13
+   |
+LL | /             concat!(
+LL | |                 "invalid", "_", "instruction3", "\n",
+LL | |                 "invalid", "_", "instruction4", "\n",
+LL | |             ),
+   | |_____________^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:6:1
+   |
+LL | invalid_instruction4
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:130:14
+   |
+LL |             "invalid_instruction"
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:5:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 24 previous errors; 1 warning emitted
+
diff --git a/tests/ui/asm/x86_64/srcloc.stderr b/tests/ui/asm/x86_64/srcloc.old.stderr
index 8899c1b916b..edb9ee46812 100644
--- a/tests/ui/asm/x86_64/srcloc.stderr
+++ b/tests/ui/asm/x86_64/srcloc.old.stderr
@@ -1,5 +1,5 @@
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:11:15
+  --> $DIR/srcloc.rs:14:15
    |
 LL |         asm!("invalid_instruction");
    |               ^
@@ -11,7 +11,7 @@ LL |     invalid_instruction
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:15:13
+  --> $DIR/srcloc.rs:18:13
    |
 LL |             invalid_instruction
    |             ^
@@ -23,7 +23,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:20:13
+  --> $DIR/srcloc.rs:23:13
    |
 LL |             invalid_instruction
    |             ^
@@ -35,7 +35,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:26:13
+  --> $DIR/srcloc.rs:29:13
    |
 LL |             invalid_instruction
    |             ^
@@ -47,7 +47,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:33:13
+  --> $DIR/srcloc.rs:36:13
    |
 LL |             invalid_instruction
    |             ^
@@ -59,7 +59,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:38:14
+  --> $DIR/srcloc.rs:41:14
    |
 LL |         asm!(concat!("invalid", "_", "instruction"));
    |              ^
@@ -71,7 +71,7 @@ LL |     invalid_instruction
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: scale factor without index register is ignored
-  --> $DIR/srcloc.rs:41:15
+  --> $DIR/srcloc.rs:44:15
    |
 LL |         asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
    |               ^
@@ -83,7 +83,7 @@ LL |     movaps %xmm3, (%esi, 2)
    |                          ^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:45:14
+  --> $DIR/srcloc.rs:48:14
    |
 LL |             "invalid_instruction",
    |              ^
@@ -95,7 +95,7 @@ LL |     invalid_instruction
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:51:14
+  --> $DIR/srcloc.rs:54:14
    |
 LL |             "invalid_instruction",
    |              ^
@@ -107,7 +107,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:58:14
+  --> $DIR/srcloc.rs:61:14
    |
 LL |             "invalid_instruction",
    |              ^
@@ -119,7 +119,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:65:13
+  --> $DIR/srcloc.rs:68:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^
@@ -131,7 +131,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:72:13
+  --> $DIR/srcloc.rs:75:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^
@@ -143,7 +143,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:79:14
+  --> $DIR/srcloc.rs:82:14
    |
 LL |             "invalid_instruction1",
    |              ^
@@ -155,7 +155,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:80:14
+  --> $DIR/srcloc.rs:83:14
    |
 LL |             "invalid_instruction2",
    |              ^
@@ -167,7 +167,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:86:13
+  --> $DIR/srcloc.rs:89:13
    |
 LL |             concat!(
    |             ^
@@ -179,7 +179,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:86:13
+  --> $DIR/srcloc.rs:89:13
    |
 LL |             concat!(
    |             ^
@@ -191,7 +191,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:95:13
+  --> $DIR/srcloc.rs:98:13
    |
 LL |             concat!(
    |             ^
@@ -203,7 +203,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:95:13
+  --> $DIR/srcloc.rs:98:13
    |
 LL |             concat!(
    |             ^
@@ -215,7 +215,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:99:13
+  --> $DIR/srcloc.rs:102:13
    |
 LL |             concat!(
    |             ^
@@ -227,7 +227,7 @@ LL | invalid_instruction3
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:99:13
+  --> $DIR/srcloc.rs:102:13
    |
 LL |             concat!(
    |             ^
@@ -239,7 +239,7 @@ LL | invalid_instruction4
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:110:13
+  --> $DIR/srcloc.rs:113:13
    |
 LL |             concat!(
    |             ^
@@ -251,7 +251,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:110:13
+  --> $DIR/srcloc.rs:113:13
    |
 LL |             concat!(
    |             ^
@@ -263,7 +263,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:114:13
+  --> $DIR/srcloc.rs:117:13
    |
 LL |             concat!(
    |             ^
@@ -275,7 +275,7 @@ LL | invalid_instruction3
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:114:13
+  --> $DIR/srcloc.rs:117:13
    |
 LL |             concat!(
    |             ^
@@ -287,7 +287,7 @@ LL | invalid_instruction4
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:127:14
+  --> $DIR/srcloc.rs:130:14
    |
 LL |             "invalid_instruction"
    |              ^
diff --git a/tests/ui/asm/x86_64/srcloc.rs b/tests/ui/asm/x86_64/srcloc.rs
index 2938bafe5e7..40fc66cbc92 100644
--- a/tests/ui/asm/x86_64/srcloc.rs
+++ b/tests/ui/asm/x86_64/srcloc.rs
@@ -1,6 +1,9 @@
+//@ revisions: old new
 //@ only-x86_64
 //@ build-fail
 //@ compile-flags: -Ccodegen-units=1
+//@[old] ignore-llvm-version: 19 - 99
+//@[new] min-llvm-version: 19
 
 use std::arch::asm;
 
diff --git a/tests/ui/associated-consts/issue-93775.rs b/tests/ui/associated-consts/issue-93775.rs
index c9044e27e0e..d7416d03707 100644
--- a/tests/ui/associated-consts/issue-93775.rs
+++ b/tests/ui/associated-consts/issue-93775.rs
@@ -1,3 +1,7 @@
+//@ ignore-windows-msvc
+// FIXME(#132111, #133432): this test is flaky on windows msvc, it sometimes fail but it sometimes
+// passes.
+
 //@ build-pass
 // ignore-tidy-linelength
 
diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr
index e5013a35d45..ccd13123d70 100644
--- a/tests/ui/associated-types/associated-types-eq-2.stderr
+++ b/tests/ui/associated-types/associated-types-eq-2.stderr
@@ -3,8 +3,7 @@ error[E0658]: associated const equality is incomplete
    |
 LL |   impl Tr3<N
    |  __________^
-LL | |
-LL | |
+...  |
 LL | | = 42, T2 = Qux, T3 = usize> for Bar {
    | |____^
    |
@@ -198,8 +197,7 @@ error[E0229]: associated item constraints are not allowed here
    |
 LL |   impl Tr3<N
    |  __________^
-LL | |
-LL | |
+...  |
 LL | | = 42, T2 = Qux, T3 = usize> for Bar {
    | |____^ associated item constraint not allowed here
    |
diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr
index ec2890cc8e7..805c3e60bb6 100644
--- a/tests/ui/associated-types/issue-59324.stderr
+++ b/tests/ui/associated-types/issue-59324.stderr
@@ -2,8 +2,7 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied
   --> $DIR/issue-59324.rs:11:1
    |
 LL | / pub trait ThriftService<Bug: NotFoo>:
-LL | |
-LL | |
+...  |
 LL | |     Service<AssocType = <Bug as Foo>::OnlyFoo>
    | |______________________________________________^ the trait `Foo` is not implemented for `Bug`
    |
@@ -20,7 +19,6 @@ LL | |
 LL | |
 LL | |     Service<AssocType = <Bug as Foo>::OnlyFoo>
 ...  |
-LL | |
 LL | | }
    | |_^ the trait `Foo` is not implemented for `Bug`
    |
diff --git a/tests/ui/associated-types/missing-associated-types.stderr b/tests/ui/associated-types/missing-associated-types.stderr
index ce4b57e8af8..3a56c55896e 100644
--- a/tests/ui/associated-types/missing-associated-types.stderr
+++ b/tests/ui/associated-types/missing-associated-types.stderr
@@ -42,11 +42,11 @@ LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Fine<Rhs> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0191]: the value of the associated types `Output` in `Div`, `Output` in `Mul` must be specified
+error[E0191]: the value of the associated types `Output` in `Div<Rhs>`, `Output` in `Mul<Rhs>` must be specified
   --> $DIR/missing-associated-types.rs:20:21
    |
 LL | type Bal<Rhs> = dyn X<Rhs>;
-   |                     ^^^^^^ associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified
+   |                     ^^^^^^ associated types `Output` (from trait `Div<Rhs>`), `Output` (from trait `Mul<Rhs>`) must be specified
    |
    = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
 
diff --git a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
index 3bc467cc84d..4ed15a942c6 100644
--- a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -23,7 +23,6 @@ LL | |
 LL | |     let block = async {
 LL | |         return 0u8;
 ...  |
-LL | |
 LL | | }
    | |_^ expected `u8`, found `()`
 
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/dont-ice-for-type-mismatch-in-closure-in-async.stderr b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
index 649a868faa5..b60f6a08338 100644
--- a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
+++ b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
@@ -31,7 +31,6 @@ LL | |
 LL | |         if true {
 LL | |             false
 ...  |
-LL | |
 LL | |     })
    | |_____^ expected `bool`, found `Option<()>`
    |
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/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/issue-84841.stderr b/tests/ui/async-await/issue-84841.stderr
index 1e22373ba6e..69c1c882d60 100644
--- a/tests/ui/async-await/issue-84841.stderr
+++ b/tests/ui/async-await/issue-84841.stderr
@@ -14,8 +14,7 @@ LL |   async fn foo() {
 LL | |     // Adding an .await here avoids the ICE
 LL | |     test()?;
    | |           ^ cannot use the `?` operator in an async function that returns `()`
-LL | |
-LL | |
+...  |
 LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
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/issues/issue-72312.stderr b/tests/ui/async-await/issues/issue-72312.stderr
index cd93f8a3c55..8e6fb138a1f 100644
--- a/tests/ui/async-await/issues/issue-72312.stderr
+++ b/tests/ui/async-await/issues/issue-72312.stderr
@@ -8,10 +8,7 @@ LL |       pub async fn start(&self) {
    |                          let's call the lifetime of this reference `'1`
 ...
 LL | /         require_static(async move {
-LL | |
-LL | |
-LL | |
-LL | |             &self;
+...  |
 LL | |         });
    | |          ^
    | |          |
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.afn.stderr b/tests/ui/async-await/track-caller/async-closure-gate.afn.stderr
index 8344b7a07dc..6887a904211 100644
--- a/tests/ui/async-await/track-caller/async-closure-gate.afn.stderr
+++ b/tests/ui/async-await/track-caller/async-closure-gate.afn.stderr
@@ -66,8 +66,7 @@ LL |   fn foo3() {
 LL | /     async {
 LL | |
 LL | |         let _ = #[track_caller] || {
-LL | |
-LL | |         };
+...  |
 LL | |     }
    | |_____^ expected `()`, found `async` block
    |
diff --git a/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr b/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr
index 8344b7a07dc..6887a904211 100644
--- a/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr
+++ b/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr
@@ -66,8 +66,7 @@ LL |   fn foo3() {
 LL | /     async {
 LL | |
 LL | |         let _ = #[track_caller] || {
-LL | |
-LL | |         };
+...  |
 LL | |     }
    | |_____^ expected `()`, found `async` block
    |
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/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
index 7cbbd1d647e..70376f985cb 100644
--- a/tests/ui/attributes/collapse-debuginfo-invalid.stderr
+++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
@@ -45,7 +45,6 @@ LL | |     let _ = #[collapse_debuginfo(yes)] || { };
 LL | |
 LL | |     #[collapse_debuginfo(yes)]
 ...  |
-LL | |     }
 LL | | }
    | |_- not a macro definition
 
diff --git a/tests/ui/attributes/dump_def_parents.stderr b/tests/ui/attributes/dump_def_parents.stderr
index a928e8e33a4..74ecd9b0a89 100644
--- a/tests/ui/attributes/dump_def_parents.stderr
+++ b/tests/ui/attributes/dump_def_parents.stderr
@@ -22,7 +22,6 @@ LL | |
 LL | | fn bar() {
 LL | |     fn foo() {
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
@@ -66,7 +65,6 @@ LL | |
 LL | | fn bar() {
 LL | |     fn foo() {
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
@@ -124,7 +122,6 @@ LL | |
 LL | | fn bar() {
 LL | |     fn foo() {
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
@@ -173,7 +170,6 @@ LL | |
 LL | | fn bar() {
 LL | |     fn foo() {
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.rs b/tests/ui/borrowck/borrowck-describe-lvalue.rs
index cdcff69d6e5..f3a4b382fa8 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.rs
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.rs
@@ -231,7 +231,6 @@ fn main() {
         let x = &mut v;
         v[0].y;
         //~^ ERROR cannot use `v[_].y` because it was mutably borrowed
-        //~| ERROR cannot use `*v` because it was mutably borrowed
         drop(x);
     }
     // Field of constant index
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.stderr b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
index 11f2e42d42b..666a21808d8 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.stderr
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/borrowck-describe-lvalue.rs:254:13
+  --> $DIR/borrowck-describe-lvalue.rs:253:13
    |
 LL |             let y = &mut x;
    |                     ------ first mutable borrow occurs here
@@ -9,7 +9,7 @@ LL |             *y = 1;
    |             ------ first borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/borrowck-describe-lvalue.rs:264:20
+  --> $DIR/borrowck-describe-lvalue.rs:263:20
    |
 LL |                    let y = &mut x;
    |                            ------ first mutable borrow occurs here
@@ -19,7 +19,7 @@ LL |                    *y = 1;
    |                    ------ first borrow later used here
 
 error: captured variable cannot escape `FnMut` closure body
-  --> $DIR/borrowck-describe-lvalue.rs:262:16
+  --> $DIR/borrowck-describe-lvalue.rs:261:16
    |
 LL |           let mut x = 0;
    |               ----- variable defined here
@@ -300,17 +300,6 @@ LL |             S  { x: F { y: ref x0, .. }, .. } =>
 LL |         drop(x);
    |              - mutable borrow later used here
 
-error[E0503]: cannot use `*v` because it was mutably borrowed
-  --> $DIR/borrowck-describe-lvalue.rs:232:9
-   |
-LL |         let x = &mut v;
-   |                 ------ `v` is borrowed here
-LL |         v[0].y;
-   |         ^^^^ use of borrowed `v`
-...
-LL |         drop(x);
-   |              - borrow later used here
-
 error[E0503]: cannot use `v[_].y` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:232:9
    |
@@ -318,12 +307,12 @@ LL |         let x = &mut v;
    |                 ------ `v` is borrowed here
 LL |         v[0].y;
    |         ^^^^^^ use of borrowed `v`
-...
+LL |
 LL |         drop(x);
    |              - borrow later used here
 
 error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-describe-lvalue.rs:243:24
+  --> $DIR/borrowck-describe-lvalue.rs:242:24
    |
 LL |         let x = &mut v;
    |                 ------ mutable borrow occurs here
@@ -357,7 +346,7 @@ LL |             drop(x);
    |                  - mutable borrow later used here
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/borrowck-describe-lvalue.rs:274:22
+  --> $DIR/borrowck-describe-lvalue.rs:273:22
    |
 LL |                 drop(x);
    |                      - value moved here
@@ -366,7 +355,7 @@ LL |                 drop(x);
    |
    = note: move occurs because `x` has type `Vec<i32>`, which does not implement the `Copy` trait
 
-error: aborting due to 32 previous errors
+error: aborting due to 31 previous errors
 
 Some errors have detailed explanations: E0382, E0499, E0502, E0503.
 For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr
index a66281a188d..aa4e5fb2f69 100644
--- a/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr
+++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr
@@ -40,8 +40,6 @@ LL |       v.call(|(), this: &mut S| {
    |       | |
    |  _____| first borrow later used by call
    | |
-LL | |
-LL | |
 ...  |
 LL | |         v.set();
    | |         - first borrow occurs due to use of `v` in closure
diff --git a/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.rs b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.rs
new file mode 100644
index 00000000000..5425e571af0
--- /dev/null
+++ b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.rs
@@ -0,0 +1,8 @@
+//! Regression test for invalid suggestion for `&raw const expr` reported in
+//! <https://github.com/rust-lang/rust/issues/127562>.
+
+fn main() {
+    let val = 2;
+    let ptr = &raw const val;
+    unsafe { *ptr = 3; } //~ ERROR cannot assign to `*ptr`, which is behind a `*const` pointer
+}
diff --git a/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr
new file mode 100644
index 00000000000..c27dcc19827
--- /dev/null
+++ b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr
@@ -0,0 +1,9 @@
+error[E0594]: cannot assign to `*ptr`, which is behind a `*const` pointer
+  --> $DIR/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.rs:7:14
+   |
+LL |     unsafe { *ptr = 3; }
+   |              ^^^^^^^^ `ptr` is a `*const` pointer, so the data it refers to cannot be written
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/tests/ui/check-cfg/auxiliary/cfg_macro.rs b/tests/ui/check-cfg/auxiliary/cfg_macro.rs
index d68accd9202..1293fd6975e 100644
--- a/tests/ui/check-cfg/auxiliary/cfg_macro.rs
+++ b/tests/ui/check-cfg/auxiliary/cfg_macro.rs
@@ -9,3 +9,19 @@ macro_rules! my_lib_macro {
         $crate::my_lib_func()
     };
 }
+
+#[macro_export]
+macro_rules! my_lib_macro_value {
+    () => {
+        #[cfg(panic = "UNEXPECTED_VALUE")]
+        $crate::my_lib_func()
+    };
+}
+
+#[macro_export]
+macro_rules! my_lib_macro_feature {
+    () => {
+        #[cfg(feature = "UNEXPECTED_FEATURE")]
+        $crate::my_lib_func()
+    };
+}
diff --git a/tests/ui/check-cfg/report-in-external-macros.cargo.stderr b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
new file mode 100644
index 00000000000..290de4afb26
--- /dev/null
+++ b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
@@ -0,0 +1,42 @@
+warning: unexpected `cfg` condition name: `my_lib_cfg`
+  --> $DIR/report-in-external-macros.rs:13:5
+   |
+LL |     cfg_macro::my_lib_macro!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
+   = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
+   = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
+   = help: the macro `cfg_macro::my_lib_macro` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+   = note: this warning originates in the macro `cfg_macro::my_lib_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unexpected `cfg` condition value: `UNEXPECTED_VALUE`
+  --> $DIR/report-in-external-macros.rs:16:5
+   |
+LL |     cfg_macro::my_lib_macro_value!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected values for `panic` are: `abort` and `unwind`
+   = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
+   = help: try referring to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg
+   = help: the macro `cfg_macro::my_lib_macro_value` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
+   = note: this warning originates in the macro `cfg_macro::my_lib_macro_value` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unexpected `cfg` condition value: `UNEXPECTED_FEATURE`
+  --> $DIR/report-in-external-macros.rs:19:5
+   |
+LL |     cfg_macro::my_lib_macro_feature!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: no expected values for `feature`
+   = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
+   = help: try referring to `cfg_macro::my_lib_macro_feature` crate for guidance on how handle this unexpected cfg
+   = help: the macro `cfg_macro::my_lib_macro_feature` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
+   = note: this warning originates in the macro `cfg_macro::my_lib_macro_feature` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/check-cfg/report-in-external-macros.rs b/tests/ui/check-cfg/report-in-external-macros.rs
index 56550b04af3..72c2f6f6618 100644
--- a/tests/ui/check-cfg/report-in-external-macros.rs
+++ b/tests/ui/check-cfg/report-in-external-macros.rs
@@ -3,10 +3,19 @@
 
 //@ check-pass
 //@ no-auto-check-cfg
+//@ revisions: cargo rustc
+//@ [rustc]unset-rustc-env:CARGO_CRATE_NAME
+//@ [cargo]rustc-env:CARGO_CRATE_NAME=foo
 //@ aux-crate: cfg_macro=cfg_macro.rs
-//@ compile-flags: --check-cfg=cfg()
+//@ compile-flags: --check-cfg=cfg(feature,values())
 
 fn main() {
     cfg_macro::my_lib_macro!();
     //~^ WARNING unexpected `cfg` condition name
+
+    cfg_macro::my_lib_macro_value!();
+    //~^ WARNING unexpected `cfg` condition value
+
+    cfg_macro::my_lib_macro_feature!();
+    //~^ WARNING unexpected `cfg` condition value
 }
diff --git a/tests/ui/check-cfg/report-in-external-macros.rustc.stderr b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
new file mode 100644
index 00000000000..e1a2a8e86c6
--- /dev/null
+++ b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
@@ -0,0 +1,41 @@
+warning: unexpected `cfg` condition name: `my_lib_cfg`
+  --> $DIR/report-in-external-macros.rs:13:5
+   |
+LL |     cfg_macro::my_lib_macro!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
+   = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
+   = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
+   = help: to expect this configuration use `--check-cfg=cfg(my_lib_cfg)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+   = note: this warning originates in the macro `cfg_macro::my_lib_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unexpected `cfg` condition value: `UNEXPECTED_VALUE`
+  --> $DIR/report-in-external-macros.rs:16:5
+   |
+LL |     cfg_macro::my_lib_macro_value!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected values for `panic` are: `abort` and `unwind`
+   = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
+   = help: try referring to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+   = note: this warning originates in the macro `cfg_macro::my_lib_macro_value` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unexpected `cfg` condition value: `UNEXPECTED_FEATURE`
+  --> $DIR/report-in-external-macros.rs:19:5
+   |
+LL |     cfg_macro::my_lib_macro_feature!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: no expected values for `feature`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("UNEXPECTED_FEATURE"))`
+   = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
+   = help: try referring to `cfg_macro::my_lib_macro_feature` crate for guidance on how handle this unexpected cfg
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+   = note: this warning originates in the macro `cfg_macro::my_lib_macro_feature` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/check-cfg/report-in-external-macros.stderr b/tests/ui/check-cfg/report-in-external-macros.stderr
deleted file mode 100644
index 11300a4e402..00000000000
--- a/tests/ui/check-cfg/report-in-external-macros.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-warning: unexpected `cfg` condition name: `my_lib_cfg`
-  --> $DIR/report-in-external-macros.rs:10:5
-   |
-LL |     cfg_macro::my_lib_macro!();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
-   = help: to expect this configuration use `--check-cfg=cfg(my_lib_cfg)`
-   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
-   = note: `#[warn(unexpected_cfgs)]` on by default
-   = note: this warning originates in the macro `cfg_macro::my_lib_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr
index 3df1545cd4a..70fec8a350a 100644
--- a/tests/ui/check-cfg/target_feature.stderr
+++ b/tests/ui/check-cfg/target_feature.stderr
@@ -98,6 +98,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `fp8dot2`
 `fp8dot4`
 `fp8fma`
+`fpregs`
 `fpuv2_df`
 `fpuv2_sf`
 `fpuv3_df`
@@ -117,6 +118,14 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `hvx-length128b`
 `hwdiv`
 `i8mm`
+`isa-68000`
+`isa-68010`
+`isa-68020`
+`isa-68030`
+`isa-68040`
+`isa-68060`
+`isa-68881`
+`isa-68882`
 `jsconv`
 `lahfsahf`
 `lasx`
@@ -261,6 +270,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `vsx`
 `wfxt`
 `wide-arithmetic`
+`x87`
 `xop`
 `xsave`
 `xsavec`
diff --git a/tests/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr b/tests/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr
index 3c4f2de73a4..cb351d3cebd 100644
--- a/tests/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr
+++ b/tests/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         m[0] += 10;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -39,7 +38,6 @@ LL | |
 LL | |
 LL | |         m[0] += 10;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/by_value.stderr b/tests/ui/closures/2229_closure_analysis/by_value.stderr
index f843b76d723..af4ae34ad64 100644
--- a/tests/ui/closures/2229_closure_analysis/by_value.stderr
+++ b/tests/ui/closures/2229_closure_analysis/by_value.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         let p = t.0.0;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -39,7 +38,6 @@ LL | |
 LL | |
 LL | |         let p = t.0.0;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/capture-analysis-1.stderr b/tests/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
index 64ae704bc90..eef201792c6 100644
--- a/tests/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
+++ b/tests/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", p);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -49,7 +48,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", p);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/capture-analysis-2.stderr b/tests/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
index 40c075f3cc8..8fe4d2d57ab 100644
--- a/tests/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
+++ b/tests/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         let _x = p.x;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -39,7 +38,6 @@ LL | |
 LL | |
 LL | |         let _x = p.x;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/capture-analysis-3.stderr b/tests/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
index a4689f2ea96..f1dbefe15d5 100644
--- a/tests/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
+++ b/tests/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         let _x = a.b.c;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -39,7 +38,6 @@ LL | |
 LL | |
 LL | |         let _x = a.b.c;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/capture-analysis-4.stderr b/tests/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
index 9d3004dbbb0..91c3d6d1674 100644
--- a/tests/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
+++ b/tests/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         let _x = a.b;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -39,7 +38,6 @@ LL | |
 LL | |
 LL | |         let _x = a.b;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr b/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr
index 48fbd682a5b..c9c227335a9 100644
--- a/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr
+++ b/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr
@@ -15,8 +15,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", p.x);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -33,8 +32,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", p.x);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr b/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr
index 496511d6025..84aac180fbb 100644
--- a/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr
+++ b/tests/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr
@@ -15,8 +15,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", t.0);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -33,8 +32,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", t.0);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr
index 2d70b614858..89a879cec46 100644
--- a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr
+++ b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr
@@ -26,7 +26,6 @@ LL | |
 LL | |
 LL | |         if let Info::Point(_, _, str) = point {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -59,7 +58,6 @@ LL | |
 LL | |
 LL | |         if let Info::Point(_, _, str) = point {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr b/tests/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
index d118f7573a4..447ad8f4a68 100644
--- a/tests/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
+++ b/tests/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         let x = &p.a.p.x;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -44,7 +43,6 @@ LL | |
 LL | |
 LL | |         let x = &p.a.p.x;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr b/tests/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
index cc5f74613e4..639d1714721 100644
--- a/tests/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
+++ b/tests/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         let x = &t.0.0.0;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -44,7 +43,6 @@ LL | |
 LL | |
 LL | |         let x = &t.0.0.0;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
index 3abc81e191e..2d22c9a856f 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
@@ -12,8 +12,7 @@ fn arrays_1() {
     // c will capture `arr` completely, therefore another index into the
     // array can't be modified here
     arr[1] += 10;
-    //~^ ERROR: cannot use `arr` because it was mutably borrowed
-    //~| ERROR: cannot use `arr[_]` because it was mutably borrowed
+    //~^ ERROR: cannot use `arr[_]` because it was mutably borrowed
     c();
 }
 
@@ -55,8 +54,7 @@ fn arrays_4() {
     // c will capture `arr` completely, therefore we cannot borrow another index
     // into the array.
     println!("{}", arr[3]);
-    //~^ ERROR: cannot use `arr` because it was mutably borrowed
-    //~| ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
+    //~^ ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
 
     c();
 }
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
index 9e5200ef34b..97ecdfab820 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -1,17 +1,3 @@
-error[E0503]: cannot use `arr` because it was mutably borrowed
-  --> $DIR/arrays.rs:14:5
-   |
-LL |     let mut c = || {
-   |                 -- `arr` is borrowed here
-LL |         arr[0] += 10;
-   |         --- borrow occurs due to use of `arr` in closure
-...
-LL |     arr[1] += 10;
-   |     ^^^^^^ use of borrowed `arr`
-...
-LL |     c();
-   |     - borrow later used here
-
 error[E0503]: cannot use `arr[_]` because it was mutably borrowed
   --> $DIR/arrays.rs:14:5
    |
@@ -22,12 +8,12 @@ LL |         arr[0] += 10;
 ...
 LL |     arr[1] += 10;
    |     ^^^^^^^^^^^^ use of borrowed `arr`
-...
+LL |
 LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:29:5
+  --> $DIR/arrays.rs:28:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -41,7 +27,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:43:5
+  --> $DIR/arrays.rs:42:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -54,22 +40,8 @@ LL |
 LL |     c();
    |     - borrow later used here
 
-error[E0503]: cannot use `arr` because it was mutably borrowed
-  --> $DIR/arrays.rs:57:20
-   |
-LL |     let mut c = || {
-   |                 -- `arr` is borrowed here
-LL |         arr[1] += 10;
-   |         --- borrow occurs due to use of `arr` in closure
-...
-LL |     println!("{}", arr[3]);
-   |                    ^^^^^^ use of borrowed `arr`
-...
-LL |     c();
-   |     - borrow later used here
-
 error[E0502]: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:57:20
+  --> $DIR/arrays.rs:56:20
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -85,7 +57,7 @@ LL |     c();
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:73:24
+  --> $DIR/arrays.rs:71:24
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -98,7 +70,7 @@ LL |     println!("{:#?}", &arr[3..2]);
 LL |     c();
    |     - mutable borrow later used here
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0502, E0503, E0506.
 For more information about an error, try `rustc --explain E0502`.
diff --git a/tests/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr b/tests/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr
index 6dbe8c153c0..3e4c4d3ccd3 100644
--- a/tests/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr
+++ b/tests/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr
@@ -15,8 +15,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("This uses new capture analyysis to capture s={}", s);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -33,8 +32,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("This uses new capture analyysis to capture s={}", s);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/issue-118144.stderr b/tests/ui/closures/2229_closure_analysis/issue-118144.stderr
index 85cb5adc07e..87084e60237 100644
--- a/tests/ui/closures/2229_closure_analysis/issue-118144.stderr
+++ b/tests/ui/closures/2229_closure_analysis/issue-118144.stderr
@@ -5,6 +5,11 @@ LL |         V(x) = func_arg;
    |         ^^^^   -------- this expression has type `&mut V`
    |         |
    |         expected `&mut V`, found `V`
+   |
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |         V(x) = &*func_arg;
+   |                ~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/closures/2229_closure_analysis/issue-87378.stderr b/tests/ui/closures/2229_closure_analysis/issue-87378.stderr
index 3273e92d9d1..862ae7445e8 100644
--- a/tests/ui/closures/2229_closure_analysis/issue-87378.stderr
+++ b/tests/ui/closures/2229_closure_analysis/issue-87378.stderr
@@ -15,8 +15,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |        unsafe { u.value }
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -33,8 +32,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |        unsafe { u.value }
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/issue-88476.stderr b/tests/ui/closures/2229_closure_analysis/issue-88476.stderr
index 1c0e254dbf7..225b0335cf5 100644
--- a/tests/ui/closures/2229_closure_analysis/issue-88476.stderr
+++ b/tests/ui/closures/2229_closure_analysis/issue-88476.stderr
@@ -23,11 +23,7 @@ error: First Pass analysis includes:
    |
 LL |       let x = #[rustc_capture_analysis] move || {
    |  _______________________________________^
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -42,11 +38,7 @@ error: Min Capture analysis includes:
    |
 LL |       let x = #[rustc_capture_analysis] move || {
    |  _______________________________________^
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -61,11 +53,7 @@ error: First Pass analysis includes:
    |
 LL |       let c = #[rustc_capture_analysis] move || {
    |  _______________________________________^
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -80,11 +68,7 @@ error: Min Capture analysis includes:
    |
 LL |       let c = #[rustc_capture_analysis] move || {
    |  _______________________________________^
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr
index 7125bfa3101..e7e5e7f7fa1 100644
--- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr
+++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr
@@ -6,7 +6,6 @@ LL | |
 LL | |
 LL | |         match variant {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -24,7 +23,6 @@ LL | |
 LL | |
 LL | |         match variant {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -64,7 +62,6 @@ LL | |
 LL | |
 LL | |         match variant {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -87,7 +84,6 @@ LL | |
 LL | |
 LL | |         match variant {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -138,7 +134,6 @@ LL | |
 LL | |
 LL | |         match variant {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -156,7 +151,6 @@ LL | |
 LL | |
 LL | |         match variant {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -174,7 +168,6 @@ LL | |
 LL | |
 LL | |         match slice {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -192,7 +185,6 @@ LL | |
 LL | |
 LL | |         match slice {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -210,7 +202,6 @@ LL | |
 LL | |
 LL | |         match slice {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -228,7 +219,6 @@ LL | |
 LL | |
 LL | |         match slice {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -246,7 +236,6 @@ LL | |
 LL | |
 LL | |         match slice {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -264,7 +253,6 @@ LL | |
 LL | |
 LL | |         match slice {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
@@ -281,8 +269,7 @@ LL | /     || {
 LL | |
 LL | |         match slice {
 LL | |             [..] => {},
-LL | |             _ => {}
-LL | |         }
+...  |
 LL | |     };
    | |_____^
 
diff --git a/tests/ui/closures/2229_closure_analysis/move_closure.stderr b/tests/ui/closures/2229_closure_analysis/move_closure.stderr
index 68754b8f7be..a4919d488d1 100644
--- a/tests/ui/closures/2229_closure_analysis/move_closure.stderr
+++ b/tests/ui/closures/2229_closure_analysis/move_closure.stderr
@@ -139,8 +139,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         t.0.0 = "new S".into();
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -157,8 +156,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         t.0.0 = "new S".into();
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -175,8 +173,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         *ref_s += 10;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -193,8 +190,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         *ref_s += 10;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -211,8 +207,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         t.0.0 = "new s".into();
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -229,8 +224,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         t.0.0 = "new s".into();
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -247,8 +241,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         let _t = t.0.0;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -265,8 +258,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         let _t = t.0.0;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -283,8 +275,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         let _t = t.0.0;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -301,8 +292,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         let _t = t.0.0;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -319,8 +309,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         let _t = b.0;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -337,8 +326,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         let _t = b.0;
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -355,8 +343,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         println!("{}", b.0);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -373,8 +360,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         println!("{}", b.0);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -391,8 +377,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         println!("{}", t.1.0);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -409,8 +394,7 @@ LL | /     move || {
 LL | |
 LL | |
 LL | |         println!("{}", t.1.0);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/multilevel-path-2.stderr b/tests/ui/closures/2229_closure_analysis/multilevel-path-2.stderr
index 97f53e490e8..cbc7188a4ec 100644
--- a/tests/ui/closures/2229_closure_analysis/multilevel-path-2.stderr
+++ b/tests/ui/closures/2229_closure_analysis/multilevel-path-2.stderr
@@ -15,8 +15,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", w.p.x);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -33,8 +32,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", w.p.x);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/nested-closure.stderr b/tests/ui/closures/2229_closure_analysis/nested-closure.stderr
index 03550cb2d35..3b36069e624 100644
--- a/tests/ui/closures/2229_closure_analysis/nested-closure.stderr
+++ b/tests/ui/closures/2229_closure_analysis/nested-closure.stderr
@@ -60,7 +60,6 @@ LL | |
 LL | |
 LL | |         println!("{}", p.x);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -88,7 +87,6 @@ LL | |
 LL | |
 LL | |         println!("{}", p.x);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/path-with-array-access.stderr b/tests/ui/closures/2229_closure_analysis/path-with-array-access.stderr
index e82295f047b..c6608c05900 100644
--- a/tests/ui/closures/2229_closure_analysis/path-with-array-access.stderr
+++ b/tests/ui/closures/2229_closure_analysis/path-with-array-access.stderr
@@ -15,8 +15,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", pent.points[5].x);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -33,8 +32,7 @@ LL | /     || {
 LL | |
 LL | |
 LL | |         println!("{}", pent.points[5].x);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr b/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr
index 65a0a317ab6..ff3cd5b8f01 100644
--- a/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr
+++ b/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr
@@ -36,7 +36,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", a.0);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -69,7 +68,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", a.0);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -102,7 +100,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", a.1);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -135,7 +132,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", a.1);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -168,7 +164,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", b.1);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -201,7 +196,6 @@ LL | |
 LL | |
 LL | |         println!("{:?}", b.1);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/repr_packed.stderr b/tests/ui/closures/2229_closure_analysis/repr_packed.stderr
index d4b2f8bfeae..bab1e8f9977 100644
--- a/tests/ui/closures/2229_closure_analysis/repr_packed.stderr
+++ b/tests/ui/closures/2229_closure_analysis/repr_packed.stderr
@@ -118,7 +118,6 @@ LL | |
 LL | |
 LL | |         println!("{}", foo.x);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -141,7 +140,6 @@ LL | |
 LL | |
 LL | |         println!("{}", foo.x);
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr b/tests/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
index a88bd01093a..d4201b2d4c2 100644
--- a/tests/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
+++ b/tests/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
@@ -16,7 +16,6 @@ LL | |
 LL | |
 LL | |         p.x += 10;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -39,7 +38,6 @@ LL | |
 LL | |
 LL | |         p.x += 10;
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr b/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
index 54463c5277d..9f3c6576c72 100644
--- a/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
+++ b/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
@@ -25,8 +25,7 @@ LL | /      || unsafe {
 LL | |
 LL | |
 LL | |         println!("{:?}", (*t.0).s);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
@@ -43,8 +42,7 @@ LL | /      || unsafe {
 LL | |
 LL | |
 LL | |         println!("{:?}", (*t.0).s);
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr b/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr
index 4d6d85649da..4cb0f4a4a92 100644
--- a/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr
+++ b/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr
@@ -32,11 +32,7 @@ error: First Pass analysis includes:
   --> $DIR/wild_patterns.rs:26:5
    |
 LL | /     || {
-LL | |
-LL | |
-LL | |         // FIXME(arora-aman): Change `_x` to `_`
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -50,11 +46,7 @@ error: Min Capture analysis includes:
   --> $DIR/wild_patterns.rs:26:5
    |
 LL | /     || {
-LL | |
-LL | |
-LL | |         // FIXME(arora-aman): Change `_x` to `_`
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -68,11 +60,7 @@ error: First Pass analysis includes:
   --> $DIR/wild_patterns.rs:45:5
    |
 LL | /     || {
-LL | |
-LL | |
-LL | |         // FIXME(arora-aman): Change `_x` to `_`
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -86,11 +74,7 @@ error: Min Capture analysis includes:
   --> $DIR/wild_patterns.rs:45:5
    |
 LL | /     || {
-LL | |
-LL | |
-LL | |         // FIXME(arora-aman): Change `_x` to `_`
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -104,11 +88,7 @@ error: First Pass analysis includes:
   --> $DIR/wild_patterns.rs:64:5
    |
 LL | /     || {
-LL | |
-LL | |
-LL | |         // FIXME(arora-aman): Change `_x` to `_`
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
@@ -122,11 +102,7 @@ error: Min Capture analysis includes:
   --> $DIR/wild_patterns.rs:64:5
    |
 LL | /     || {
-LL | |
-LL | |
-LL | |         // FIXME(arora-aman): Change `_x` to `_`
 ...  |
-LL | |
 LL | |     };
    | |_____^
    |
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/codegen/alias-uninit-value.rs b/tests/ui/codegen/alias-uninit-value.rs
new file mode 100644
index 00000000000..a8aa94caaf2
--- /dev/null
+++ b/tests/ui/codegen/alias-uninit-value.rs
@@ -0,0 +1,26 @@
+//! Regression test for issue #374, where previously rustc performed conditional jumps or moves that
+//! incorrectly depended on uninitialized values.
+//!
+//! Issue: <https://github.com/rust-lang/rust/issues/374>.
+
+//@ run-pass
+
+#![allow(dead_code)]
+
+enum TyS {
+    Nil,
+}
+
+struct RawT {
+    struct_: TyS,
+    cname: Option<String>,
+    hash: usize,
+}
+
+fn mk_raw_ty(st: TyS, cname: Option<String>) -> RawT {
+    return RawT { struct_: st, cname: cname, hash: 0 };
+}
+
+pub fn main() {
+    mk_raw_ty(TyS::Nil, None::<String>);
+}
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
index 6f46df0101e..1cedbf75e4b 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
@@ -1,4 +1,4 @@
-<svg width="743px" height="848px" xmlns="http://www.w3.org/2000/svg">
+<svg width="743px" height="758px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
     .bg { background: #000000 }
@@ -33,83 +33,73 @@
 </tspan>
     <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold"> _________________-</tspan>
 </tspan>
-    <tspan x="10px" y="154px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>             // last line shown in multispan header</tspan>
+    <tspan x="10px" y="154px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="172px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+    <tspan x="10px" y="172px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         ),</tspan>
 </tspan>
-    <tspan x="10px" y="190px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+    <tspan x="10px" y="190px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `()`</tspan>
 </tspan>
-    <tspan x="10px" y="208px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         ),</tspan>
+    <tspan x="10px" y="208px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `()`</tspan>
+    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold"> __________________^</tspan>
 </tspan>
-    <tspan x="10px" y="244px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
+    <tspan x="10px" y="244px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold"> __________________^</tspan>
+    <tspan x="10px" y="262px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         ",</tspan>
 </tspan>
-    <tspan x="10px" y="280px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `()`, found `&amp;str`</tspan>
 </tspan>
-    <tspan x="10px" y="298px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+    <tspan x="10px" y="298px">
 </tspan>
-    <tspan x="10px" y="316px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         ",</tspan>
+    <tspan x="10px" y="316px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
 </tspan>
-    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `()`, found `&amp;str`</tspan>
+    <tspan x="10px" y="334px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/huge_multispan_highlight.rs:216:18</tspan>
 </tspan>
-    <tspan x="10px" y="352px">
+    <tspan x="10px" y="352px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="370px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
+    <tspan x="10px" y="370px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>       let _ = match true {</tspan>
 </tspan>
-    <tspan x="10px" y="388px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/huge_multispan_highlight.rs:216:18</tspan>
+    <tspan x="10px" y="388px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
 </tspan>
-    <tspan x="10px" y="406px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+    <tspan x="10px" y="406px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           true =&gt; (</tspan>
 </tspan>
-    <tspan x="10px" y="424px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>       let _ = match true {</tspan>
+    <tspan x="10px" y="424px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold"> _________________-</tspan>
 </tspan>
-    <tspan x="10px" y="442px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
+    <tspan x="10px" y="442px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="460px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           true =&gt; (</tspan>
+    <tspan x="10px" y="460px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         1 // last line shown in multispan header</tspan>
 </tspan>
-    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold"> _________________-</tspan>
+    <tspan x="10px" y="478px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+    <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         ),</tspan>
 </tspan>
-    <tspan x="10px" y="514px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         1 // last line shown in multispan header</tspan>
+    <tspan x="10px" y="514px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `{integer}`</tspan>
 </tspan>
-    <tspan x="10px" y="532px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+    <tspan x="10px" y="532px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="550px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+    <tspan x="10px" y="550px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold"> __________________^</tspan>
 </tspan>
-    <tspan x="10px" y="568px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         ),</tspan>
+    <tspan x="10px" y="568px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="586px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `{integer}`</tspan>
+    <tspan x="10px" y="586px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="604px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
+    <tspan x="10px" y="604px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         1 last line shown in multispan</tspan>
 </tspan>
-    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold"> __________________^</tspan>
+    <tspan x="10px" y="622px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="640px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+    <tspan x="10px" y="640px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         ",</tspan>
 </tspan>
-    <tspan x="10px" y="658px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+    <tspan x="10px" y="658px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `&amp;str`</tspan>
 </tspan>
-    <tspan x="10px" y="676px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         1 last line shown in multispan</tspan>
+    <tspan x="10px" y="676px">
 </tspan>
-    <tspan x="10px" y="694px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+    <tspan x="10px" y="694px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 2 previous errors</tspan>
 </tspan>
-    <tspan x="10px" y="712px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+    <tspan x="10px" y="712px">
 </tspan>
-    <tspan x="10px" y="730px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         ",</tspan>
+    <tspan x="10px" y="730px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
 </tspan>
-    <tspan x="10px" y="748px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `&amp;str`</tspan>
-</tspan>
-    <tspan x="10px" y="766px">
-</tspan>
-    <tspan x="10px" y="784px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 2 previous errors</tspan>
-</tspan>
-    <tspan x="10px" y="802px">
-</tspan>
-    <tspan x="10px" y="820px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
-</tspan>
-    <tspan x="10px" y="838px">
+    <tspan x="10px" y="748px">
 </tspan>
   </text>
 
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg b/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
index 4e1a8d14a28..36a33b74042 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
@@ -1,4 +1,4 @@
-<svg width="743px" height="848px" xmlns="http://www.w3.org/2000/svg">
+<svg width="743px" height="758px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
     .bg { background: #000000 }
@@ -33,83 +33,73 @@
 </tspan>
     <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">┌─────────────────┘</tspan>
 </tspan>
-    <tspan x="10px" y="154px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>             // last line shown in multispan header</tspan>
+    <tspan x="10px" y="154px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
 </tspan>
-    <tspan x="10px" y="172px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+    <tspan x="10px" y="172px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         ),</tspan>
 </tspan>
-    <tspan x="10px" y="190px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+    <tspan x="10px" y="190px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">└─────────┘</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `()`</tspan>
 </tspan>
-    <tspan x="10px" y="208px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         ),</tspan>
+    <tspan x="10px" y="208px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">└─────────┘</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `()`</tspan>
+    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┏━━━━━━━━━━━━━━━━━━┛</tspan>
 </tspan>
-    <tspan x="10px" y="244px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           false =&gt; "</tspan>
+    <tspan x="10px" y="244px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
 </tspan>
-    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┏━━━━━━━━━━━━━━━━━━┛</tspan>
+    <tspan x="10px" y="262px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         ",</tspan>
 </tspan>
-    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰╴</tspan><tspan class="fg-ansi256-009 bold">┗━━━━━━━━━┛</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `()`, found `&amp;str`</tspan>
 </tspan>
-    <tspan x="10px" y="298px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+    <tspan x="10px" y="298px">
 </tspan>
-    <tspan x="10px" y="316px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         ",</tspan>
+    <tspan x="10px" y="316px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
 </tspan>
-    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰╴</tspan><tspan class="fg-ansi256-009 bold">┗━━━━━━━━━┛</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `()`, found `&amp;str`</tspan>
+    <tspan x="10px" y="334px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/huge_multispan_highlight.rs:216:18</tspan>
 </tspan>
-    <tspan x="10px" y="352px">
+    <tspan x="10px" y="352px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
 </tspan>
-    <tspan x="10px" y="370px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
+    <tspan x="10px" y="370px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>       let _ = match true {</tspan>
 </tspan>
-    <tspan x="10px" y="388px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/huge_multispan_highlight.rs:216:18</tspan>
+    <tspan x="10px" y="388px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">──────────</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
 </tspan>
-    <tspan x="10px" y="406px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+    <tspan x="10px" y="406px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           true =&gt; (</tspan>
 </tspan>
-    <tspan x="10px" y="424px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>       let _ = match true {</tspan>
+    <tspan x="10px" y="424px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">┌─────────────────┘</tspan>
 </tspan>
-    <tspan x="10px" y="442px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">──────────</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
+    <tspan x="10px" y="442px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
 </tspan>
-    <tspan x="10px" y="460px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           true =&gt; (</tspan>
+    <tspan x="10px" y="460px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         1 // last line shown in multispan header</tspan>
 </tspan>
-    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">┌─────────────────┘</tspan>
+    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
 </tspan>
-    <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+    <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         ),</tspan>
 </tspan>
-    <tspan x="10px" y="514px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         1 // last line shown in multispan header</tspan>
+    <tspan x="10px" y="514px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">└─────────┘</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `{integer}`</tspan>
 </tspan>
-    <tspan x="10px" y="532px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+    <tspan x="10px" y="532px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="550px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+    <tspan x="10px" y="550px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┏━━━━━━━━━━━━━━━━━━┛</tspan>
 </tspan>
-    <tspan x="10px" y="568px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         ),</tspan>
+    <tspan x="10px" y="568px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
 </tspan>
-    <tspan x="10px" y="586px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">└─────────┘</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `{integer}`</tspan>
+    <tspan x="10px" y="586px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
 </tspan>
-    <tspan x="10px" y="604px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           false =&gt; "</tspan>
+    <tspan x="10px" y="604px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         1 last line shown in multispan</tspan>
 </tspan>
-    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┏━━━━━━━━━━━━━━━━━━┛</tspan>
+    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
 </tspan>
-    <tspan x="10px" y="640px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+    <tspan x="10px" y="640px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         ",</tspan>
 </tspan>
-    <tspan x="10px" y="658px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+    <tspan x="10px" y="658px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰╴</tspan><tspan class="fg-ansi256-009 bold">┗━━━━━━━━━┛</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `&amp;str`</tspan>
 </tspan>
-    <tspan x="10px" y="676px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         1 last line shown in multispan</tspan>
+    <tspan x="10px" y="676px">
 </tspan>
-    <tspan x="10px" y="694px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+    <tspan x="10px" y="694px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 2 previous errors</tspan>
 </tspan>
-    <tspan x="10px" y="712px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+    <tspan x="10px" y="712px">
 </tspan>
-    <tspan x="10px" y="730px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         ",</tspan>
+    <tspan x="10px" y="730px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
 </tspan>
-    <tspan x="10px" y="748px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰╴</tspan><tspan class="fg-ansi256-009 bold">┗━━━━━━━━━┛</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `&amp;str`</tspan>
-</tspan>
-    <tspan x="10px" y="766px">
-</tspan>
-    <tspan x="10px" y="784px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 2 previous errors</tspan>
-</tspan>
-    <tspan x="10px" y="802px">
-</tspan>
-    <tspan x="10px" y="820px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
-</tspan>
-    <tspan x="10px" y="838px">
+    <tspan x="10px" y="748px">
 </tspan>
   </text>
 
diff --git a/tests/ui/coercion/coerce-loop-issue-122561.stderr b/tests/ui/coercion/coerce-loop-issue-122561.stderr
index 90e9f41c291..3af7e7cddb3 100644
--- a/tests/ui/coercion/coerce-loop-issue-122561.stderr
+++ b/tests/ui/coercion/coerce-loop-issue-122561.stderr
@@ -189,8 +189,7 @@ error[E0308]: mismatched types
 LL |   fn while_never_type() -> ! {
    |                            - expected `!` because of return type
 LL | /     while true {
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____^ expected `!`, found `()`
    |
diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr
index a3211b77623..58d42d82998 100644
--- a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr
+++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr
@@ -2,10 +2,7 @@ error: free constant item without body
   --> $DIR/const_arg_trivial_macro_expansion-2.rs:12:1
    |
 LL | / const _: A<
-LL | |
-LL | |
-LL | |     {
-LL | |         y! { test.tou8 }
+...  |
 LL | |     },
 LL | | >;
    | |  ^ help: provide a definition for the constant: `= <expr>;`
diff --git a/tests/ui/const-generics/issues/issue-67945-2.full.stderr b/tests/ui/const-generics/issues/issue-67945-2.full.stderr
index 837927d588c..1eca3261a4a 100644
--- a/tests/ui/const-generics/issues/issue-67945-2.full.stderr
+++ b/tests/ui/const-generics/issues/issue-67945-2.full.stderr
@@ -5,8 +5,7 @@ LL |       A: [(); {
    |  _____________^
 LL | |
 LL | |         let x: Option<Box<Self>> = None;
-LL | |
-LL | |         0
+...  |
 LL | |     }],
    | |_____^ blocks are not supported in generic constants
    |
diff --git a/tests/ui/const-generics/issues/issue-71202.stderr b/tests/ui/const-generics/issues/issue-71202.stderr
index a2d38221852..cc3603d1145 100644
--- a/tests/ui/const-generics/issues/issue-71202.stderr
+++ b/tests/ui/const-generics/issues/issue-71202.stderr
@@ -4,7 +4,6 @@ error: unconstrained generic constant
 LL | /     const ITEM_IS_COPY: [(); 1 - {
 LL | |         trait NotCopy {
 LL | |             const VALUE: bool = false;
-LL | |         }
 ...  |
 LL | |         <IsCopy<T>>::VALUE
 LL | |     } as usize] = [];
diff --git a/tests/ui/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr
index 8696be3faf3..cdc0b9807d9 100644
--- a/tests/ui/const-generics/nested-type.min.stderr
+++ b/tests/ui/const-generics/nested-type.min.stderr
@@ -25,7 +25,6 @@ LL | |     struct Foo<const N: usize>;
 LL | |
 LL | |     impl<const N: usize> Foo<N> {
 ...  |
-LL | |
 LL | | }]>;
    | |__^
    |
diff --git a/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr
index d664ae88323..f326da8e26a 100644
--- a/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr
+++ b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr
@@ -16,7 +16,6 @@ LL |       let s = [(); {
    |  __________________^
 LL | |         let mut n = 113383; // #20 in https://oeis.org/A006884
 LL | |         while n != 0 {
-LL | |
 ...  |
 LL | |         n
 LL | |     }];
diff --git a/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr
index d664ae88323..f326da8e26a 100644
--- a/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr
+++ b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr
@@ -16,7 +16,6 @@ LL |       let s = [(); {
    |  __________________^
 LL | |         let mut n = 113383; // #20 in https://oeis.org/A006884
 LL | |         while n != 0 {
-LL | |
 ...  |
 LL | |         n
 LL | |     }];
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr
index 7f6625bcfcd..dddd79a4383 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr
@@ -2,10 +2,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/ctfe-simple-loop.rs:10:5
    |
 LL | /     while index < n {
-LL | |
-LL | |
-LL | |
-LL | |         index = index + 1;
+...  |
 LL | |     }
    | |_____^ the const evaluator is currently interpreting this expression
    |
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr
index 657f0e5bcba..2bb9a8a98ec 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr
@@ -2,10 +2,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/ctfe-simple-loop.rs:10:5
    |
 LL | /     while index < n {
-LL | |
-LL | |
-LL | |
-LL | |         index = index + 1;
+...  |
 LL | |     }
    | |_____^
    |
@@ -26,10 +23,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/ctfe-simple-loop.rs:10:5
    |
 LL | /     while index < n {
-LL | |
-LL | |
-LL | |
-LL | |         index = index + 1;
+...  |
 LL | |     }
    | |_____^
    |
@@ -45,10 +39,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/ctfe-simple-loop.rs:10:5
    |
 LL | /     while index < n {
-LL | |
-LL | |
-LL | |
-LL | |         index = index + 1;
+...  |
 LL | |     }
    | |_____^ the const evaluator is currently interpreting this expression
    |
diff --git a/tests/ui/consts/const-eval/stable-metric/evade-deduplication-issue-118612.stderr b/tests/ui/consts/const-eval/stable-metric/evade-deduplication-issue-118612.stderr
index cb19c59b15b..f41d2ea3e62 100644
--- a/tests/ui/consts/const-eval/stable-metric/evade-deduplication-issue-118612.stderr
+++ b/tests/ui/consts/const-eval/stable-metric/evade-deduplication-issue-118612.stderr
@@ -2,11 +2,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/evade-deduplication-issue-118612.rs:8:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |         }
 LL | |     }
    | |_____^ the const evaluator is currently interpreting this expression
    |
@@ -20,11 +16,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/evade-deduplication-issue-118612.rs:8:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |         }
 LL | |     }
    | |_____^ the const evaluator is currently interpreting this expression
    |
@@ -38,11 +30,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/evade-deduplication-issue-118612.rs:8:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |         }
 LL | |     }
    | |_____^ the const evaluator is currently interpreting this expression
    |
@@ -56,11 +44,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/evade-deduplication-issue-118612.rs:8:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |         }
 LL | |     }
    | |_____^ the const evaluator is currently interpreting this expression
    |
@@ -74,11 +58,7 @@ warning: constant evaluation is taking a long time
   --> $DIR/evade-deduplication-issue-118612.rs:8:5
    |
 LL | /     loop {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |         }
 LL | |     }
    | |_____^ the const evaluator is currently interpreting this expression
    |
diff --git a/tests/ui/consts/issue-65348.rs b/tests/ui/consts/issue-65348.rs
index 1443fcbe1c1..0d12da3926c 100644
--- a/tests/ui/consts/issue-65348.rs
+++ b/tests/ui/consts/issue-65348.rs
@@ -9,15 +9,17 @@ impl<T> Generic<T> {
 }
 
 pub const fn array<T>() -> &'static T {
-    #[allow(unconditional_panic)]
+    #[expect(unconditional_panic)]
     &Generic::<T>::ARRAY[0]
 }
 
 pub const fn newtype_array<T>() -> &'static T {
+    #[expect(unconditional_panic)]
     &Generic::<T>::NEWTYPE_ARRAY.0[0]
 }
 
 pub const fn array_field<T>() -> &'static T {
+    #[expect(unconditional_panic)]
     &(Generic::<T>::ARRAY_FIELD.0).1[0]
 }
 
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/coroutine/drop-tracking-parent-expression.stderr b/tests/ui/coroutine/drop-tracking-parent-expression.stderr
index 51fc20070bf..dc2f9768d23 100644
--- a/tests/ui/coroutine/drop-tracking-parent-expression.stderr
+++ b/tests/ui/coroutine/drop-tracking-parent-expression.stderr
@@ -7,7 +7,6 @@ LL |               assert_send(g);
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -26,7 +25,6 @@ LL |                   _ => yield,
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -47,7 +45,6 @@ LL |               assert_send(g);
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -66,7 +63,6 @@ LL |                   _ => yield,
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -87,7 +83,6 @@ LL |               assert_send(g);
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -106,7 +101,6 @@ LL |                   _ => yield,
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
diff --git a/tests/ui/coroutine/issue-88653.stderr b/tests/ui/coroutine/issue-88653.stderr
index ef0cc11dde8..772a7f8424a 100644
--- a/tests/ui/coroutine/issue-88653.stderr
+++ b/tests/ui/coroutine/issue-88653.stderr
@@ -12,8 +12,7 @@ LL |       |bar| {
 LL | |
 LL | |
 LL | |         if bar {
-LL | |             yield bar;
-LL | |         }
+...  |
 LL | |     }
    | |_____- return type was inferred to be `{coroutine@$DIR/issue-88653.rs:15:5: 15:10}` here
    |
diff --git a/tests/ui/coroutine/match-bindings.stderr b/tests/ui/coroutine/match-bindings.stderr
index 5525bfed116..1318e6931f5 100644
--- a/tests/ui/coroutine/match-bindings.stderr
+++ b/tests/ui/coroutine/match-bindings.stderr
@@ -7,7 +7,6 @@ LL | |         loop {
 LL | |             if let true = true {
 LL | |                 match Enum::A(String::new()) {
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/coroutine/parent-expression.stderr b/tests/ui/coroutine/parent-expression.stderr
index 770ffda7a26..a9125772b5a 100644
--- a/tests/ui/coroutine/parent-expression.stderr
+++ b/tests/ui/coroutine/parent-expression.stderr
@@ -7,7 +7,6 @@ LL |               assert_send(g);
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -26,7 +25,6 @@ LL |                   _ => yield,
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -47,7 +45,6 @@ LL |               assert_send(g);
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -66,7 +63,6 @@ LL |                   _ => yield,
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -87,7 +83,6 @@ LL |               assert_send(g);
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
@@ -106,7 +101,6 @@ LL |                   _ => yield,
 LL | /     type_combinations!(
 LL | |         // OK
 LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
 ...  |
 LL | |         };
 LL | |     );
diff --git a/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr b/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr
index 48df5c5beac..4fad4036300 100644
--- a/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr
+++ b/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr
@@ -3,9 +3,6 @@ warning: unused coroutine that must be used
    |
 LL |           #[coroutine] static move || {
    |  ______________________^
-LL | |             // Tests that the coroutine transformation finds out that `a` is not live
-LL | |             // during the yield expression. Type checking will also compute liveness
-LL | |             // and it should also find out that `a` is not live.
 ...  |
 LL | |             let _ = &a;
 LL | |         };
diff --git a/tests/ui/coroutine/yield-in-initializer.stderr b/tests/ui/coroutine/yield-in-initializer.stderr
index 1e22b787668..eff5a0fdccf 100644
--- a/tests/ui/coroutine/yield-in-initializer.stderr
+++ b/tests/ui/coroutine/yield-in-initializer.stderr
@@ -4,10 +4,7 @@ warning: unused coroutine that must be used
 LL |       #[coroutine] static || {
    |  __________________^
 LL | |         loop {
-LL | |             // Test that `opt` is not live across the yield, even when borrowed in a loop
-LL | |             // See https://github.com/rust-lang/rust/issues/52792
 ...  |
-LL | |         }
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr
index 986467dda69..38101764d6f 100644
--- a/tests/ui/coverage-attr/name-value.stderr
+++ b/tests/ui/coverage-attr/name-value.stderr
@@ -171,8 +171,6 @@ LL |   #[coverage = "off"]
 ...
 LL | / trait MyTrait {
 LL | |     #[coverage = "off"]
-LL | |
-LL | |
 ...  |
 LL | |     type T;
 LL | | }
diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr
index 1ce149724c6..154ea61f3a3 100644
--- a/tests/ui/coverage-attr/word-only.stderr
+++ b/tests/ui/coverage-attr/word-only.stderr
@@ -171,8 +171,6 @@ LL |   #[coverage]
 ...
 LL | / trait MyTrait {
 LL | |     #[coverage]
-LL | |
-LL | |
 ...  |
 LL | |     type T;
 LL | | }
diff --git a/tests/ui/diagnostic-flags/allow-non-lint-warnings.rs b/tests/ui/diagnostic-flags/allow-non-lint-warnings.rs
new file mode 100644
index 00000000000..40b9e6536f5
--- /dev/null
+++ b/tests/ui/diagnostic-flags/allow-non-lint-warnings.rs
@@ -0,0 +1,27 @@
+// ignore-tidy-linelength
+//! Check that `-A warnings` cli flag applies to non-lint warnings as well.
+//!
+//! This test tries to exercise that by checking that the "relaxing a default bound only does
+//! something for `?Sized`; all other traits are not bound by default" non-lint warning (normally
+//! warn-by-default) is suppressed if the `-A warnings` cli flag is passed.
+//!
+//! Take special note that `warnings` is a special pseudo lint group in relationship to non-lint
+//! warnings, which is somewhat special. This test does not exercise other `-A <other_lint_group>`
+//! that check that they are working in the same way, only `warnings` specifically.
+//!
+//! # Relevant context
+//!
+//! - Original impl PR: <https://github.com/rust-lang/rust/pull/21248>.
+//! - RFC 507 "Release channels":
+//!   <https://github.com/rust-lang/rfcs/blob/c017755b9bfa0421570d92ba38082302e0f3ad4f/text/0507-release-channels.md>.
+#![crate_type = "lib"]
+
+//@ revisions: without_flag with_flag
+
+//@[with_flag] compile-flags: -Awarnings
+
+//@ check-pass
+
+pub trait Trait {}
+pub fn f<T: ?Trait>() {}
+//[without_flag]~^ WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
diff --git a/tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr b/tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr
new file mode 100644
index 00000000000..b037847c70f
--- /dev/null
+++ b/tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr
@@ -0,0 +1,8 @@
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/allow-non-lint-warnings.rs:26:13
+   |
+LL | pub fn f<T: ?Trait>() {}
+   |             ^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr
index e276299e9e8..7446b1a543e 100644
--- a/tests/ui/diagnostic-width/E0271.ascii.stderr
+++ b/tests/ui/diagnostic-width/E0271.ascii.stderr
@@ -6,7 +6,6 @@ LL | |         Ok::<_, ()>(
 LL | |             Err::<(), _>(
 LL | |                 Ok::<_, ()>(
 ...  |
-LL | |         )
 LL | |     )
    | |_____^ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
    |
diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr
index 4a96ca36cd7..72df2a381a4 100644
--- a/tests/ui/diagnostic-width/E0271.unicode.stderr
+++ b/tests/ui/diagnostic-width/E0271.unicode.stderr
@@ -6,7 +6,6 @@ LL │ ┃         Ok::<_, ()>(
 LL │ ┃             Err::<(), _>(
 LL │ ┃                 Ok::<_, ()>(
    ‡ ┃
-LL │ ┃         )
 LL │ ┃     )
    │ ┗━━━━━┛ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
    ╰╴
diff --git a/tests/ui/drop/lint-tail-expr-drop-order.stderr b/tests/ui/drop/lint-tail-expr-drop-order.stderr
index f0da24605e6..a3084f660e4 100644
--- a/tests/ui/drop/lint-tail-expr-drop-order.stderr
+++ b/tests/ui/drop/lint-tail-expr-drop-order.stderr
@@ -22,22 +22,14 @@ note: `#1` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
 note: `x` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
@@ -71,22 +63,14 @@ note: `#1` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
 note: `x` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
@@ -115,22 +99,14 @@ note: `#1` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
 note: `x` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
@@ -159,22 +135,14 @@ note: `#1` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
 note: `future` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
@@ -225,22 +193,14 @@ note: `#1` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
 note: `x` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
@@ -311,22 +271,14 @@ note: `#1` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
 note: `_x` invokes this custom destructor
   --> $DIR/lint-tail-expr-drop-order.rs:11:1
    |
 LL | / impl Drop for LoudDropper {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_^
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds.rs b/tests/ui/dyn-compatibility/assoc_type_bounds.rs
index 8634ba626a1..6e2076a4822 100644
--- a/tests/ui/dyn-compatibility/assoc_type_bounds.rs
+++ b/tests/ui/dyn-compatibility/assoc_type_bounds.rs
@@ -7,7 +7,7 @@ trait Foo<T> {
 trait Cake {}
 impl Cake for () {}
 
-fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified
-fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified
+fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` in `Foo<()>` must be specified
+fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` in `Foo<i32>` must be specified
 
 fn main() {}
diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds.stderr
index 3d5482625af..21ba9030117 100644
--- a/tests/ui/dyn-compatibility/assoc_type_bounds.stderr
+++ b/tests/ui/dyn-compatibility/assoc_type_bounds.stderr
@@ -1,4 +1,4 @@
-error[E0191]: the value of the associated type `Bar` in `Foo` must be specified
+error[E0191]: the value of the associated type `Bar` in `Foo<()>` must be specified
   --> $DIR/assoc_type_bounds.rs:10:16
    |
 LL |     type Bar
@@ -7,7 +7,7 @@ LL |     type Bar
 LL | fn foo(_: &dyn Foo<()>) {}
    |                ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>`
 
-error[E0191]: the value of the associated type `Bar` in `Foo` must be specified
+error[E0191]: the value of the associated type `Bar` in `Foo<i32>` must be specified
   --> $DIR/assoc_type_bounds.rs:11:16
    |
 LL |     type Bar
diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds2.rs b/tests/ui/dyn-compatibility/assoc_type_bounds2.rs
index f7dc2fb8839..2b35016d774 100644
--- a/tests/ui/dyn-compatibility/assoc_type_bounds2.rs
+++ b/tests/ui/dyn-compatibility/assoc_type_bounds2.rs
@@ -7,7 +7,7 @@ trait Foo<T> {
 trait Cake {}
 impl Cake for () {}
 
-fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified
-fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified
+fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` in `Foo<()>` must be specified
+fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` in `Foo<i32>` must be specified
 
 fn main() {}
diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr
index 815747436bf..5c4163b1969 100644
--- a/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr
+++ b/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr
@@ -1,4 +1,4 @@
-error[E0191]: the value of the associated type `Bar` in `Foo` must be specified
+error[E0191]: the value of the associated type `Bar` in `Foo<()>` must be specified
   --> $DIR/assoc_type_bounds2.rs:10:16
    |
 LL |     type Bar
@@ -7,7 +7,7 @@ LL |     type Bar
 LL | fn foo(_: &dyn Foo<()>) {}
    |                ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>`
 
-error[E0191]: the value of the associated type `Bar` in `Foo` must be specified
+error[E0191]: the value of the associated type `Bar` in `Foo<i32>` must be specified
   --> $DIR/assoc_type_bounds2.rs:11:16
    |
 LL |     type Bar
diff --git a/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.rs b/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.rs
new file mode 100644
index 00000000000..1f4e1bf653a
--- /dev/null
+++ b/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.rs
@@ -0,0 +1,15 @@
+trait Sup<T> {
+    type Assoc: Default;
+}
+
+impl<T: Default> Sup<T> for () {
+    type Assoc = T;
+}
+impl<T: Default, U: Default> Dyn<T, U> for () {}
+
+trait Dyn<A, B>: Sup<A, Assoc = A> + Sup<B> {}
+
+fn main() {
+    let q: <dyn Dyn<i32, u32> as Sup<u32>>::Assoc = Default::default();
+    //~^ ERROR the value of the associated type `Assoc` in `Sup<u32>` must be specified
+}
diff --git a/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr b/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr
new file mode 100644
index 00000000000..3d89b52d522
--- /dev/null
+++ b/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr
@@ -0,0 +1,12 @@
+error[E0191]: the value of the associated type `Assoc` in `Sup<u32>` must be specified
+  --> $DIR/require-assoc-for-all-super-substs.rs:13:17
+   |
+LL |     type Assoc: Default;
+   |     ------------------- `Assoc` defined here
+...
+LL |     let q: <dyn Dyn<i32, u32> as Sup<u32>>::Assoc = Default::default();
+   |                 ^^^^^^^^^^^^^ help: specify the associated type: `Dyn<i32, u32, Assoc = Type>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0191`.
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/errors/issue-89280-emitter-overflow-splice-lines.stderr b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr
index 08eb8cfac49..54bde98b57f 100644
--- a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr
+++ b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr
@@ -3,8 +3,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi
    |
 LL |       fn test(x: u32, (
    |  _____________________^
-LL | |
-LL | |
+...  |
 LL | |     )) {}
    | |_____^
    |
diff --git a/tests/ui/expr/if/if-let-arm-types.stderr b/tests/ui/expr/if/if-let-arm-types.stderr
index 285f5c4a6f2..0a8260f0fea 100644
--- a/tests/ui/expr/if/if-let-arm-types.stderr
+++ b/tests/ui/expr/if/if-let-arm-types.stderr
@@ -5,8 +5,7 @@ LL | /     if let Some(b) = None {
 LL | |
 LL | |         ()
    | |         -- expected because of this
-LL | |
-LL | |     } else {
+...  |
 LL | |         1
    | |         ^ expected `()`, found integer
 LL | |     };
diff --git a/tests/ui/extern/issue-116203.stderr b/tests/ui/extern/issue-116203.stderr
index 86e4cc763bd..51ef1421e3e 100644
--- a/tests/ui/extern/issue-116203.stderr
+++ b/tests/ui/extern/issue-116203.stderr
@@ -22,8 +22,7 @@ LL |   extern "C" {
 LL | /     thread_local! {
 LL | |       static FOO: u32 = 0;
    | |              ^^^ cannot have a body
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____- the invalid body
    |
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.default.stderr
index 3bb93cf2ea0..d0a25e28a76 100644
--- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr
+++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.default.stderr
@@ -1,5 +1,5 @@
 error[E0658]: `*const Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
-  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:8:18
+  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:11:18
    |
 LL |     fn foo(self: *const Self) {}
    |                  ^^^^^^^^^^^
@@ -7,10 +7,10 @@ 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
+  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:15:18
    |
 LL |     fn bar(self: *mut Self) {}
    |                  ^^^^^^^^^
@@ -18,10 +18,10 @@ 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
+  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:5:18
    |
 LL |     fn foo(self: *const Self);
    |                  ^^^^^^^^^^^
@@ -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-pointers.feature.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.feature.stderr
new file mode 100644
index 00000000000..d0a25e28a76
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.feature.stderr
@@ -0,0 +1,36 @@
+error[E0658]: `*const Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
+  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:11:18
+   |
+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`, 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:15:18
+   |
+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`, 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:5:18
+   |
+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`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs
index 79ceb05662b..7ea1b875f79 100644
--- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs
+++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs
@@ -1,3 +1,6 @@
+//@ revisions: default feature
+#![cfg_attr(feature, feature(arbitrary_self_types))]
+
 trait Foo {
     fn foo(self: *const Self); //~ ERROR `*const Self` cannot be used as the type of `self`
 }
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-impl-trait-in-bindings.rs b/tests/ui/feature-gates/feature-gate-impl-trait-in-bindings.rs
new file mode 100644
index 00000000000..f6574b48120
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-impl-trait-in-bindings.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let x: impl Sized = ();
+    //~^ ERROR `impl Trait` is not allowed in the type of variable bindings
+}
diff --git a/tests/ui/feature-gates/feature-gate-impl-trait-in-bindings.stderr b/tests/ui/feature-gates/feature-gate-impl-trait-in-bindings.stderr
new file mode 100644
index 00000000000..58f058fb564
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-impl-trait-in-bindings.stderr
@@ -0,0 +1,14 @@
+error[E0562]: `impl Trait` is not allowed in the type of variable bindings
+  --> $DIR/feature-gate-impl-trait-in-bindings.rs:2:12
+   |
+LL |     let x: impl Sized = ();
+   |            ^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/tests/ui/feature-gates/feature-gate-unsafe-binders.rs b/tests/ui/feature-gates/feature-gate-unsafe-binders.rs
new file mode 100644
index 00000000000..a2997ced4fa
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe-binders.rs
@@ -0,0 +1,7 @@
+#[cfg(any())]
+fn test() {
+    let x: unsafe<> ();
+    //~^ ERROR unsafe binder types are experimental
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-unsafe-binders.stderr b/tests/ui/feature-gates/feature-gate-unsafe-binders.stderr
new file mode 100644
index 00000000000..93997d6c14a
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe-binders.stderr
@@ -0,0 +1,13 @@
+error[E0658]: unsafe binder types are experimental
+  --> $DIR/feature-gate-unsafe-binders.rs:3:12
+   |
+LL |     let x: unsafe<> ();
+   |            ^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = help: add `#![feature(unsafe_binders)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
index fe764ff4925..db8c5295a2d 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
@@ -54,11 +54,7 @@ LL |   #[inline]
    |   ^^^^^^^^^
 LL |
 LL | / mod inline {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | | }
    | |_- not a function or closure
 
@@ -73,7 +69,6 @@ LL | |
 LL | |
 LL | |     mod inner { #![no_link] }
 ...  |
-LL | |
 LL | | }
    | |_- not an `extern crate` item
 
@@ -88,7 +83,6 @@ LL | |
 LL | |
 LL | |     mod inner { #![export_name="2200"] }
 ...  |
-LL | |     }
 LL | | }
    | |_- not a free function, impl method or static
 
@@ -101,9 +95,7 @@ LL |
 LL | / mod repr {
 LL | |
 LL | |     mod inner { #![repr(C)] }
-LL | |
 ...  |
-LL | |
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -116,9 +108,7 @@ LL |
 LL | / mod repr_rust {
 LL | |
 LL | |     mod inner { #![repr(Rust)] }
-LL | |
 ...  |
-LL | |
 LL | | }
    | |_- not a struct, enum, or union
 
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
index e43cef7c150..18fb75aafbb 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
@@ -227,9 +227,7 @@ LL |   #[no_mangle]
 LL | / mod no_mangle {
 LL | |
 LL | |     mod inner { #![no_mangle] }
-LL | |
 ...  |
-LL | |     }
 LL | | }
    | |_- not a free function, impl method or static
    |
@@ -270,7 +268,6 @@ LL | |
 LL | |
 LL | |     mod inner { #![cold] }
 ...  |
-LL | |
 LL | | }
    | |_- not a function definition
    |
@@ -287,7 +284,6 @@ LL | |
 LL | |
 LL | |     #[link_name = "1900"]
 ...  |
-LL | |
 LL | | }
    | |_- not a foreign function or static
    |
@@ -304,7 +300,6 @@ LL | |
 LL | |
 LL | |     mod inner { #![link_section="1800"] }
 ...  |
-LL | |
 LL | | }
    | |_- not a function or static
    |
@@ -321,7 +316,6 @@ LL | |
 LL | |
 LL | |     mod inner { #![link()] }
 ...  |
-LL | |
 LL | | }
    | |_- not an `extern` block
    |
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-derive.stderr b/tests/ui/feature-gates/issue-43106-gating-of-derive.stderr
index 4dee7a00544..5df3e9e73fe 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-derive.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-derive.stderr
@@ -6,8 +6,6 @@ LL |   #[derive(Debug)]
 LL |
 LL | / mod derive {
 LL | |     mod inner { #![derive(Debug)] }
-LL | |
-LL | |
 ...  |
 LL | |     impl S { }
 LL | | }
diff --git a/tests/ui/for/for-else-err.stderr b/tests/ui/for/for-else-err.stderr
index bd49dc47244..a872cde5cac 100644
--- a/tests/ui/for/for-else-err.stderr
+++ b/tests/ui/for/for-else-err.stderr
@@ -6,8 +6,7 @@ LL |       for _ in 0..1 {
 LL |
 LL |       } else {
    |  _______^
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____^
    |
diff --git a/tests/ui/for/for-else-let-else-err.stderr b/tests/ui/for/for-else-let-else-err.stderr
index bb6558739ba..22432a18bbb 100644
--- a/tests/ui/for/for-else-let-else-err.stderr
+++ b/tests/ui/for/for-else-let-else-err.stderr
@@ -6,8 +6,7 @@ LL |       let _ = for _ in 0..1 {
 LL |
 LL |       } else {
    |  _______^
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/generic-associated-types/collectivity-regression.stderr b/tests/ui/generic-associated-types/collectivity-regression.stderr
index 0c395a1664f..1c081ac644a 100644
--- a/tests/ui/generic-associated-types/collectivity-regression.stderr
+++ b/tests/ui/generic-associated-types/collectivity-regression.stderr
@@ -2,10 +2,7 @@ error: `T` does not live long enough
   --> $DIR/collectivity-regression.rs:13:5
    |
 LL | /     || {
-LL | |
-LL | |         //
-LL | |         // FIXME(#98437). This regressed at some point and
-LL | |         // probably should work.
+...  |
 LL | |         let _x = x;
 LL | |     };
    | |_____^
diff --git a/tests/ui/generics/overlapping-errors-span-issue-123861.rs b/tests/ui/generics/overlapping-errors-span-issue-123861.rs
new file mode 100644
index 00000000000..e0a27f68748
--- /dev/null
+++ b/tests/ui/generics/overlapping-errors-span-issue-123861.rs
@@ -0,0 +1,8 @@
+fn mainIterator<_ = _> {}
+//~^ ERROR expected identifier, found reserved identifier `_`
+//~| ERROR   missing parameters for function definition
+//~| ERROR   defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions [invalid_type_param_default]
+//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+//~| ERROR   the placeholder `_` is not allowed within types on item signatures for functions [E0121]
+
+fn main() {}
diff --git a/tests/ui/generics/overlapping-errors-span-issue-123861.stderr b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr
new file mode 100644
index 00000000000..e0a49343b0e
--- /dev/null
+++ b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr
@@ -0,0 +1,52 @@
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/overlapping-errors-span-issue-123861.rs:1:17
+   |
+LL | fn mainIterator<_ = _> {}
+   |                 ^ expected identifier, found reserved identifier
+
+error: missing parameters for function definition
+  --> $DIR/overlapping-errors-span-issue-123861.rs:1:23
+   |
+LL | fn mainIterator<_ = _> {}
+   |                       ^
+   |
+help: add a parameter list
+   |
+LL | fn mainIterator<_ = _>() {}
+   |                       ++
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/overlapping-errors-span-issue-123861.rs:1:17
+   |
+LL | fn mainIterator<_ = _> {}
+   |                 ^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+   = note: `#[deny(invalid_type_param_default)]` on by default
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/overlapping-errors-span-issue-123861.rs:1:21
+   |
+LL | fn mainIterator<_ = _> {}
+   |                     ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | fn mainIterator<T = T> {}
+   |                 ~   ~
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0121`.
+Future incompatibility report: Future breakage diagnostic:
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/overlapping-errors-span-issue-123861.rs:1:17
+   |
+LL | fn mainIterator<_ = _> {}
+   |                 ^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+   = note: `#[deny(invalid_type_param_default)]` on by default
+
diff --git a/tests/ui/anonymous-higher-ranked-lifetime.rs b/tests/ui/higher-ranked/anonymous-higher-ranked-lifetime.rs
index 898fe22fa23..8d8d0e71067 100644
--- a/tests/ui/anonymous-higher-ranked-lifetime.rs
+++ b/tests/ui/higher-ranked/anonymous-higher-ranked-lifetime.rs
@@ -1,3 +1,9 @@
+//! Diagnostics test to check that higher-ranked lifetimes are properly named when being pretty
+//! printed in diagnostics.
+//!
+//! Issue: <https://github.com/rust-lang/rust/issues/44887>
+//! PR: <https://github.com/rust-lang/rust/pull/44888>
+
 fn main() {
     f1(|_: (), _: ()| {}); //~ ERROR type mismatch
     f2(|_: (), _: ()| {}); //~ ERROR type mismatch
diff --git a/tests/ui/anonymous-higher-ranked-lifetime.stderr b/tests/ui/higher-ranked/anonymous-higher-ranked-lifetime.stderr
index c28d856ad55..7e0cdba6ff2 100644
--- a/tests/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/tests/ui/higher-ranked/anonymous-higher-ranked-lifetime.stderr
@@ -1,5 +1,5 @@
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
    |
 LL |     f1(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -10,7 +10,7 @@ LL |     f1(|_: (), _: ()| {});
    = note: expected closure signature `for<'a, 'b> fn(&'a (), &'b ()) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `f1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:16:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:22:25
    |
 LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
    |                         ^^^^^^^^^^^^ required by this bound in `f1`
@@ -20,7 +20,7 @@ LL |     f1(|_: &(), _: &()| {});
    |            +       +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
    |
 LL |     f2(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -31,7 +31,7 @@ LL |     f2(|_: (), _: ()| {});
    = note: expected closure signature `for<'a, 'b> fn(&'a (), &'b ()) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `f2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:17:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:23:25
    |
 LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f2`
@@ -41,7 +41,7 @@ LL |     f2(|_: &(), _: &()| {});
    |            +       +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
    |
 LL |     f3(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -52,7 +52,7 @@ LL |     f3(|_: (), _: ()| {});
    = note: expected closure signature `for<'a> fn(&(), &'a ()) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `f3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:18:29
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:24:29
    |
 LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
    |                             ^^^^^^^^^^^^^^^ required by this bound in `f3`
@@ -62,7 +62,7 @@ LL |     f3(|_: &(), _: &()| {});
    |            +       +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
    |
 LL |     f4(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -73,7 +73,7 @@ LL |     f4(|_: (), _: ()| {});
    = note: expected closure signature `for<'a, 'r> fn(&'a (), &'r ()) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `f4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:19:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:25:25
    |
 LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f4`
@@ -83,7 +83,7 @@ LL |     f4(|_: &(), _: &()| {});
    |            +       +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
    |
 LL |     f5(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -94,7 +94,7 @@ LL |     f5(|_: (), _: ()| {});
    = note: expected closure signature `for<'r> fn(&'r (), &'r ()) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `f5`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:20:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:26:25
    |
 LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f5`
@@ -104,7 +104,7 @@ LL |     f5(|_: &(), _: &()| {});
    |            +       +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5
    |
 LL |     g1(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -115,7 +115,7 @@ LL |     g1(|_: (), _: ()| {});
    = note: expected closure signature `for<'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `g1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:23:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:29:25
    |
 LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g1`
@@ -125,7 +125,7 @@ LL |     g1(|_: &(), _: ()| {});
    |            +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
    |
 LL |     g2(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -136,7 +136,7 @@ LL |     g2(|_: (), _: ()| {});
    = note: expected closure signature `for<'a> fn(&'a (), for<'a> fn(&'a ())) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `g2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:24:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:30:25
    |
 LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
    |                         ^^^^^^^^^^^^^^^^ required by this bound in `g2`
@@ -146,7 +146,7 @@ LL |     g2(|_: &(), _: ()| {});
    |            +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5
    |
 LL |     g3(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -157,7 +157,7 @@ LL |     g3(|_: (), _: ()| {});
    = note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `g3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:25:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:31:25
    |
 LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g3`
@@ -167,7 +167,7 @@ LL |     g3(|_: &(), _: ()| {});
    |            +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
    |
 LL |     g4(|_: (), _: ()| {});
    |     ^^^--------------^^^^
@@ -178,7 +178,7 @@ LL |     g4(|_: (), _: ()| {});
    = note: expected closure signature `for<'a> fn(&'a (), for<'r> fn(&'r ())) -> _`
               found closure signature `fn((), ()) -> _`
 note: required by a bound in `g4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:26:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:32:25
    |
 LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g4`
@@ -188,7 +188,7 @@ LL |     g4(|_: &(), _: ()| {});
    |            +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5
    |
 LL |     h1(|_: (), _: (), _: (), _: ()| {});
    |     ^^^----------------------------^^^^
@@ -199,7 +199,7 @@ LL |     h1(|_: (), _: (), _: (), _: ()| {});
    = note: expected closure signature `for<'a, 'b> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'b (), for<'a, 'b> fn(&'a (), &'b ())) -> _`
               found closure signature `fn((), (), (), ()) -> _`
 note: required by a bound in `h1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:29:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:35:25
    |
 LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h1`
@@ -209,7 +209,7 @@ LL |     h1(|_: &(), _: (), _: &(), _: ()| {});
    |            +              +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
    |
 LL |     h2(|_: (), _: (), _: (), _: ()| {});
    |     ^^^----------------------------^^^^
@@ -220,7 +220,7 @@ LL |     h2(|_: (), _: (), _: (), _: ()| {});
    = note: expected closure signature `for<'a, 't0> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'t0 (), for<'a, 'b> fn(&'a (), &'b ())) -> _`
               found closure signature `fn((), (), (), ()) -> _`
 note: required by a bound in `h2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:30:25
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:36:25
    |
 LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h2`
diff --git a/tests/ui/impl-trait/in-bindings/bad-nesting.rs b/tests/ui/impl-trait/in-bindings/bad-nesting.rs
new file mode 100644
index 00000000000..7f4b44cc691
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/bad-nesting.rs
@@ -0,0 +1,10 @@
+#![feature(impl_trait_in_bindings)]
+
+trait Foo<T> {}
+
+impl Foo<()> for () {}
+
+fn main() {
+    let x: impl Foo<impl Sized> = ();
+    //~^ ERROR nested `impl Trait` is not allowed
+}
diff --git a/tests/ui/impl-trait/in-bindings/bad-nesting.stderr b/tests/ui/impl-trait/in-bindings/bad-nesting.stderr
new file mode 100644
index 00000000000..d82ce733254
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/bad-nesting.stderr
@@ -0,0 +1,12 @@
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/bad-nesting.rs:8:21
+   |
+LL |     let x: impl Foo<impl Sized> = ();
+   |            ---------^^^^^^^^^^-
+   |            |        |
+   |            |        nested `impl Trait` here
+   |            outer `impl Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0666`.
diff --git a/tests/ui/impl-trait/in-bindings/dont-make-def-id.rs b/tests/ui/impl-trait/in-bindings/dont-make-def-id.rs
new file mode 100644
index 00000000000..d159e9ab0f9
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/dont-make-def-id.rs
@@ -0,0 +1,10 @@
+//@ check-pass
+
+// Make sure we don't create an opaque def id for ITIB.
+
+#![crate_type = "lib"]
+#![feature(impl_trait_in_bindings)]
+
+fn foo() {
+    let _: impl Sized = 0;
+}
diff --git a/tests/ui/impl-trait/in-bindings/escaping-bound-var.rs b/tests/ui/impl-trait/in-bindings/escaping-bound-var.rs
new file mode 100644
index 00000000000..b57fef9be21
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/escaping-bound-var.rs
@@ -0,0 +1,14 @@
+#![feature(impl_trait_in_bindings)]
+
+trait Foo<'a> {
+    type Out;
+}
+
+impl<'a> Foo<'a> for () {
+    type Out = ();
+}
+
+fn main() {
+    let x: &dyn for<'a> Foo<'a, Out = impl Sized + 'a> = &();
+    //~^ ERROR cannot capture late-bound lifetime in `impl Trait` in binding
+}
diff --git a/tests/ui/impl-trait/in-bindings/escaping-bound-var.stderr b/tests/ui/impl-trait/in-bindings/escaping-bound-var.stderr
new file mode 100644
index 00000000000..640f6f36927
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/escaping-bound-var.stderr
@@ -0,0 +1,8 @@
+error: cannot capture late-bound lifetime in `impl Trait` in binding
+  --> $DIR/escaping-bound-var.rs:12:52
+   |
+LL |     let x: &dyn for<'a> Foo<'a, Out = impl Sized + 'a> = &();
+   |                     -- lifetime defined here       ^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/impl-trait/in-bindings/lifetime-failure.rs b/tests/ui/impl-trait/in-bindings/lifetime-failure.rs
new file mode 100644
index 00000000000..df685c36c43
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/lifetime-failure.rs
@@ -0,0 +1,12 @@
+#![feature(impl_trait_in_bindings)]
+
+trait Static: 'static {}
+impl<T: 'static> Static for T {}
+
+struct W<T>(T);
+
+fn main() {
+    let local = 0;
+    let _: W<impl Static> = W(&local);
+    //~^ ERROR `local` does not live long enough
+}
diff --git a/tests/ui/impl-trait/in-bindings/lifetime-failure.stderr b/tests/ui/impl-trait/in-bindings/lifetime-failure.stderr
new file mode 100644
index 00000000000..189efcbca87
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/lifetime-failure.stderr
@@ -0,0 +1,16 @@
+error[E0597]: `local` does not live long enough
+  --> $DIR/lifetime-failure.rs:10:31
+   |
+LL |     let local = 0;
+   |         ----- binding `local` declared here
+LL |     let _: W<impl Static> = W(&local);
+   |            --------------     ^^^^^^ borrowed value does not live long enough
+   |            |
+   |            type annotation requires that `local` is borrowed for `'static`
+LL |
+LL | }
+   | - `local` dropped here while still borrowed
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.rs b/tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.rs
new file mode 100644
index 00000000000..7e5d2cf18bd
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.rs
@@ -0,0 +1,10 @@
+#![feature(impl_trait_in_bindings)]
+
+trait Static {}
+impl<T: 'static> Static for T {}
+
+fn main() {
+    let local = 0;
+    let _: impl IntoIterator<Item = impl Static> = [&local];
+    //~^ ERROR `local` does not live long enough
+}
diff --git a/tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.stderr b/tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.stderr
new file mode 100644
index 00000000000..c0326b37949
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.stderr
@@ -0,0 +1,16 @@
+error[E0597]: `local` does not live long enough
+  --> $DIR/nesting-lifetime-failure.rs:8:53
+   |
+LL |     let local = 0;
+   |         ----- binding `local` declared here
+LL |     let _: impl IntoIterator<Item = impl Static> = [&local];
+   |            -------------------------------------    ^^^^^^ borrowed value does not live long enough
+   |            |
+   |            type annotation requires that `local` is borrowed for `'static`
+LL |
+LL | }
+   | - `local` dropped here while still borrowed
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/impl-trait/in-bindings/nesting.rs b/tests/ui/impl-trait/in-bindings/nesting.rs
new file mode 100644
index 00000000000..51ff42bcafe
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/nesting.rs
@@ -0,0 +1,7 @@
+//@ check-pass
+
+#![feature(impl_trait_in_bindings)]
+
+fn main() {
+    let _: impl IntoIterator<Item = impl Sized> = ["hello", " world"];
+}
diff --git a/tests/ui/impl-trait/in-bindings/simple.rs b/tests/ui/impl-trait/in-bindings/simple.rs
new file mode 100644
index 00000000000..8052f5a1880
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/simple.rs
@@ -0,0 +1,10 @@
+//@ check-pass
+
+#![feature(impl_trait_in_bindings)]
+
+trait Foo {}
+impl Foo for () {}
+
+fn main() {
+    let x: impl Foo = ();
+}
diff --git a/tests/ui/impl-trait/in-bindings/trait-failure.rs b/tests/ui/impl-trait/in-bindings/trait-failure.rs
new file mode 100644
index 00000000000..e4052437f2f
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/trait-failure.rs
@@ -0,0 +1,13 @@
+#![feature(impl_trait_in_bindings)]
+
+trait Foo {}
+
+struct W<T>(T);
+impl<T> Foo for W<T> where T: Foo {}
+
+fn main() {
+    let x: impl Foo = W(());
+    //~^ ERROR the trait bound `(): Foo` is not satisfied
+    let x: W<impl Foo> = W(());
+    //~^ ERROR the trait bound `(): Foo` is not satisfied
+}
diff --git a/tests/ui/impl-trait/in-bindings/trait-failure.stderr b/tests/ui/impl-trait/in-bindings/trait-failure.stderr
new file mode 100644
index 00000000000..332cefd796d
--- /dev/null
+++ b/tests/ui/impl-trait/in-bindings/trait-failure.stderr
@@ -0,0 +1,24 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/trait-failure.rs:9:17
+   |
+LL |     let x: impl Foo = W(());
+   |                 ^^^ the trait `Foo` is not implemented for `()`
+   |
+   = help: the trait `Foo` is implemented for `W<T>`
+note: required for `W<()>` to implement `Foo`
+  --> $DIR/trait-failure.rs:6:9
+   |
+LL | impl<T> Foo for W<T> where T: Foo {}
+   |         ^^^     ^^^^          --- unsatisfied trait bound introduced here
+
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/trait-failure.rs:11:19
+   |
+LL |     let x: W<impl Foo> = W(());
+   |                   ^^^ the trait `Foo` is not implemented for `()`
+   |
+   = help: the trait `Foo` is implemented for `W<T>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr
index 1ddbd75142f..e38e18857ef 100644
--- a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr
+++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr
@@ -2,9 +2,6 @@ error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
   --> $DIR/false-positive-predicate-entailment-error.rs:36:5
    |
 LL | /     fn autobatch<F>(self) -> impl Trait
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     where
 LL | |         F: Callback<Self::CallbackArg>,
@@ -52,9 +49,6 @@ error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
   --> $DIR/false-positive-predicate-entailment-error.rs:36:5
    |
 LL | /     fn autobatch<F>(self) -> impl Trait
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     where
 LL | |         F: Callback<Self::CallbackArg>,
@@ -105,9 +99,6 @@ error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
   --> $DIR/false-positive-predicate-entailment-error.rs:36:5
    |
 LL | /     fn autobatch<F>(self) -> impl Trait
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     where
 LL | |         F: Callback<Self::CallbackArg>,
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/impl-trait/issues/issue-54600.stderr b/tests/ui/impl-trait/issues/issue-54600.stderr
index c75c0fa0f05..02d60960233 100644
--- a/tests/ui/impl-trait/issues/issue-54600.stderr
+++ b/tests/ui/impl-trait/issues/issue-54600.stderr
@@ -5,6 +5,9 @@ LL |     let x: Option<impl Debug> = Some(44_u32);
    |                   ^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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 1 previous error
 
diff --git a/tests/ui/impl-trait/issues/issue-54840.stderr b/tests/ui/impl-trait/issues/issue-54840.stderr
index de75256d5a9..805ea04f0bc 100644
--- a/tests/ui/impl-trait/issues/issue-54840.stderr
+++ b/tests/ui/impl-trait/issues/issue-54840.stderr
@@ -5,6 +5,9 @@ LL |     let j: &impl Add = &i;
    |             ^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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 1 previous error
 
diff --git a/tests/ui/impl-trait/issues/issue-58504.stderr b/tests/ui/impl-trait/issues/issue-58504.stderr
index 8231732bba1..bc921d5cd2c 100644
--- a/tests/ui/impl-trait/issues/issue-58504.stderr
+++ b/tests/ui/impl-trait/issues/issue-58504.stderr
@@ -5,6 +5,9 @@ LL |     let gens: [impl Coroutine<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen()
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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 1 previous error
 
diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr
index 0c81c69def3..825777e4923 100644
--- a/tests/ui/impl-trait/issues/issue-58956.stderr
+++ b/tests/ui/impl-trait/issues/issue-58956.stderr
@@ -13,6 +13,9 @@ LL |     let x: Wrap<impl Lam> = Wrap(B);
    |                 ^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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
 
diff --git a/tests/ui/impl-trait/issues/issue-70971.stderr b/tests/ui/impl-trait/issues/issue-70971.stderr
index 28c463cea85..10e5fffa430 100644
--- a/tests/ui/impl-trait/issues/issue-70971.stderr
+++ b/tests/ui/impl-trait/issues/issue-70971.stderr
@@ -5,6 +5,9 @@ LL |     let x : (impl Copy,) = (true,);
    |              ^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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 1 previous error
 
diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr
index 96825eabec7..d7c0c494454 100644
--- a/tests/ui/impl-trait/issues/issue-79099.stderr
+++ b/tests/ui/impl-trait/issues/issue-79099.stderr
@@ -16,6 +16,9 @@ LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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
 
diff --git a/tests/ui/impl-trait/issues/issue-84919.stderr b/tests/ui/impl-trait/issues/issue-84919.stderr
index 02d2ce28fb3..21dd355065d 100644
--- a/tests/ui/impl-trait/issues/issue-84919.stderr
+++ b/tests/ui/impl-trait/issues/issue-84919.stderr
@@ -5,6 +5,9 @@ LL |     let _x: impl Trait = ();
    |             ^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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 1 previous error
 
diff --git a/tests/ui/impl-trait/issues/issue-87295.stderr b/tests/ui/impl-trait/issues/issue-87295.stderr
index 78274a056ec..31f3b2f5bf2 100644
--- a/tests/ui/impl-trait/issues/issue-87295.stderr
+++ b/tests/ui/impl-trait/issues/issue-87295.stderr
@@ -5,6 +5,9 @@ LL |     let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(());
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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 1 previous error
 
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index 13f50fcea7b..400df87ca3f 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -333,6 +333,9 @@ LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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[E0562]: `impl Trait` is not allowed in closure return types
   --> $DIR/where-allowed.rs:253:46
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-18611.stderr b/tests/ui/issues/issue-18611.stderr
index 76848201f73..918654215b3 100644
--- a/tests/ui/issues/issue-18611.stderr
+++ b/tests/ui/issues/issue-18611.stderr
@@ -15,8 +15,7 @@ error[E0277]: the trait bound `isize: HasState` is not satisfied
    |
 LL |   fn add_state(op: <isize as HasState>::State) {
    |  ______________________________________________^
-LL | |
-LL | |
+...  |
 LL | | }
    | |_^ the trait `HasState` is not implemented for `isize`
    |
diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr
index d8febe71652..7bc965536e9 100644
--- a/tests/ui/issues/issue-28344.stderr
+++ b/tests/ui/issues/issue-28344.stderr
@@ -12,7 +12,7 @@ help: if this is a dyn-compatible trait, use `dyn`
 LL |     let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
    |                 ++++       +
 
-error[E0191]: the value of the associated type `Output` in `BitXor` must be specified
+error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified
   --> $DIR/issue-28344.rs:4:17
    |
 LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
@@ -31,7 +31,7 @@ help: if this is a dyn-compatible trait, use `dyn`
 LL |     let g = <dyn BitXor>::bitor;
    |             ++++       +
 
-error[E0191]: the value of the associated type `Output` in `BitXor` must be specified
+error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified
   --> $DIR/issue-28344.rs:9:13
    |
 LL |     let g = BitXor::bitor;
diff --git a/tests/ui/issues/issue-51714.stderr b/tests/ui/issues/issue-51714.stderr
index e53e10afcaf..da3e3caea29 100644
--- a/tests/ui/issues/issue-51714.stderr
+++ b/tests/ui/issues/issue-51714.stderr
@@ -2,14 +2,10 @@ error[E0572]: return statement outside of function body
   --> $DIR/issue-51714.rs:6:13
    |
 LL | / fn main() {
-LL | |
-LL | |
-LL | |
-LL | |
+...  |
 LL | |     |_: [_; return || {}]| {};
    | |             ^^^^^^^^^^^^ the return is part of this body...
 ...  |
-LL | |
 LL | | }
    | |_- ...not the enclosing function body
 
@@ -17,14 +13,10 @@ error[E0572]: return statement outside of function body
   --> $DIR/issue-51714.rs:10:10
    |
 LL | / fn main() {
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     [(); return || {}];
    | |          ^^^^^^^^^^^^ the return is part of this body...
 ...  |
-LL | |
 LL | | }
    | |_- ...not the enclosing function body
 
@@ -32,14 +24,10 @@ error[E0572]: return statement outside of function body
   --> $DIR/issue-51714.rs:14:10
    |
 LL | / fn main() {
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     [(); return |ice| {}];
    | |          ^^^^^^^^^^^^^^^ the return is part of this body...
 ...  |
-LL | |
 LL | | }
    | |_- ...not the enclosing function body
 
@@ -47,14 +35,10 @@ error[E0572]: return statement outside of function body
   --> $DIR/issue-51714.rs:18:10
    |
 LL | / fn main() {
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     [(); return while let Some(n) = Some(0) {}];
    | |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
-LL | |
-LL | |
+...  |
 LL | | }
    | |_- ...not the enclosing function body
 
diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr
index 38014ecce75..3c19b68cffb 100644
--- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr
+++ b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr
@@ -2,57 +2,61 @@ error[E0308]: mismatched types
   --> $DIR/issue-57741.rs:20:9
    |
 LL |     let y = match x {
-   |                   -
-   |                   |
-   |                   this expression has type `Box<T>`
-   |                   help: consider dereferencing the boxed value: `*x`
+   |                   - this expression has type `Box<T>`
 LL |         T::A(a) | T::B(a) => a,
    |         ^^^^^^^ expected `Box<T>`, found `T`
    |
    = note: expected struct `Box<T>`
                 found enum `T`
+help: consider dereferencing the boxed value
+   |
+LL |     let y = match *x {
+   |                   ~~
 
 error[E0308]: mismatched types
   --> $DIR/issue-57741.rs:20:19
    |
 LL |     let y = match x {
-   |                   -
-   |                   |
-   |                   this expression has type `Box<T>`
-   |                   help: consider dereferencing the boxed value: `*x`
+   |                   - this expression has type `Box<T>`
 LL |         T::A(a) | T::B(a) => a,
    |                   ^^^^^^^ expected `Box<T>`, found `T`
    |
    = note: expected struct `Box<T>`
                 found enum `T`
+help: consider dereferencing the boxed value
+   |
+LL |     let y = match *x {
+   |                   ~~
 
 error[E0308]: mismatched types
   --> $DIR/issue-57741.rs:27:9
    |
 LL |     let y = match x {
-   |                   -
-   |                   |
-   |                   this expression has type `Box<S>`
-   |                   help: consider dereferencing the boxed value: `*x`
+   |                   - this expression has type `Box<S>`
 LL |         S::A { a } | S::B { b: a } => a,
    |         ^^^^^^^^^^ expected `Box<S>`, found `S`
    |
    = note: expected struct `Box<S>`
                 found enum `S`
+help: consider dereferencing the boxed value
+   |
+LL |     let y = match *x {
+   |                   ~~
 
 error[E0308]: mismatched types
   --> $DIR/issue-57741.rs:27:22
    |
 LL |     let y = match x {
-   |                   -
-   |                   |
-   |                   this expression has type `Box<S>`
-   |                   help: consider dereferencing the boxed value: `*x`
+   |                   - this expression has type `Box<S>`
 LL |         S::A { a } | S::B { b: a } => a,
    |                      ^^^^^^^^^^^^^ expected `Box<S>`, found `S`
    |
    = note: expected struct `Box<S>`
                 found enum `S`
+help: consider dereferencing the boxed value
+   |
+LL |     let y = match *x {
+   |                   ~~
 
 error: aborting due to 4 previous errors
 
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/let-else/let-else-deref-coercion.stderr b/tests/ui/let-else/let-else-deref-coercion.stderr
index 143b838bac5..da8b1f4c48e 100644
--- a/tests/ui/let-else/let-else-deref-coercion.stderr
+++ b/tests/ui/let-else/let-else-deref-coercion.stderr
@@ -5,6 +5,11 @@ LL |         let Bar::Present(z) = self else {
    |             ^^^^^^^^^^^^^^^   ---- this expression has type `&mut Foo`
    |             |
    |             expected `Foo`, found `Bar`
+   |
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |         let Bar::Present(z) = &**self else {
+   |                               ~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/let-else-deref-coercion.rs:68:13
@@ -13,6 +18,11 @@ LL |         let Bar(z) = x;
    |             ^^^^^^   - this expression has type `&mut irrefutable::Foo`
    |             |
    |             expected `Foo`, found `Bar`
+   |
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |         let Bar(z) = &**x;
+   |                      ~~~~
 
 error: aborting due to 2 previous errors
 
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/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr
index e8c3ab00226..90572fed0ed 100644
--- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr
+++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr
@@ -2,9 +2,6 @@ error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
   --> $DIR/issue-76168-hr-outlives-3.rs:6:1
    |
 LL | / async fn wrapper<F>(f: F)
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | F:,
 LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
@@ -24,9 +21,6 @@ error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
   --> $DIR/issue-76168-hr-outlives-3.rs:6:1
    |
 LL | / async fn wrapper<F>(f: F)
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | F:,
 LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
@@ -38,9 +32,6 @@ error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
   --> $DIR/issue-76168-hr-outlives-3.rs:6:1
    |
 LL | / async fn wrapper<F>(f: F)
-LL | |
-LL | |
-LL | |
 ...  |
 LL | | F:,
 LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
diff --git a/tests/ui/lifetimes/issue-97194.stderr b/tests/ui/lifetimes/issue-97194.stderr
index 93bde285a99..345e21cb250 100644
--- a/tests/ui/lifetimes/issue-97194.stderr
+++ b/tests/ui/lifetimes/issue-97194.stderr
@@ -7,10 +7,7 @@ LL |       fn bget(&self, index: [usize; Self::DIM]) -> bool {
    |  ________^^^^___________________________________________-
    | |        |
    | |        cannot have a body
-LL | |
-LL | |
-LL | |
-LL | |         type T<'a> = &'a str;
+...  |
 LL | |     }
    | |_____- help: remove the invalid body: `;`
    |
diff --git a/tests/ui/lint/fn-ptr-comparisons-134345.rs b/tests/ui/lint/fn-ptr-comparisons-134345.rs
new file mode 100644
index 00000000000..9650a910a34
--- /dev/null
+++ b/tests/ui/lint/fn-ptr-comparisons-134345.rs
@@ -0,0 +1,16 @@
+// This check veifies that we do not ICE when not showing a user type
+// in the suggestions/diagnostics.
+//
+// cf. https://github.com/rust-lang/rust/issues/134345
+//
+//@ check-pass
+
+struct A;
+
+fn fna(_a: A) {}
+
+#[allow(unpredictable_function_pointer_comparisons)]
+fn main() {
+    let fa: fn(A) = fna;
+    let _ = fa == fna;
+}
diff --git a/tests/ui/lint/lints-in-foreign-macros.stderr b/tests/ui/lint/lints-in-foreign-macros.stderr
index f20e16287af..c0164bd00ff 100644
--- a/tests/ui/lint/lints-in-foreign-macros.stderr
+++ b/tests/ui/lint/lints-in-foreign-macros.stderr
@@ -34,7 +34,6 @@ LL | | #![warn(missing_docs)]
 LL | |
 LL | | #[macro_use]
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
    |
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index 20fb4a6432e..077837f4a6b 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -124,7 +124,6 @@ LL | |         impl Uto10 for Test {}
    | |              |         |
    | |              |         `Test` is not local
    | |              `Uto10` is not local
-LL | |
 ...  |
 LL | |     }];
    | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index ec3517140ef..5b7d1a83744 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -8,7 +8,6 @@ LL | |     impl Uto for *mut Test {}
    | |          |            |
    | |          |            `Test` is not local
    | |          `Uto` is not local
-LL | |
 ...  |
 LL | | }];
    | |_- move the `impl` block outside of this constant expression `<unnameable>`
@@ -26,7 +25,6 @@ LL | |         impl Uto for Test {}
    | |              |       |
    | |              |       `Test` is not local
    | |              `Uto` is not local
-LL | |
 ...  |
 LL | |     }
    | |_____- move the `impl` block outside of this constant expression `<unnameable>`
@@ -61,7 +59,6 @@ LL | |         impl Uto for &Test {}
    | |              |        |
    | |              |        `Test` is not local
    | |              `Uto` is not local
-LL | |
 ...  |
 LL | |     }];
    | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
@@ -78,7 +75,6 @@ LL | |         impl Uto for &(Test,) {}
    | |              |         |
    | |              |         `Test` is not local
    | |              `Uto` is not local
-LL | |
 ...  |
 LL | |     }]) {}
    | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
@@ -96,7 +92,6 @@ LL | |         impl Uto for &(Test,Test) {}
    | |              |         |    `Test` is not local
    | |              |         `Test` is not local
    | |              `Uto` is not local
-LL | |
 ...  |
 LL | |     }] { todo!() }
    | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
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/loops/dont-suggest-break-thru-item.stderr b/tests/ui/loops/dont-suggest-break-thru-item.stderr
index 642578ade60..e7ed7ae1501 100644
--- a/tests/ui/loops/dont-suggest-break-thru-item.stderr
+++ b/tests/ui/loops/dont-suggest-break-thru-item.stderr
@@ -4,8 +4,7 @@ error[E0308]: mismatched types
 LL | /             if true {
 LL | |                 Err(1)
    | |                 ^^^^^^ expected `()`, found `Result<_, {integer}>`
-LL | |
-LL | |
+...  |
 LL | |             }
    | |_____________- expected this to be `()`
    |
@@ -22,8 +21,7 @@ error[E0308]: mismatched types
 LL | /             if true {
 LL | |                 Err(1)
    | |                 ^^^^^^ expected `()`, found `Result<_, {integer}>`
-LL | |
-LL | |
+...  |
 LL | |             }
    | |_____________- expected this to be `()`
    |
diff --git a/tests/ui/loops/loop-else-err.stderr b/tests/ui/loops/loop-else-err.stderr
index c1cbd544afd..36ccd9c4047 100644
--- a/tests/ui/loops/loop-else-err.stderr
+++ b/tests/ui/loops/loop-else-err.stderr
@@ -6,8 +6,7 @@ LL |       loop {
 LL |
 LL |       } else {
    |  _______^
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____^
    |
diff --git a/tests/ui/loops/loop-else-let-else-err.stderr b/tests/ui/loops/loop-else-let-else-err.stderr
index 6ee77fb47af..b2d07d4b2b2 100644
--- a/tests/ui/loops/loop-else-let-else-err.stderr
+++ b/tests/ui/loops/loop-else-let-else-err.stderr
@@ -6,8 +6,7 @@ LL |       let _ = loop {
 LL |
 LL |       } else {
    |  _______^
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/lub-glb/old-lub-glb-hr-noteq1.leak.stderr b/tests/ui/lub-glb/old-lub-glb-hr-noteq1.leak.stderr
index 10e3fc92868..747d492999c 100644
--- a/tests/ui/lub-glb/old-lub-glb-hr-noteq1.leak.stderr
+++ b/tests/ui/lub-glb/old-lub-glb-hr-noteq1.leak.stderr
@@ -7,8 +7,7 @@ LL | |         0 => x,
    | |              - this is found to be of type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
 LL | |         _ => y,
    | |              ^ one type is more general than the other
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
diff --git a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout
index e9ee59abfae..e8c88d2dcdf 100644
--- a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout
+++ b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout
@@ -7,9 +7,7 @@ extern crate std;
 // issue#97006
 
 macro_rules! m { ($attr_path: path) => { #[$attr_path] fn f() {} } }
-#[
-
-inline]
+#[inline]
 fn f() { }
 
 fn main() { }
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/match/match-incompat-type-semi.stderr b/tests/ui/match/match-incompat-type-semi.stderr
index 008b1c1e93d..ca5336602c7 100644
--- a/tests/ui/match/match-incompat-type-semi.stderr
+++ b/tests/ui/match/match-incompat-type-semi.stderr
@@ -31,8 +31,7 @@ LL | |         0;
    | |         ||
    | |         |help: consider removing this semicolon
    | |         expected integer, found `()`
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____- `if` and `else` have incompatible types
 
diff --git a/tests/ui/match/match-type-err-first-arm.stderr b/tests/ui/match/match-type-err-first-arm.stderr
index 1cfe7ce1ed7..69f4e22e6ae 100644
--- a/tests/ui/match/match-type-err-first-arm.stderr
+++ b/tests/ui/match/match-type-err-first-arm.stderr
@@ -21,8 +21,7 @@ LL | |         12 => 'b',
    | |               --- this is found to be of type `char`
 LL | |         _ => 42,
    | |              ^^ expected `char`, found integer
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____- `match` arms have incompatible types
 
@@ -40,8 +39,7 @@ LL | |         6 => 'b',
 LL | |
 LL | |         _ => 42,
    | |              ^^ expected `char`, found integer
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____- `match` arms have incompatible types
 
@@ -55,8 +53,7 @@ LL | |             x
 LL | |         },
 LL | |         None => {}
    | |                 ^^ expected `u32`, found `()`
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____- `match` arms have incompatible types
 
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/diverging-place-match.stderr b/tests/ui/never_type/diverging-place-match.stderr
index 74e1bfa0a6b..14300c4df05 100644
--- a/tests/ui/never_type/diverging-place-match.stderr
+++ b/tests/ui/never_type/diverging-place-match.stderr
@@ -5,8 +5,7 @@ LL | /     unsafe {
 LL | |
 LL | |         let x: *const ! = 0 as _;
 LL | |         let _: ! = *x;
-LL | |         // Since `*x` "diverges" in HIR, but doesn't count as a read in MIR, this
-LL | |         // is unsound since we act as if it diverges but it doesn't.
+...  |
 LL | |     }
    | |_____^ expected `!`, found `()`
    |
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/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index ca7d187ac57..3c04cf300ad 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -30,10 +30,7 @@ LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
    |             |
    |             lifetime `'a` defined here
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |
-LL | |
-LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get())
+...  |
 LL | |     });
    | |      ^
    | |      |
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index d11a64272a9..9f5762ccbfa 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -30,10 +30,7 @@ LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
    |             |
    |             lifetime `'a` defined here
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |
-LL | |
-LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get())
+...  |
 LL | |     });
    | |      ^
    | |      |
diff --git a/tests/ui/nll/snocat-regression.stderr b/tests/ui/nll/snocat-regression.stderr
index 135b6951537..ae61245290b 100644
--- a/tests/ui/nll/snocat-regression.stderr
+++ b/tests/ui/nll/snocat-regression.stderr
@@ -2,10 +2,7 @@ error: `S` does not live long enough
   --> $DIR/snocat-regression.rs:7:5
    |
 LL | /     || {
-LL | |
-LL | |         //
-LL | |         // FIXME(#98437). This regressed at some point and
-LL | |         // probably should work.
+...  |
 LL | |         let _x = link;
 LL | |     };
    | |_____^
diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr
index 677b40a7f0d..6288cc58913 100644
--- a/tests/ui/or-patterns/missing-bindings.stderr
+++ b/tests/ui/or-patterns/missing-bindings.stderr
@@ -219,7 +219,6 @@ LL | |                 A(
 LL | |                     A(_, a) |
 LL | |                     B(b),
 ...  |
-LL | |
 LL | |             ) |
    | |_____________^ pattern doesn't bind `c`
 LL |               V3(c),
diff --git a/tests/ui/parser/as-precedence.rs b/tests/ui/parser/as-precedence.rs
new file mode 100644
index 00000000000..ca8328adb0e
--- /dev/null
+++ b/tests/ui/parser/as-precedence.rs
@@ -0,0 +1,18 @@
+//! Parser precedence test to help with [RFC 87 "Trait Bounds with Plus"][rfc-87], to check the
+//! precedence of the `as` operator in relation to some arithmetic bin-ops and parentheses.
+//!
+//! Editor's note: this test seems quite incomplete compared to what's possible nowadays. Maybe
+//! there's another set of tests whose coverage overshadows this test?
+//!
+//! [rfc-87]: https://rust-lang.github.io/rfcs/0087-trait-bounds-with-plus.html
+
+//@ run-pass
+
+#[allow(unused_parens)]
+fn main() {
+    assert_eq!(3 as usize * 3, 9);
+    assert_eq!(3 as (usize) * 3, 9);
+    assert_eq!(3 as (usize) / 3, 1);
+    assert_eq!(3 as usize + 3, 6);
+    assert_eq!(3 as (usize) + 3, 6);
+}
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/parser/brace-in-let-chain.rs b/tests/ui/parser/brace-in-let-chain.rs
index 1f34c73a2c3..2009bc88d9e 100644
--- a/tests/ui/parser/brace-in-let-chain.rs
+++ b/tests/ui/parser/brace-in-let-chain.rs
@@ -3,7 +3,7 @@
 #![feature(let_chains)]
 fn main() {
     if let () = ()
-        && let () = () { //~ERROR: found a `{` in the middle of a let-chain
+        && let () = () {
         && let () = ()
     {
     }
@@ -11,7 +11,7 @@ fn main() {
 
 fn quux() {
     while let () = ()
-        && let () = () { //~ERROR: found a `{` in the middle of a let-chain
+        && let () = () {
         && let () = ()
     {
     }
diff --git a/tests/ui/parser/brace-in-let-chain.stderr b/tests/ui/parser/brace-in-let-chain.stderr
index 913a34700df..12af95c2786 100644
--- a/tests/ui/parser/brace-in-let-chain.stderr
+++ b/tests/ui/parser/brace-in-let-chain.stderr
@@ -27,33 +27,5 @@ LL |     }
 LL | }
    |                                                     ^
 
-error: found a `{` in the middle of a let-chain
-  --> $DIR/brace-in-let-chain.rs:14:24
-   |
-LL |         && let () = () {
-   |                        ^
-LL |         && let () = ()
-   |         ------ you might have meant to continue the let-chain here
-   |
-help: consider removing this brace to parse the `let` as part of the same chain
-   |
-LL -         && let () = () {
-LL +         && let () = ()
-   |
-
-error: found a `{` in the middle of a let-chain
-  --> $DIR/brace-in-let-chain.rs:6:24
-   |
-LL |         && let () = () {
-   |                        ^
-LL |         && let () = ()
-   |         ------ you might have meant to continue the let-chain here
-   |
-help: consider removing this brace to parse the `let` as part of the same chain
-   |
-LL -         && let () = () {
-LL +         && let () = ()
-   |
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/circular_modules_main.stderr b/tests/ui/parser/circular_modules_main.stderr
index 2de70789358..e1780fe9fd9 100644
--- a/tests/ui/parser/circular_modules_main.stderr
+++ b/tests/ui/parser/circular_modules_main.stderr
@@ -4,22 +4,5 @@ error: circular modules: $DIR/circular_modules_main.rs -> $DIR/circular_modules_
 LL | mod circular_modules_main;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0425]: cannot find function `hi_str` in module `circular_modules_main`
-  --> $DIR/circular_modules_hello.rs:7:43
-   |
-LL |     println!("{}", circular_modules_main::hi_str());
-   |                                           ^^^^^^ not found in `circular_modules_main`
-   |
-help: consider importing this function
-   |
-LL + use hi_str;
-   |
-help: if you import `hi_str`, refer to it directly
-   |
-LL -     println!("{}", circular_modules_main::hi_str());
-LL +     println!("{}", hi_str());
-   |
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.rs b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.rs
index da1774acea5..41a7de03d4b 100644
--- a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.rs
+++ b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.rs
@@ -1,9 +1,11 @@
+// The diff marker detection was removed for this example, because it relied on
+// the lexer having a dependency on the parser, which was horrible.
+
 macro_rules! foo {
 <<<<<<< HEAD
-    //~^ ERROR encountered diff marker
     () {
 =======
     () { //
 >>>>>>> 7a4f13c blah blah blah
     }
-}
+} //~ this file contains an unclosed delimiter
diff --git a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr
index 927821ddfae..b33f2b5d1b8 100644
--- a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr
+++ b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr
@@ -1,23 +1,16 @@
-error: encountered diff marker
-  --> $DIR/unclosed-delims-in-macro.rs:2:1
+error: this file contains an unclosed delimiter
+  --> $DIR/unclosed-delims-in-macro.rs:11:48
    |
+LL | macro_rules! foo {
+   |                  - unclosed delimiter
 LL | <<<<<<< HEAD
-   | ^^^^^^^ between this marker and `=======` is the code that we're merging into
+LL |     () {
+   |        - this delimiter might not be properly closed...
 ...
-LL | =======
-   | ------- between this marker and `>>>>>>>` is the incoming code
-LL |     () { //
-LL | >>>>>>> 7a4f13c blah blah blah
-   | ^^^^^^^ this marker concludes the conflict region
-   |
-   = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
-           to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
-   = help: if you're having merge conflicts after pulling new code:
-           the top section is the code you already had and the bottom section is the remote code
-           if you're in the middle of a rebase:
-           the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased
-   = note: for an explanation on these markers from the `git` documentation:
-           visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
+LL | }
+   | -                                             ^
+   | |
+   | ...as it matches this but it has different indentation
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/diff-markers/unclosed-delims.rs b/tests/ui/parser/diff-markers/unclosed-delims.rs
index 7d400c3827b..827c1eebb9d 100644
--- a/tests/ui/parser/diff-markers/unclosed-delims.rs
+++ b/tests/ui/parser/diff-markers/unclosed-delims.rs
@@ -1,18 +1,12 @@
+// The diff marker detection was removed for this example, because it relied on
+// the lexer having a dependency on the parser, which was horrible.
+
 mod tests {
     #[test]
 <<<<<<< HEAD
-//~^ ERROR encountered diff marker
-//~| NOTE between this marker and `=======`
-
-//~| NOTE conflict markers indicate that
-//~| HELP if you're having merge conflicts
-//~| NOTE for an explanation on these markers
-
     fn test1() {
 =======
-//~^ NOTE between this marker and `>>>>>>>`
     fn test2() {
 >>>>>>> 7a4f13c blah blah blah
-//~^ NOTE this marker concludes the conflict region
     }
-}
+} //~ this file contains an unclosed delimiter
diff --git a/tests/ui/parser/diff-markers/unclosed-delims.stderr b/tests/ui/parser/diff-markers/unclosed-delims.stderr
index 1eab96442b4..b2541aa47ba 100644
--- a/tests/ui/parser/diff-markers/unclosed-delims.stderr
+++ b/tests/ui/parser/diff-markers/unclosed-delims.stderr
@@ -1,23 +1,16 @@
-error: encountered diff marker
-  --> $DIR/unclosed-delims.rs:3:1
+error: this file contains an unclosed delimiter
+  --> $DIR/unclosed-delims.rs:12:48
    |
-LL | <<<<<<< HEAD
-   | ^^^^^^^ between this marker and `=======` is the code that we're merging into
+LL | mod tests {
+   |           - unclosed delimiter
 ...
-LL | =======
-   | ------- between this marker and `>>>>>>>` is the incoming code
+LL |     fn test1() {
+   |                - this delimiter might not be properly closed...
 ...
-LL | >>>>>>> 7a4f13c blah blah blah
-   | ^^^^^^^ this marker concludes the conflict region
-   |
-   = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
-           to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
-   = help: if you're having merge conflicts after pulling new code:
-           the top section is the code you already had and the bottom section is the remote code
-           if you're in the middle of a rebase:
-           the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased
-   = note: for an explanation on these markers from the `git` documentation:
-           visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
+LL | }
+   | -                                             ^
+   | |
+   | ...as it matches this but it has different indentation
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/fn-arg-doc-comment.stderr b/tests/ui/parser/fn-arg-doc-comment.stderr
index c8d7e2efe79..1891c708903 100644
--- a/tests/ui/parser/fn-arg-doc-comment.stderr
+++ b/tests/ui/parser/fn-arg-doc-comment.stderr
@@ -30,15 +30,11 @@ note: function defined here
 LL |   pub fn f(
    |          ^
 LL | /     /// Comment
-LL | |
-LL | |
-LL | |
+...  |
 LL | |     id: u8,
    | |__________-
 LL | /     /// Other
-LL | |
-LL | |
-LL | |
+...  |
 LL | |     a: u8,
    | |_________-
 
diff --git a/tests/ui/privacy/effective_visibilities.stderr b/tests/ui/privacy/effective_visibilities.stderr
index 41d63532dea..6954279c05a 100644
--- a/tests/ui/privacy/effective_visibilities.stderr
+++ b/tests/ui/privacy/effective_visibilities.stderr
@@ -6,7 +6,6 @@ LL | | #![feature(rustc_attrs)]
 LL | |
 LL | | #[rustc_effective_visibility]
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/privacy/effective_visibilities_invariants.stderr b/tests/ui/privacy/effective_visibilities_invariants.stderr
index 1c19afdcdba..64d0402f84e 100644
--- a/tests/ui/privacy/effective_visibilities_invariants.stderr
+++ b/tests/ui/privacy/effective_visibilities_invariants.stderr
@@ -16,7 +16,6 @@ LL | / #![feature(staged_api)]
 LL | |
 LL | | pub mod m {}
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/privacy/issue-113860-1.stderr b/tests/ui/privacy/issue-113860-1.stderr
index c05452fb51c..dad9ebadf04 100644
--- a/tests/ui/privacy/issue-113860-1.stderr
+++ b/tests/ui/privacy/issue-113860-1.stderr
@@ -14,7 +14,6 @@ LL | |
 LL | |
 LL | | pub trait Trait {
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/privacy/issue-113860-2.stderr b/tests/ui/privacy/issue-113860-2.stderr
index c53c490ca1e..9805c22dbdf 100644
--- a/tests/ui/privacy/issue-113860-2.stderr
+++ b/tests/ui/privacy/issue-113860-2.stderr
@@ -14,7 +14,6 @@ LL | |
 LL | |
 LL | | pub trait Trait {
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/privacy/issue-113860.stderr b/tests/ui/privacy/issue-113860.stderr
index d813b740ac5..88efcae4a85 100644
--- a/tests/ui/privacy/issue-113860.stderr
+++ b/tests/ui/privacy/issue-113860.stderr
@@ -14,7 +14,6 @@ LL | |
 LL | |
 LL | | pub trait Trait {
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/raw-ref-op/amp-raw-without-mut-const-is-a-normal-borrow.rs b/tests/ui/raw-ref-op/amp-raw-without-mut-const-is-a-normal-borrow.rs
new file mode 100644
index 00000000000..9360146a0fc
--- /dev/null
+++ b/tests/ui/raw-ref-op/amp-raw-without-mut-const-is-a-normal-borrow.rs
@@ -0,0 +1,30 @@
+//! The token sequence `&raw` *only* starts a raw borrow expr if it's immediately
+//! followed by either `const` or `mut`. If that's not the case, the `&` denotes
+//! the start of a normal borrow expr where `raw` is interpreted as a regular
+//! identifier and thus denotes the start of a path expr.
+//!
+//! This test ensures that we never commit too early/overzealously in the parser
+//! when encountering the sequence `&raw` (even during parse error recovery) so
+//! as not to regress preexisting code.
+
+//@ check-pass
+
+fn main() { // the odd formatting in here is intentional
+    let raw = 0;
+    let _ = &raw;
+
+    let raw = 0;
+    let local = 1;
+    let _: i32 = &raw *local;
+
+    let raw = |_| ();
+    let local = [0];
+    let () = &raw (local[0]);
+}
+
+macro_rules! check {
+    ($e:expr) => { compile_error!("expr"); };
+    (&raw $e:expr) => {};
+}
+
+check!(&raw local);
diff --git a/tests/ui/raw-ref-op/never-place-isnt-diverging.stderr b/tests/ui/raw-ref-op/never-place-isnt-diverging.stderr
index af9e7889821..0a8340545eb 100644
--- a/tests/ui/raw-ref-op/never-place-isnt-diverging.stderr
+++ b/tests/ui/raw-ref-op/never-place-isnt-diverging.stderr
@@ -7,8 +7,7 @@ LL | /     unsafe {
 LL | |
 LL | |         let x: *const ! = 0 as _;
 LL | |         &raw const *x;
-LL | |         // Since `*x` is `!`, HIR typeck used to think that it diverges
-LL | |         // and allowed the block to coerce to any value, leading to UB.
+...  |
 LL | |     }
    | |_____^ expected type parameter `T`, found `()`
    |
diff --git a/tests/ui/reachable/artificial-block.rs b/tests/ui/reachable/artificial-block.rs
new file mode 100644
index 00000000000..6d73ba1a972
--- /dev/null
+++ b/tests/ui/reachable/artificial-block.rs
@@ -0,0 +1,30 @@
+//! Check that we don't get compile errors on unreachable code after the `{ return 3; }` artificial
+//! block below. This test is run-pass to also exercise the codegen, but it might be possible to
+//! reduce to build-pass or even check-pass.
+//!
+//! This test was introduced as part of commit `a833f152baa17460e8414355e832d30d5161f8e8` which
+//! removes an "artificial block". See also commit `3d738e9e0634a4cd6239d1317bd7dad53be68dc8` for
+//! more elaboration, reproduced below (this is outdated for *today*'s rustc as of 2024-12-10, but
+//! is helpful to understand the original intention):
+//!
+//! > Return a fresh, unreachable context after ret, break, and cont
+//! >
+//! > This ensures we don't get compile errors on unreachable code (see
+//! > test/run-pass/artificial-block.rs for an example of sane code that wasn't compiling). In the
+//! > future, we might want to warn about non-trivial code appearing in an unreachable context,
+//! > and/or avoid generating unreachable code altogether (though I'm sure LLVM will weed it out as
+//! > well).
+//!
+//! Since then, `ret` became `return`, `int` became `isize` and `assert` became a macro.
+
+//@ run-pass
+
+fn f() -> isize {
+    {
+        return 3;
+    }
+}
+
+fn main() {
+    assert_eq!(f(), 3);
+}
diff --git a/tests/ui/resolve/parse-error-resolve.rs b/tests/ui/resolve/parse-error-resolve.rs
new file mode 100644
index 00000000000..1e0772648af
--- /dev/null
+++ b/tests/ui/resolve/parse-error-resolve.rs
@@ -0,0 +1,7 @@
+mod parse_error;
+use parse_error::Canonical; // ok, `parse_error.rs` had parse errors
+
+fn main() {
+    let _ = "" + 1; //~ ERROR E0369
+    parse_error::Canonical.foo(); // ok, `parse_error.rs` had parse errors
+}
diff --git a/tests/ui/resolve/parse-error-resolve.stderr b/tests/ui/resolve/parse-error-resolve.stderr
new file mode 100644
index 00000000000..30475aa0ee6
--- /dev/null
+++ b/tests/ui/resolve/parse-error-resolve.stderr
@@ -0,0 +1,22 @@
+error: expected one of `+`, `,`, `::`, `=`, or `>`, found `From`
+  --> $DIR/parse_error.rs:2:46
+   |
+LL | impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {
+   |                                              ^^^^ expected one of `+`, `,`, `::`, `=`, or `>`
+   |
+help: you might have meant to end the type parameters here
+   |
+LL | impl<S: Into<std::borrow::Cow<'static, str>>> From<S> for Canonical {
+   |                                             +
+
+error[E0369]: cannot add `{integer}` to `&str`
+  --> $DIR/parse-error-resolve.rs:5:16
+   |
+LL |     let _ = "" + 1;
+   |             -- ^ - {integer}
+   |             |
+   |             &str
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/resolve/parse_error.rs b/tests/ui/resolve/parse_error.rs
new file mode 100644
index 00000000000..4cd025e1edf
--- /dev/null
+++ b/tests/ui/resolve/parse_error.rs
@@ -0,0 +1,5 @@
+struct Canonical;
+impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical { //~ ERROR expected
+    fn foo() {}
+}
+fn bar() {}
diff --git a/tests/ui/resolve/parse_error.stderr b/tests/ui/resolve/parse_error.stderr
new file mode 100644
index 00000000000..f764f08875f
--- /dev/null
+++ b/tests/ui/resolve/parse_error.stderr
@@ -0,0 +1,13 @@
+error: expected one of `+`, `,`, `::`, `=`, or `>`, found `From`
+  --> $DIR/parse_error.rs:2:46
+   |
+LL | impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {
+   |                                              ^^^^ expected one of `+`, `,`, `::`, `=`, or `>`
+   |
+help: you might have meant to end the type parameters here
+   |
+LL | impl<S: Into<std::borrow::Cow<'static, str>>> From<S> for Canonical {
+   |                                             +
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/return/issue-86188-return-not-in-fn-body.stderr b/tests/ui/return/issue-86188-return-not-in-fn-body.stderr
index 4f938670e5e..abbcc21141e 100644
--- a/tests/ui/return/issue-86188-return-not-in-fn-body.stderr
+++ b/tests/ui/return/issue-86188-return-not-in-fn-body.stderr
@@ -15,8 +15,7 @@ LL | /     fn bar() {
 LL | |
 LL | |         [(); return];
    | |              ^^^^^^ the return is part of this body...
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____- ...not the enclosing function body
 
@@ -27,8 +26,7 @@ LL | /     fn foo() {
 LL | |
 LL | |         [(); return];
    | |              ^^^^^^ the return is part of this body...
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____- ...not the enclosing function body
 
diff --git a/tests/ui/return/return-match-array-const.stderr b/tests/ui/return/return-match-array-const.stderr
index 85a733adfee..c2a0ada7098 100644
--- a/tests/ui/return/return-match-array-const.stderr
+++ b/tests/ui/return/return-match-array-const.stderr
@@ -2,13 +2,10 @@ error[E0572]: return statement outside of function body
   --> $DIR/return-match-array-const.rs:5:10
    |
 LL | / fn main() {
-LL | |
-LL | |
-LL | |
+...  |
 LL | |     [(); return match 0 { n => n }];
    | |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
 ...  |
-LL | |
 LL | | }
    | |_- ...not the enclosing function body
 
@@ -16,14 +13,10 @@ error[E0572]: return statement outside of function body
   --> $DIR/return-match-array-const.rs:9:10
    |
 LL | / fn main() {
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     [(); return match 0 { 0 => 0 }];
    | |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
 ...  |
-LL | |
 LL | | }
    | |_- ...not the enclosing function body
 
@@ -31,14 +24,10 @@ error[E0572]: return statement outside of function body
   --> $DIR/return-match-array-const.rs:13:10
    |
 LL | / fn main() {
-LL | |
-LL | |
-LL | |
 ...  |
 LL | |     [(); return match () { 'a' => 0, _ => 0 }];
    | |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
 ...  |
-LL | |
 LL | | }
    | |_- ...not the enclosing function body
 
diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr
index 635a9e06633..756de2b5a16 100644
--- a/tests/ui/return/tail-expr-as-potential-return.stderr
+++ b/tests/ui/return/tail-expr-as-potential-return.stderr
@@ -4,8 +4,7 @@ error[E0308]: mismatched types
 LL | /     if x {
 LL | |         Err(42)
    | |         ^^^^^^^ expected `()`, found `Result<_, {integer}>`
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____- expected this to be `()`
    |
@@ -22,8 +21,7 @@ error[E0308]: mismatched types
 LL | /     if true {
 LL | |         1i32
    | |         ^^^^ expected `()`, found `i32`
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____- expected this to be `()`
    |
@@ -38,8 +36,7 @@ error[E0308]: mismatched types
 LL | /     if x {
 LL | |         Err(42)
    | |         ^^^^^^^ expected `()`, found `Result<_, {integer}>`
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____- expected this to be `()`
    |
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/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr
index cceb3bddef4..874b32346af 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr
@@ -4,9 +4,7 @@ error: extern blocks must be unsafe
 LL | / extern "C" {
 LL | |
 LL | |     safe static TEST1: i32;
-LL | |
-LL | |     safe fn test1(i: i32);
-LL | |
+...  |
 LL | | }
    | |_^
 
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_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_nonnull.rs b/tests/ui/self/arbitrary_self_types_nonnull.rs
new file mode 100644
index 00000000000..ab1589b956e
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_nonnull.rs
@@ -0,0 +1,13 @@
+#![feature(arbitrary_self_types)]
+
+struct A;
+
+impl A {
+    fn m(self: std::ptr::NonNull<Self>) {}
+    //~^ ERROR: invalid `self` parameter type
+    fn n(self: &std::ptr::NonNull<Self>) {}
+    //~^ ERROR: invalid `self` parameter type
+}
+
+fn main() {
+}
diff --git a/tests/ui/self/arbitrary_self_types_nonnull.stderr b/tests/ui/self/arbitrary_self_types_nonnull.stderr
new file mode 100644
index 00000000000..5ebe58b4e48
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_nonnull.stderr
@@ -0,0 +1,23 @@
+error[E0307]: invalid `self` parameter type: `NonNull<A>`
+  --> $DIR/arbitrary_self_types_nonnull.rs:6:16
+   |
+LL |     fn m(self: std::ptr::NonNull<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>`
+   = note: `NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`
+
+error[E0307]: invalid `self` parameter type: `&NonNull<A>`
+  --> $DIR/arbitrary_self_types_nonnull.rs:8:16
+   |
+LL |     fn n(self: &std::ptr::NonNull<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>`
+   = note: `NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0307`.
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/arbitrary_self_types_weak.rs b/tests/ui/self/arbitrary_self_types_weak.rs
new file mode 100644
index 00000000000..91f2b9e0a95
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_weak.rs
@@ -0,0 +1,13 @@
+#![feature(arbitrary_self_types)]
+
+struct A;
+
+impl A {
+    fn m(self: std::rc::Weak<Self>) {}
+    //~^ ERROR: invalid `self` parameter type
+    fn n(self: std::sync::Weak<Self>) {}
+    //~^ ERROR: invalid `self` parameter type
+}
+
+fn main() {
+}
diff --git a/tests/ui/self/arbitrary_self_types_weak.stderr b/tests/ui/self/arbitrary_self_types_weak.stderr
new file mode 100644
index 00000000000..42d239419ad
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_weak.stderr
@@ -0,0 +1,23 @@
+error[E0307]: invalid `self` parameter type: `std::rc::Weak<A>`
+  --> $DIR/arbitrary_self_types_weak.rs:6:16
+   |
+LL |     fn m(self: std::rc::Weak<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>`
+   = note: `Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`
+
+error[E0307]: invalid `self` parameter type: `std::sync::Weak<A>`
+  --> $DIR/arbitrary_self_types_weak.rs:8:16
+   |
+LL |     fn n(self: std::sync::Weak<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>`
+   = note: `Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0307`.
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/specialization/min_specialization/issue-79224.rs b/tests/ui/specialization/min_specialization/issue-79224.rs
index 6ddd3d79ccf..15429bf60e5 100644
--- a/tests/ui/specialization/min_specialization/issue-79224.rs
+++ b/tests/ui/specialization/min_specialization/issue-79224.rs
@@ -1,6 +1,16 @@
 #![feature(min_specialization)]
 use std::fmt::{self, Display};
 
+pub trait ToString {
+    fn to_string(&self) -> String;
+}
+
+impl<T: Display + ?Sized> ToString for T {
+    default fn to_string(&self) -> String {
+        todo!()
+    }
+}
+
 pub enum Cow<'a, B: ?Sized + 'a, O = <B as ToOwned>::Owned>
 where
     B: ToOwned,
diff --git a/tests/ui/specialization/min_specialization/issue-79224.stderr b/tests/ui/specialization/min_specialization/issue-79224.stderr
index 84e526f4597..b2118ccd81b 100644
--- a/tests/ui/specialization/min_specialization/issue-79224.stderr
+++ b/tests/ui/specialization/min_specialization/issue-79224.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:18:29
+  --> $DIR/issue-79224.rs:28:29
    |
 LL | impl<B: ?Sized> Display for Cow<'_, B> {
    |                             ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
@@ -11,7 +11,7 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
    |                +++++++++++++++++++
 
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:20:5
+  --> $DIR/issue-79224.rs:30:5
    |
 LL |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `B`
@@ -23,7 +23,7 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
    |                +++++++++++++++++++
 
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:20:13
+  --> $DIR/issue-79224.rs:30:13
    |
 LL |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    |             ^^^^ the trait `Clone` is not implemented for `B`
@@ -35,14 +35,11 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
    |                +++++++++++++++++++
 
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:20:62
+  --> $DIR/issue-79224.rs:30:62
    |
 LL |       fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    |  ______________________________________________________________^
-LL | |
-LL | |
-LL | |
-LL | |         write!(f, "foo")
+...  |
 LL | |     }
    | |_____^ the trait `Clone` is not implemented for `B`
    |
diff --git a/tests/ui/stability-attribute/missing-stability-attr-at-top-level.stderr b/tests/ui/stability-attribute/missing-stability-attr-at-top-level.stderr
index 3af1e82d207..fb564932cd5 100644
--- a/tests/ui/stability-attribute/missing-stability-attr-at-top-level.stderr
+++ b/tests/ui/stability-attribute/missing-stability-attr-at-top-level.stderr
@@ -2,8 +2,7 @@ error: module has missing stability attribute
   --> $DIR/missing-stability-attr-at-top-level.rs:1:1
    |
 LL | / #![feature(staged_api)]
-LL | |
-LL | |
+...  |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr b/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr
index 018786dd26d..c954282cbc7 100644
--- a/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr
+++ b/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr
@@ -23,7 +23,6 @@ LL | |
 LL | |
 LL | | #[stable(feature = "a", since = "3.3.3")]
 ...  |
-LL | |
 LL | | fn main() {}
    | |____________^
 
diff --git a/tests/ui/stable-mir-print/async-closure.rs b/tests/ui/stable-mir-print/async-closure.rs
new file mode 100644
index 00000000000..7da532a359f
--- /dev/null
+++ b/tests/ui/stable-mir-print/async-closure.rs
@@ -0,0 +1,12 @@
+//@ compile-flags: -Z unpretty=stable-mir --crate-type lib -C panic=abort
+//@ check-pass
+//@ only-x86_64
+//@ edition: 2024
+//@ needs-unwind unwind edges are different with panic=abort
+
+pub fn foo() {
+    let y = 0;
+    let x = async || {
+        let y = y;
+    };
+}
diff --git a/tests/ui/stable-mir-print/async-closure.stdout b/tests/ui/stable-mir-print/async-closure.stdout
new file mode 100644
index 00000000000..21df1fd3954
--- /dev/null
+++ b/tests/ui/stable-mir-print/async-closure.stdout
@@ -0,0 +1,90 @@
+// WARNING: This is highly experimental output it's intended for stable-mir developers only.
+// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir.
+fn foo() -> () {
+    let mut _0: ();
+    let  _1: i32;
+    let  _2: {async closure@$DIR/async-closure.rs:9:13: 9:21};
+    let mut _3: &i32;
+    debug y => _1;
+    debug x => _2;
+    bb0: {
+        _1 = 0_i32;
+        _3 = &_1;
+        _2 = {coroutine-closure@$DIR/async-closure.rs:9:13: 9:21}(move _3);
+        return;
+    }
+}
+fn foo::{closure#0}(_1: &{async closure@$DIR/async-closure.rs:9:13: 9:21}) -> {async closure body@$DIR/async-closure.rs:9:22: 11:6} {
+    let mut _0: {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+    let mut _2: &i32;
+    debug y => (*((*_1).0: &i32));
+    bb0: {
+        _2 = CopyForDeref(((*_1).0: &i32));
+        _0 = {coroutine@$DIR/async-closure.rs:9:22: 11:6}(_2);
+        return;
+    }
+}
+fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
+    let mut _0: Poll<()>;
+    let  _3: i32;
+    let mut _4: &i32;
+    let mut _5: u32;
+    let mut _6: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+    let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+    let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+    debug _task_context => _2;
+    debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32));
+    debug y => _3;
+    bb0: {
+        _6 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
+        _5 = discriminant((*_6));
+        switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3];
+    }
+    bb1: {
+        _7 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
+        _4 = CopyForDeref(((*_7).0: &i32));
+        _3 = (*_4);
+        _0 = std::task::Poll::Ready(());
+        _8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
+        discriminant((*_8) = 1;
+        return;
+    }
+    bb2: {
+        assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable];
+    }
+    bb3: {
+        unreachable;
+    }
+}
+fn foo::{closure#0}::{closure#1}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
+    let mut _0: Poll<()>;
+    let  _3: i32;
+    let mut _4: &i32;
+    let mut _5: u32;
+    let mut _6: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+    let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+    let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+    debug _task_context => _2;
+    debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32));
+    debug y => _3;
+    bb0: {
+        _6 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
+        _5 = discriminant((*_6));
+        switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3];
+    }
+    bb1: {
+        _7 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
+        _4 = CopyForDeref(((*_7).0: &i32));
+        _3 = (*_4);
+        _0 = std::task::Poll::Ready(());
+        _8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
+        discriminant((*_8) = 1;
+        return;
+    }
+    bb2: {
+        assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable];
+    }
+    bb3: {
+        unreachable;
+    }
+}
diff --git a/tests/ui/stable-mir-print/operands.stdout b/tests/ui/stable-mir-print/operands.stdout
index 3c27878b3cf..c3b1151ae24 100644
--- a/tests/ui/stable-mir-print/operands.stdout
+++ b/tests/ui/stable-mir-print/operands.stdout
@@ -5,187 +5,183 @@ fn operands(_1: u8) -> () {
     let  _2: [u8; 10];
     let  _3: u8;
     let  _4: usize;
-    let mut _5: usize;
-    let mut _6: bool;
-    let  _7: u8;
-    let  _8: usize;
-    let mut _9: (usize, bool);
-    let mut _10: usize;
-    let mut _11: bool;
-    let mut _12: (&u8, &u8);
-    let mut _13: &u8;
-    let mut _14: &u8;
-    let  _15: &u8;
-    let  _16: &u8;
-    let mut _17: bool;
-    let mut _18: u8;
-    let mut _19: u8;
-    let  _20: core::panicking::AssertKind;
-    let  _21: !;
-    let mut _22: Option<Arguments<'_>>;
-    let  _23: &u8;
-    let  _24: u8;
-    let mut _25: (&u8, &u8);
-    let mut _26: &u8;
-    let mut _27: &u8;
-    let  _28: &u8;
-    let  _29: &u8;
-    let mut _30: bool;
-    let mut _31: u8;
-    let mut _32: u8;
-    let  _33: core::panicking::AssertKind;
-    let  _34: !;
-    let mut _35: Option<Arguments<'_>>;
-    let  _36: (u8, u8);
-    let  _37: u8;
-    let  _38: u8;
-    let mut _39: (&u8, &u8);
-    let mut _40: &u8;
-    let mut _41: &u8;
-    let  _42: &u8;
-    let  _43: &u8;
-    let mut _44: bool;
-    let mut _45: u8;
-    let mut _46: u8;
-    let  _47: core::panicking::AssertKind;
-    let  _48: !;
-    let mut _49: Option<Arguments<'_>>;
-    let  _50: usize;
-    let mut _51: &[u8];
-    let mut _52: &[u8; 10];
-    let  _53: usize;
-    let  _54: &usize;
-    let mut _55: (&usize, &usize);
-    let mut _56: &usize;
-    let mut _57: &usize;
-    let  _58: &usize;
-    let  _59: &usize;
-    let mut _60: bool;
-    let mut _61: usize;
-    let mut _62: usize;
-    let  _63: core::panicking::AssertKind;
-    let  _64: !;
-    let mut _65: Option<Arguments<'_>>;
+    let mut _5: bool;
+    let  _6: u8;
+    let  _7: usize;
+    let mut _8: (usize, bool);
+    let mut _9: bool;
+    let mut _10: (&u8, &u8);
+    let mut _11: &u8;
+    let mut _12: &u8;
+    let  _13: &u8;
+    let  _14: &u8;
+    let mut _15: bool;
+    let mut _16: u8;
+    let mut _17: u8;
+    let  _18: core::panicking::AssertKind;
+    let  _19: !;
+    let mut _20: Option<Arguments<'_>>;
+    let  _21: &u8;
+    let  _22: u8;
+    let mut _23: (&u8, &u8);
+    let mut _24: &u8;
+    let mut _25: &u8;
+    let  _26: &u8;
+    let  _27: &u8;
+    let mut _28: bool;
+    let mut _29: u8;
+    let mut _30: u8;
+    let  _31: core::panicking::AssertKind;
+    let  _32: !;
+    let mut _33: Option<Arguments<'_>>;
+    let  _34: (u8, u8);
+    let  _35: u8;
+    let  _36: u8;
+    let mut _37: (&u8, &u8);
+    let mut _38: &u8;
+    let mut _39: &u8;
+    let  _40: &u8;
+    let  _41: &u8;
+    let mut _42: bool;
+    let mut _43: u8;
+    let mut _44: u8;
+    let  _45: core::panicking::AssertKind;
+    let  _46: !;
+    let mut _47: Option<Arguments<'_>>;
+    let  _48: usize;
+    let mut _49: &[u8];
+    let mut _50: &[u8; 10];
+    let  _51: usize;
+    let  _52: &usize;
+    let mut _53: (&usize, &usize);
+    let mut _54: &usize;
+    let mut _55: &usize;
+    let  _56: &usize;
+    let  _57: &usize;
+    let mut _58: bool;
+    let mut _59: usize;
+    let mut _60: usize;
+    let  _61: core::panicking::AssertKind;
+    let  _62: !;
+    let mut _63: Option<Arguments<'_>>;
     debug val => _1;
     debug array => _2;
     debug first => _3;
-    debug last => _7;
-    debug left_val => _15;
-    debug right_val => _16;
-    debug kind => _20;
-    debug reference => _23;
-    debug dereferenced => _24;
-    debug left_val => _28;
-    debug right_val => _29;
-    debug kind => _33;
-    debug tuple => _36;
-    debug first_again => _37;
-    debug first_again_again => _38;
-    debug left_val => _42;
-    debug right_val => _43;
-    debug kind => _47;
-    debug length => _50;
-    debug size_of => _53;
-    debug left_val => _58;
-    debug right_val => _59;
-    debug kind => _63;
+    debug last => _6;
+    debug left_val => _13;
+    debug right_val => _14;
+    debug kind => _18;
+    debug reference => _21;
+    debug dereferenced => _22;
+    debug left_val => _26;
+    debug right_val => _27;
+    debug kind => _31;
+    debug tuple => _34;
+    debug first_again => _35;
+    debug first_again_again => _36;
+    debug left_val => _40;
+    debug right_val => _41;
+    debug kind => _45;
+    debug length => _48;
+    debug size_of => _51;
+    debug left_val => _56;
+    debug right_val => _57;
+    debug kind => _61;
     bb0: {
         _2 = [_1; 10];
         _4 = 0_usize;
-        _5 = 10_usize;
-        _6 = Lt(_4, _5);
-        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
+        _5 = Lt(_4, 10_usize);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", 10_usize, _4) -> [success: bb1, unwind unreachable];
     }
     bb1: {
         _3 = _2[_4];
-        _9 = CheckedSub(10_usize, 1_usize);
-        assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable];
+        _8 = CheckedSub(10_usize, 1_usize);
+        assert(!move (_8.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable];
     }
     bb2: {
-        _8 = move (_9.0: usize);
-        _10 = 10_usize;
-        _11 = Lt(_8, _10);
-        assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _8) -> [success: bb3, unwind unreachable];
+        _7 = move (_8.0: usize);
+        _9 = Lt(_7, 10_usize);
+        assert(move _9, "index out of bounds: the length is {} but the index is {}", 10_usize, _7) -> [success: bb3, unwind unreachable];
     }
     bb3: {
-        _7 = _2[_8];
-        _13 = &_3;
-        _14 = &_7;
-        _12 = (move _13, move _14);
-        _15 = (_12.0: &u8);
-        _16 = (_12.1: &u8);
-        _18 = (*_15);
-        _19 = (*_16);
-        _17 = Eq(move _18, move _19);
-        switchInt(move _17) -> [0: bb5, otherwise: bb4];
+        _6 = _2[_7];
+        _11 = &_3;
+        _12 = &_6;
+        _10 = (move _11, move _12);
+        _13 = (_10.0: &u8);
+        _14 = (_10.1: &u8);
+        _16 = (*_13);
+        _17 = (*_14);
+        _15 = Eq(move _16, move _17);
+        switchInt(move _15) -> [0: bb5, otherwise: bb4];
     }
     bb4: {
-        _23 = &_3;
-        _24 = (*_23);
-        _26 = &_24;
-        _27 = &_3;
-        _25 = (move _26, move _27);
-        _28 = (_25.0: &u8);
-        _29 = (_25.1: &u8);
-        _31 = (*_28);
-        _32 = (*_29);
-        _30 = Eq(move _31, move _32);
-        switchInt(move _30) -> [0: bb7, otherwise: bb6];
+        _21 = &_3;
+        _22 = (*_21);
+        _24 = &_22;
+        _25 = &_3;
+        _23 = (move _24, move _25);
+        _26 = (_23.0: &u8);
+        _27 = (_23.1: &u8);
+        _29 = (*_26);
+        _30 = (*_27);
+        _28 = Eq(move _29, move _30);
+        switchInt(move _28) -> [0: bb7, otherwise: bb6];
     }
     bb5: {
-        _20 = core::panicking::AssertKind::Eq;
-        _22 = std::option::Option::None;
-        _21 = core::panicking::assert_failed::<u8, u8>(move _20, _15, _16, move _22) -> unwind unreachable;
+        _18 = core::panicking::AssertKind::Eq;
+        _20 = std::option::Option::None;
+        _19 = core::panicking::assert_failed::<u8, u8>(move _18, _13, _14, move _20) -> unwind unreachable;
     }
     bb6: {
-        _36 = (_3, _7);
-        _37 = (_36.0: u8);
-        _38 = (_36.0: u8);
-        _40 = &_37;
-        _41 = &_38;
-        _39 = (move _40, move _41);
-        _42 = (_39.0: &u8);
-        _43 = (_39.1: &u8);
-        _45 = (*_42);
-        _46 = (*_43);
-        _44 = Eq(move _45, move _46);
-        switchInt(move _44) -> [0: bb9, otherwise: bb8];
+        _34 = (_3, _6);
+        _35 = (_34.0: u8);
+        _36 = (_34.0: u8);
+        _38 = &_35;
+        _39 = &_36;
+        _37 = (move _38, move _39);
+        _40 = (_37.0: &u8);
+        _41 = (_37.1: &u8);
+        _43 = (*_40);
+        _44 = (*_41);
+        _42 = Eq(move _43, move _44);
+        switchInt(move _42) -> [0: bb9, otherwise: bb8];
     }
     bb7: {
-        _33 = core::panicking::AssertKind::Eq;
-        _35 = std::option::Option::None;
-        _34 = core::panicking::assert_failed::<u8, u8>(move _33, _28, _29, move _35) -> unwind unreachable;
+        _31 = core::panicking::AssertKind::Eq;
+        _33 = std::option::Option::None;
+        _32 = core::panicking::assert_failed::<u8, u8>(move _31, _26, _27, move _33) -> unwind unreachable;
     }
     bb8: {
-        _52 = &_2;
-        _51 = move _52 as &[u8];
-        _50 = PtrMetadata(move _51);
-        _54 = &_50;
-        _53 = std::mem::size_of_val::<usize>(_54) -> [return: bb10, unwind unreachable];
+        _50 = &_2;
+        _49 = move _50 as &[u8];
+        _48 = PtrMetadata(move _49);
+        _52 = &_48;
+        _51 = std::mem::size_of_val::<usize>(_52) -> [return: bb10, unwind unreachable];
     }
     bb9: {
-        _47 = core::panicking::AssertKind::Eq;
-        _49 = std::option::Option::None;
-        _48 = core::panicking::assert_failed::<u8, u8>(move _47, _42, _43, move _49) -> unwind unreachable;
+        _45 = core::panicking::AssertKind::Eq;
+        _47 = std::option::Option::None;
+        _46 = core::panicking::assert_failed::<u8, u8>(move _45, _40, _41, move _47) -> unwind unreachable;
     }
     bb10: {
-        _56 = &_50;
-        _57 = &_53;
-        _55 = (move _56, move _57);
-        _58 = (_55.0: &usize);
-        _59 = (_55.1: &usize);
-        _61 = (*_58);
-        _62 = (*_59);
-        _60 = Eq(move _61, move _62);
-        switchInt(move _60) -> [0: bb12, otherwise: bb11];
+        _54 = &_48;
+        _55 = &_51;
+        _53 = (move _54, move _55);
+        _56 = (_53.0: &usize);
+        _57 = (_53.1: &usize);
+        _59 = (*_56);
+        _60 = (*_57);
+        _58 = Eq(move _59, move _60);
+        switchInt(move _58) -> [0: bb12, otherwise: bb11];
     }
     bb11: {
         return;
     }
     bb12: {
-        _63 = core::panicking::AssertKind::Eq;
-        _65 = std::option::Option::None;
-        _64 = core::panicking::assert_failed::<usize, usize>(move _63, _58, _59, move _65) -> unwind unreachable;
+        _61 = core::panicking::AssertKind::Eq;
+        _63 = std::option::Option::None;
+        _62 = core::panicking::assert_failed::<usize, usize>(move _61, _56, _57, move _63) -> unwind unreachable;
     }
 }
 fn operands::{constant#0}() -> usize {
diff --git a/tests/ui/static/issue-24446.stderr b/tests/ui/static/issue-24446.stderr
index 9c206e5ef3c..8cb034000be 100644
--- a/tests/ui/static/issue-24446.stderr
+++ b/tests/ui/static/issue-24446.stderr
@@ -20,10 +20,7 @@ error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot b
    |
 LL |       static foo: dyn Fn() -> u32 = || -> u32 {
    |  ___________________________________^
-LL | |
-LL | |
-LL | |
-LL | |
+...  |
 LL | |         0
 LL | |     };
    | |_____^ doesn't have a size known at compile-time
@@ -36,10 +33,7 @@ error[E0308]: mismatched types
    |
 LL |       static foo: dyn Fn() -> u32 = || -> u32 {
    |  ___________________________________^
-LL | |
-LL | |
-LL | |
-LL | |
+...  |
 LL | |         0
 LL | |     };
    | |_____^ expected `dyn Fn`, found closure
diff --git a/tests/ui/structs/auxiliary/struct_field_default.rs b/tests/ui/structs/default-field-values/auxiliary/struct_field_default.rs
index b315df5dba2..b315df5dba2 100644
--- a/tests/ui/structs/auxiliary/struct_field_default.rs
+++ b/tests/ui/structs/default-field-values/auxiliary/struct_field_default.rs
diff --git a/tests/ui/structs/default-field-values-failures.rs b/tests/ui/structs/default-field-values/failures.rs
index 0ac071d91d6..0ac071d91d6 100644
--- a/tests/ui/structs/default-field-values-failures.rs
+++ b/tests/ui/structs/default-field-values/failures.rs
diff --git a/tests/ui/structs/default-field-values-failures.stderr b/tests/ui/structs/default-field-values/failures.stderr
index 5b9d2df5a5d..65ec100fe2e 100644
--- a/tests/ui/structs/default-field-values-failures.stderr
+++ b/tests/ui/structs/default-field-values/failures.stderr
@@ -1,5 +1,5 @@
 error: the `#[default]` attribute may only be used on unit enum variants or variants where every field has a default value
-  --> $DIR/default-field-values-failures.rs:47:5
+  --> $DIR/failures.rs:47:5
    |
 LL |     Variant {}
    |     ^^^^^^^
@@ -7,7 +7,7 @@ LL |     Variant {}
    = help: consider a manual implementation of `Default`
 
 error: generic parameters may not be used in const operations
-  --> $DIR/default-field-values-failures.rs:22:23
+  --> $DIR/failures.rs:22:23
    |
 LL |     bat: i32 = <Qux<{ C }> as T>::K,
    |                       ^ cannot perform const operation using `C`
@@ -16,19 +16,19 @@ LL |     bat: i32 = <Qux<{ C }> as T>::K,
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: default fields are not supported in tuple structs
-  --> $DIR/default-field-values-failures.rs:26:22
+  --> $DIR/failures.rs:26:22
    |
 LL | pub struct Rak(i32 = 42);
    |                      ^^ default fields are only supported on structs
 
 error: generic `Self` types are currently not permitted in anonymous constants
-  --> $DIR/default-field-values-failures.rs:20:14
+  --> $DIR/failures.rs:20:14
    |
 LL |     bar: S = Self::S,
    |              ^^^^
 
 error[E0277]: the trait bound `S: Default` is not satisfied
-  --> $DIR/default-field-values-failures.rs:14:5
+  --> $DIR/failures.rs:14:5
    |
 LL | #[derive(Debug, Default)]
    |                 ------- in this derive macro expansion
@@ -44,13 +44,13 @@ LL | pub struct S;
    |
 
 error: missing mandatory field `bar`
-  --> $DIR/default-field-values-failures.rs:53:21
+  --> $DIR/failures.rs:53:21
    |
 LL |     let _ = Bar { .. };
    |                     ^
 
 error[E0308]: mismatched types
-  --> $DIR/default-field-values-failures.rs:57:17
+  --> $DIR/failures.rs:57:17
    |
 LL |     let _ = Rak(..);
    |             --- ^^ expected `i32`, found `RangeFull`
@@ -58,29 +58,29 @@ LL |     let _ = Rak(..);
    |             arguments to this struct are incorrect
    |
 note: tuple struct defined here
-  --> $DIR/default-field-values-failures.rs:26:12
+  --> $DIR/failures.rs:26:12
    |
 LL | pub struct Rak(i32 = 42);
    |            ^^^
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/default-field-values-failures.rs:57:17
+  --> $DIR/failures.rs:57:17
    |
 LL |     let _ = Rak(..);
    |                 ^^
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
-  --> $DIR/default-field-values-failures.rs:59:13
+  --> $DIR/failures.rs:59:13
    |
 LL |     let _ = Rak(0, ..);
    |             ^^^    -- unexpected argument #2 of type `RangeFull`
    |
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/default-field-values-failures.rs:59:20
+  --> $DIR/failures.rs:59:20
    |
 LL |     let _ = Rak(0, ..);
    |                    ^^
 note: tuple struct defined here
-  --> $DIR/default-field-values-failures.rs:26:12
+  --> $DIR/failures.rs:26:12
    |
 LL | pub struct Rak(i32 = 42);
    |            ^^^
@@ -91,18 +91,18 @@ LL +     let _ = Rak(0);
    |
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
-  --> $DIR/default-field-values-failures.rs:61:13
+  --> $DIR/failures.rs:61:13
    |
 LL |     let _ = Rak(.., 0);
    |             ^^^ -- unexpected argument #1 of type `RangeFull`
    |
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/default-field-values-failures.rs:61:17
+  --> $DIR/failures.rs:61:17
    |
 LL |     let _ = Rak(.., 0);
    |                 ^^
 note: tuple struct defined here
-  --> $DIR/default-field-values-failures.rs:26:12
+  --> $DIR/failures.rs:26:12
    |
 LL | pub struct Rak(i32 = 42);
    |            ^^^
diff --git a/tests/ui/structs/default-field-values-invalid-const.rs b/tests/ui/structs/default-field-values/invalid-const.rs
index 203a712868b..203a712868b 100644
--- a/tests/ui/structs/default-field-values-invalid-const.rs
+++ b/tests/ui/structs/default-field-values/invalid-const.rs
diff --git a/tests/ui/structs/default-field-values-invalid-const.stderr b/tests/ui/structs/default-field-values/invalid-const.stderr
index 47f25a1f38e..f4a3437031b 100644
--- a/tests/ui/structs/default-field-values-invalid-const.stderr
+++ b/tests/ui/structs/default-field-values/invalid-const.stderr
@@ -1,13 +1,13 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/default-field-values-invalid-const.rs:5:19
+  --> $DIR/invalid-const.rs:5:19
    |
 LL |     pub bax: u8 = panic!("asdf"),
-   |                   ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/default-field-values-invalid-const.rs:5:19
+   |                   ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/invalid-const.rs:5:19
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of `Baz::<C>::bat::{constant#0}` failed
-  --> $DIR/default-field-values-invalid-const.rs:11:19
+  --> $DIR/invalid-const.rs:11:19
    |
 LL |     pub bat: u8 = 130 + 130,
    |                   ^^^^^^^^^ attempt to compute `130_u8 + 130_u8`, which would overflow
diff --git a/tests/ui/structs/default-field-values-support.rs b/tests/ui/structs/default-field-values/support.rs
index 8209d6dd4a0..8209d6dd4a0 100644
--- a/tests/ui/structs/default-field-values-support.rs
+++ b/tests/ui/structs/default-field-values/support.rs
diff --git a/tests/ui/structs/default-field-values/use-normalized-ty-for-default-struct-value.rs b/tests/ui/structs/default-field-values/use-normalized-ty-for-default-struct-value.rs
new file mode 100644
index 00000000000..bb14524608d
--- /dev/null
+++ b/tests/ui/structs/default-field-values/use-normalized-ty-for-default-struct-value.rs
@@ -0,0 +1,17 @@
+//@ check-pass
+
+#![feature(default_field_values)]
+
+struct Value<const VALUE: u8>;
+
+impl<const VALUE: u8> Value<VALUE> {
+    pub const VALUE: Self = Self;
+}
+
+pub struct WithUse {
+    _use: Value<{ 0 + 0 }> = Value::VALUE
+}
+
+const _: WithUse = WithUse { .. };
+
+fn main() {}
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/if-then-neeing-semi.stderr b/tests/ui/suggestions/if-then-neeing-semi.stderr
index 6833e0bab2b..0556d6c50b1 100644
--- a/tests/ui/suggestions/if-then-neeing-semi.stderr
+++ b/tests/ui/suggestions/if-then-neeing-semi.stderr
@@ -6,12 +6,10 @@ LL |       let _ = if true {
 LL | |
 LL | |         async_dummy();
    | |         -------------- expected because of this
-LL | |
-LL | |     } else {
+...  |
 LL | |         async_dummy()
    | |         ^^^^^^^^^^^^^ expected `()`, found future
 ...  |
-LL | |
 LL | |     };
    | |_____- `if` and `else` have incompatible types
    |
@@ -38,12 +36,10 @@ LL |       let _ = if true {
 LL | |
 LL | |         async_dummy();
    | |         -------------- expected because of this
-LL | |
-LL | |     } else {
+...  |
 LL | |         async_dummy2()
    | |         ^^^^^^^^^^^^^^ expected `()`, found future
 ...  |
-LL | |
 LL | |     };
    | |_____- `if` and `else` have incompatible types
    |
@@ -72,12 +68,10 @@ LL |       let _ = if true {
 LL | |
 LL | |         async_dummy()
    | |         ------------- expected because of this
-LL | |
-LL | |     } else {
+...  |
 LL | |         async_dummy2()
    | |         ^^^^^^^^^^^^^^ expected future, found a different future
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____- `if` and `else` have incompatible types
    |
@@ -101,8 +95,7 @@ LL | |         dummy();
    | |         |      |
    | |         |      help: consider removing this semicolon
    | |         expected because of this
-LL | |
-LL | |     } else {
+...  |
 LL | |         dummy()
    | |         ^^^^^^^ expected `()`, found `i32`
 LL | |
diff --git a/tests/ui/suggestions/match-prev-arm-needing-semi.stderr b/tests/ui/suggestions/match-prev-arm-needing-semi.stderr
index cf3cf45ef40..f70f6a1e157 100644
--- a/tests/ui/suggestions/match-prev-arm-needing-semi.stderr
+++ b/tests/ui/suggestions/match-prev-arm-needing-semi.stderr
@@ -6,12 +6,10 @@ LL |       let _ = match true {
 LL | |         true => {
 LL | |             async_dummy();
    | |             -------------- this is found to be of type `()`
-LL | |
-LL | |         }
+...  |
 LL | |         false => async_dummy(),
    | |                  ^^^^^^^^^^^^^ expected `()`, found future
 ...  |
-LL | |
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
@@ -38,12 +36,10 @@ LL |       let _ = match true {
 LL | |         true => {
 LL | |             async_dummy();
    | |             -------------- this is found to be of type `()`
-LL | |
-LL | |         }
+...  |
 LL | |         false => async_dummy2(),
    | |                  ^^^^^^^^^^^^^^ expected `()`, found future
 ...  |
-LL | |
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
@@ -74,8 +70,7 @@ LL | |         true => async_dummy(),
 LL | |
 LL | |         false => async_dummy2(),
    | |                  ^^^^^^^^^^^^^^ expected future, found a different future
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
@@ -98,8 +93,7 @@ LL | |             dummy();
    | |             |      |
    | |             |      help: consider removing this semicolon
    | |             this is found to be of type `()`
-LL | |
-LL | |         }
+...  |
 LL | |         false => dummy(),
    | |                  ^^^^^^^ expected `()`, found `i32`
 LL | |
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-deref-in-match-issue-132784.rs b/tests/ui/suggestions/suggest-deref-in-match-issue-132784.rs
new file mode 100644
index 00000000000..205e57f4a9f
--- /dev/null
+++ b/tests/ui/suggestions/suggest-deref-in-match-issue-132784.rs
@@ -0,0 +1,84 @@
+use std::sync::Arc;
+fn main() {
+    let mut x = Arc::new(Some(1));
+    match x {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+
+    match &x {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+
+    let mut y = Box::new(Some(1));
+    match y {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+
+    let mut z = Arc::new(Some(1));
+    match z as Arc<Option<i32>> {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+
+    let z_const: &Arc<Option<i32>> = &z;
+    match z_const {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+
+    // Normal reference because Arc doesn't implement DerefMut.
+    let z_mut: &mut Arc<Option<i32>> = &mut z;
+    match z_mut {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+
+    // Mutable reference because Box does implement DerefMut.
+    let y_mut: &mut Box<Option<i32>> = &mut y;
+    match y_mut {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+
+    // Difficult expression.
+    let difficult = Arc::new(Some(1));
+    match (& (&difficult)  ) {
+        //~^ HELP consider dereferencing to access the inner value using the Deref trait
+        //~| HELP consider dereferencing to access the inner value using the Deref trait
+        Some(_) => {}
+        //~^ ERROR mismatched types
+        None => {}
+        //~^ ERROR mismatched types
+    }
+}
diff --git a/tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr b/tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr
new file mode 100644
index 00000000000..9338ef19089
--- /dev/null
+++ b/tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr
@@ -0,0 +1,259 @@
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:7:9
+   |
+LL |     match x {
+   |           - this expression has type `Arc<Option<{integer}>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match *x {
+   |           ~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:9:9
+   |
+LL |     match x {
+   |           - this expression has type `Arc<Option<{integer}>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match *x {
+   |           ~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:16:9
+   |
+LL |     match &x {
+   |           -- this expression has type `&Arc<Option<{integer}>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &*x {
+   |           ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:18:9
+   |
+LL |     match &x {
+   |           -- this expression has type `&Arc<Option<{integer}>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &*x {
+   |           ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:26:9
+   |
+LL |     match y {
+   |           - this expression has type `Box<Option<{integer}>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Box<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Box<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match *y {
+   |           ~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:28:9
+   |
+LL |     match y {
+   |           - this expression has type `Box<Option<{integer}>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Box<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Box<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match *y {
+   |           ~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:36:9
+   |
+LL |     match z as Arc<Option<i32>> {
+   |           --------------------- this expression has type `Arc<Option<i32>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Arc<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match *(z as Arc<Option<i32>>) {
+   |           ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:38:9
+   |
+LL |     match z as Arc<Option<i32>> {
+   |           --------------------- this expression has type `Arc<Option<i32>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Arc<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match *(z as Arc<Option<i32>>) {
+   |           ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:46:9
+   |
+LL |     match z_const {
+   |           ------- this expression has type `&Arc<Option<i32>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Arc<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &**z_const {
+   |           ~~~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:48:9
+   |
+LL |     match z_const {
+   |           ------- this expression has type `&Arc<Option<i32>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Arc<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &**z_const {
+   |           ~~~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:57:9
+   |
+LL |     match z_mut {
+   |           ----- this expression has type `&mut Arc<Option<i32>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Arc<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &**z_mut {
+   |           ~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:59:9
+   |
+LL |     match z_mut {
+   |           ----- this expression has type `&mut Arc<Option<i32>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Arc<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &**z_mut {
+   |           ~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:68:9
+   |
+LL |     match y_mut {
+   |           ----- this expression has type `&mut Box<Option<i32>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Box<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Box<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &**y_mut {
+   |           ~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:70:9
+   |
+LL |     match y_mut {
+   |           ----- this expression has type `&mut Box<Option<i32>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Box<Option<i32>>`, found `Option<_>`
+   |
+   = note: expected struct `Box<Option<i32>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &**y_mut {
+   |           ~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:79:9
+   |
+LL |     match (& (&difficult)  ) {
+   |           ------------------ this expression has type `&&Arc<Option<{integer}>>`
+...
+LL |         Some(_) => {}
+   |         ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &*difficult {
+   |           ~~~~~~~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-deref-in-match-issue-132784.rs:81:9
+   |
+LL |     match (& (&difficult)  ) {
+   |           ------------------ this expression has type `&&Arc<Option<{integer}>>`
+...
+LL |         None => {}
+   |         ^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
+   |
+   = note: expected struct `Arc<Option<{integer}>>`
+                found enum `Option<_>`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     match &*difficult {
+   |           ~~~~~~~~~~~
+
+error: aborting due to 16 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
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/suggestions/try-operator-dont-suggest-semicolon.stderr b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr
index 939285498fb..a275f0c2fa8 100644
--- a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr
+++ b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr
@@ -13,9 +13,7 @@ LL | /     if true {
 LL | |
 LL | |         x?
    | |         ^^ expected `()`, found integer
-LL | |
-LL | |
-LL | |
+...  |
 LL | |     }
    | |_____- expected this to be `()`
    |
diff --git a/tests/ui/symbol-names/types.legacy.stderr b/tests/ui/symbol-names/types.legacy.stderr
index 87c3acae0bd..c368b318609 100644
--- a/tests/ui/symbol-names/types.legacy.stderr
+++ b/tests/ui/symbol-names/types.legacy.stderr
@@ -502,5 +502,23 @@ error: demangling-alt(a::b::Type<[T; N]>)
 LL |     #[rustc_symbol_name]
    |     ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 84 previous errors
+error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E)
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<[u8; 0]>::h[HASH])
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<[u8; 0]>)
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 87 previous errors
 
diff --git a/tests/ui/symbol-names/types.rs b/tests/ui/symbol-names/types.rs
index 7ed19e0e5a8..38735e1aa50 100644
--- a/tests/ui/symbol-names/types.rs
+++ b/tests/ui/symbol-names/types.rs
@@ -266,6 +266,17 @@ pub fn b() {
     //[v0]~| ERROR ::b::Type<[_; _]>>)
     //[v0]~| ERROR demangling-alt(<a::b::Type<[_; _]>>)
     impl<const N: usize, T> Type<[T; N]> {}
+
+    const ZERO: usize = 0;
+
+    #[rustc_symbol_name]
+    //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$
+    //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<[u8; 0]>::
+    //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<[u8; 0]>)
+    //[v0]~^^^^ ERROR symbol-name(_RMsq_NvCsCRATE_HASH_1a1bINtB<REF>_4TypeAhj0_E)
+    //[v0]~| ERROR ::b::Type<[u8; 0usize]>>)
+    //[v0]~| ERROR demangling-alt(<a::b::Type<[u8; 0]>>)
+    impl Type<[u8; ZERO]> {}
 }
 
 fn main() {}
diff --git a/tests/ui/symbol-names/types.v0.stderr b/tests/ui/symbol-names/types.v0.stderr
index 58680e00202..90012a2dcf7 100644
--- a/tests/ui/symbol-names/types.v0.stderr
+++ b/tests/ui/symbol-names/types.v0.stderr
@@ -502,5 +502,23 @@ error: demangling-alt(<a::b::Type<[_; _]>>)
 LL |     #[rustc_symbol_name]
    |     ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 84 previous errors
+error: symbol-name(_RMsq_NvCsCRATE_HASH_1a1bINtB<REF>_4TypeAhj0_E)
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(<a[HASH]::b::Type<[u8; 0usize]>>)
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(<a::b::Type<[u8; 0]>>)
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 87 previous errors
 
diff --git a/tests/ui/symbol-names/types.verbose-legacy.stderr b/tests/ui/symbol-names/types.verbose-legacy.stderr
index 87c3acae0bd..c368b318609 100644
--- a/tests/ui/symbol-names/types.verbose-legacy.stderr
+++ b/tests/ui/symbol-names/types.verbose-legacy.stderr
@@ -502,5 +502,23 @@ error: demangling-alt(a::b::Type<[T; N]>)
 LL |     #[rustc_symbol_name]
    |     ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 84 previous errors
+error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E)
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<[u8; 0]>::h[HASH])
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<[u8; 0]>)
+  --> $DIR/types.rs:272:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 87 previous errors
 
diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs
new file mode 100644
index 00000000000..8b60820cc9b
--- /dev/null
+++ b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --target=x86_64-unknown-none --crate-type=lib
+//@ needs-llvm-components: x86
+//@ build-pass
+#![feature(no_core, lang_items, x87_target_feature)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[target_feature(enable = "x87")]
+pub unsafe fn my_fun() {}
diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs
new file mode 100644
index 00000000000..e34faf5a983
--- /dev/null
+++ b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs
@@ -0,0 +1,9 @@
+//@ compile-flags: --target=x86_64-unknown-none --crate-type=lib
+//@ needs-llvm-components: x86
+//@ compile-flags: -Ctarget-feature=-x87
+//@ build-pass
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr
new file mode 100644
index 00000000000..309b64afd92
--- /dev/null
+++ b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr
@@ -0,0 +1,6 @@
+warning: unstable feature specified for `-Ctarget-feature`: `x87`
+   |
+   = note: this feature is not stably supported; its behavior can change in the future
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/target-feature/feature-hierarchy.aarch64-sve2.stderr b/tests/ui/target-feature/feature-hierarchy.aarch64-sve2.stderr
new file mode 100644
index 00000000000..d5d7d7aa627
--- /dev/null
+++ b/tests/ui/target-feature/feature-hierarchy.aarch64-sve2.stderr
@@ -0,0 +1,7 @@
+warning: target feature `neon` cannot be toggled with `-Ctarget-feature`: unsound on hard-float targets because it changes float ABI
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs
new file mode 100644
index 00000000000..b3171d52c51
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
+//@ needs-llvm-components: x86
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[target_feature(enable = "x87")]
+//~^ERROR: cannot be toggled with
+pub unsafe fn my_fun() {}
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr
new file mode 100644
index 00000000000..3ebbe69d8ae
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr
@@ -0,0 +1,8 @@
+error: target feature `x87` cannot be toggled with `#[target_feature]`: unsound on hard-float targets because it changes float ABI
+  --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:9:18
+   |
+LL | #[target_feature(enable = "x87")]
+   |                  ^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs
new file mode 100644
index 00000000000..8755791c1c0
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs
@@ -0,0 +1,14 @@
+//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
+//@ needs-llvm-components: x86
+//@ check-pass
+#![feature(no_core, lang_items)]
+#![no_core]
+#![allow(unexpected_cfgs)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+// The compile_error macro does not exist, so if the `cfg` evaluates to `true` this
+// complains about the missing macro rather than showing the error... but that's good enough.
+#[cfg(not(target_feature = "x87"))]
+compile_error!("the x87 feature *should* be exposed in `cfg`");
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
new file mode 100644
index 00000000000..95c366bb3f5
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
@@ -0,0 +1,10 @@
+//@ compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=lib
+//@ needs-llvm-components: aarch64
+//@ compile-flags: -Ctarget-feature=-neon
+// For now this is just a warning.
+//@ build-pass
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr
new file mode 100644
index 00000000000..d5d7d7aa627
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr
@@ -0,0 +1,7 @@
+warning: target feature `neon` cannot be toggled with `-Ctarget-feature`: unsound on hard-float targets because it changes float ABI
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
new file mode 100644
index 00000000000..fd8023664da
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
@@ -0,0 +1,10 @@
+//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
+//@ needs-llvm-components: x86
+//@ compile-flags: -Ctarget-feature=-x87
+// For now this is just a warning.
+//@ build-pass
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr
new file mode 100644
index 00000000000..604ad2f991a
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr
@@ -0,0 +1,7 @@
+warning: target feature `x87` cannot be toggled with `-Ctarget-feature`: unsound on hard-float targets because it changes float ABI
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs
index 91c56b43689..f13cdd17da6 100644
--- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
 //@ needs-llvm-components: x86
 #![feature(no_core, lang_items)]
-#![no_std]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr
index fb318531f7e..27ac4aaf960 100644
--- a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr
+++ b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr
@@ -1,5 +1,5 @@
 error: target feature `soft-float` cannot be toggled with `#[target_feature]`: unsound because it changes float ABI
-  --> $DIR/forbidden-target-feature-attribute.rs:10:18
+  --> $DIR/forbidden-target-feature-attribute.rs:9:18
    |
 LL | #[target_feature(enable = "soft-float")]
    |                  ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/target-feature/forbidden-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-target-feature-cfg.rs
index 5df26e26793..1f001e9f8ff 100644
--- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs
@@ -2,7 +2,6 @@
 //@ needs-llvm-components: x86
 //@ check-pass
 #![feature(no_core, lang_items)]
-#![no_std]
 #![no_core]
 #![allow(unexpected_cfgs)]
 
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
index b27e8a10afe..b09c53bd46a 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
@@ -4,7 +4,6 @@
 // For now this is just a warning.
 //@ build-pass
 #![feature(no_core, lang_items)]
-#![no_std]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs
index 93cebc6b536..0f688fde7f4 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs
@@ -4,7 +4,6 @@
 // For now this is just a warning.
 //@ build-pass
 #![feature(no_core, lang_items)]
-#![no_std]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs
index f35fbd11155..14fdad02f56 100644
--- a/tests/ui/target-feature/gate.rs
+++ b/tests/ui/target-feature/gate.rs
@@ -24,6 +24,8 @@
 // gate-test-prfchw_target_feature
 // gate-test-s390x_target_feature
 // gate-test-sparc_target_feature
+// gate-test-x87_target_feature
+// gate-test-m68k_target_feature
 
 #[target_feature(enable = "avx512bw")]
 //~^ ERROR: currently unstable
diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr
index b84bab370be..fa876893848 100644
--- a/tests/ui/target-feature/gate.stderr
+++ b/tests/ui/target-feature/gate.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the target feature `avx512bw` is currently unstable
-  --> $DIR/gate.rs:28:18
+  --> $DIR/gate.rs:30:18
    |
 LL | #[target_feature(enable = "avx512bw")]
    |                  ^^^^^^^^^^^^^^^^^^^
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/const-traits/ice-120503-async-const-method.stderr b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr
index 66862d97bf9..e499451d897 100644
--- a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr
+++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr
@@ -26,11 +26,7 @@ LL |       async const fn bar(&self) {
    |       |
    |  _____`async` because of this
    | |
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     }
    | |_____-
 
@@ -38,11 +34,7 @@ error[E0407]: method `bar` is not a member of trait `MyTrait`
   --> $DIR/ice-120503-async-const-method.rs:6:5
    |
 LL | /     async const fn bar(&self) {
-LL | |
-LL | |
-LL | |
 ...  |
-LL | |
 LL | |     }
    | |_____^ not a member of trait `MyTrait`
 
diff --git a/tests/ui/transmutability/alignment/align-fail.stderr b/tests/ui/transmutability/alignment/align-fail.stderr
index b9801e511b2..7b69820a3c6 100644
--- a/tests/ui/transmutability/alignment/align-fail.stderr
+++ b/tests/ui/transmutability/alignment/align-fail.stderr
@@ -16,7 +16,6 @@ LL | |             Assume {
 LL | |                 alignment: false,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 help: consider removing the leading `&`-reference
diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
index c975ff276c8..7e5d0a6d412 100644
--- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
+++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
@@ -16,7 +16,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -38,7 +37,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -60,7 +58,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -82,7 +79,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -104,7 +100,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -126,7 +121,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -148,7 +142,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -170,7 +163,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -192,7 +184,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -214,7 +205,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -236,7 +226,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -258,7 +247,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -280,7 +268,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -302,7 +289,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -324,7 +310,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -346,7 +331,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -368,7 +352,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -390,7 +373,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -412,7 +394,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
@@ -434,7 +415,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_transmutable`
 
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
index 1698021d554..8d3ab4868da 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
@@ -16,7 +16,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: false,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
index dbd3e39b365..8651f40f3fb 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
@@ -16,7 +16,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: false,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
diff --git a/tests/ui/transmutability/references/unit-to-u8.stderr b/tests/ui/transmutability/references/unit-to-u8.stderr
index b5a79b1917f..bc9f286e097 100644
--- a/tests/ui/transmutability/references/unit-to-u8.stderr
+++ b/tests/ui/transmutability/references/unit-to-u8.stderr
@@ -16,7 +16,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr
index f112d2fbe44..b8b7b67f781 100644
--- a/tests/ui/transmutability/uninhabited.stderr
+++ b/tests/ui/transmutability/uninhabited.stderr
@@ -40,7 +40,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
@@ -62,7 +61,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
@@ -84,7 +82,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
@@ -106,7 +103,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
@@ -128,7 +124,6 @@ LL | |             Assume {
 LL | |                 alignment: true,
 LL | |                 lifetimes: true,
 ...  |
-LL | |             }
 LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
index 8888f2d49df..c7c93eee63e 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
@@ -24,10 +24,7 @@ error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
    |
 LL |   async fn test<const N: crate::Bar>() {
    |  ______________________________________^
-LL | |
-LL | |
-LL | |
-LL | |     #[cfg(infer)]
+...  |
 LL | |     let x: u32 = N;
 LL | | }
    | |_^
diff --git a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr
index be68bac5575..8547fd53c18 100644
--- a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr
+++ b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr
@@ -31,8 +31,7 @@ note: this definition site has more where clauses than the opaque type
    |
 LL | /     pub fn define_tait() -> Tait
 LL | |     where
-LL | |         // this proves `Bar<()>: Copy`, but `define_tait` is
-LL | |         // now uncallable
+...  |
 LL | |         (): Proj<Assoc = i32>,
    | |______________________________^
 
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
index 08ebc3208d7..293c8ea09f1 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
@@ -15,8 +15,7 @@ error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signa
   --> $DIR/hkl_forbidden4.rs:22:1
    |
 LL | / {
-LL | |
-LL | |
+...  |
 LL | | }
    | |_^
    |
@@ -55,8 +54,7 @@ LL |   type FutNothing<'a> = impl 'a + Future<Output = ()>;
    |                   -- this generic parameter must be used with a generic lifetime parameter
 ...
 LL | / {
-LL | |
-LL | |
+...  |
 LL | | }
    | |_^
 
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/typeck/issue-100285.stderr b/tests/ui/typeck/issue-100285.stderr
index 6f86fd18e0f..388510b7704 100644
--- a/tests/ui/typeck/issue-100285.stderr
+++ b/tests/ui/typeck/issue-100285.stderr
@@ -8,7 +8,6 @@ LL | |        if n < 0 {
 LL | |         return i;
 LL | |         } else if n < 10 {
 ...  |
-LL | |
 LL | |     }
    | |_____^ expected `i32`, found `()`
    |
diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr
index 37d38a76a40..c3872ea8968 100644
--- a/tests/ui/typeck/issue-104513-ice.stderr
+++ b/tests/ui/typeck/issue-104513-ice.stderr
@@ -11,6 +11,9 @@ LL |     let _: S<impl Oops> = S;
    |              ^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = help: add `#![feature(impl_trait_in_bindings)]` 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
 
diff --git a/tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr b/tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr
new file mode 100644
index 00000000000..ff189e36ba0
--- /dev/null
+++ b/tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr
@@ -0,0 +1,11 @@
+error[E0369]: binary operation `==` cannot be applied to type `[X; 1]`
+  --> $DIR/rhs-ty-hint-134162.rs:16:17
+   |
+LL |     let _ = [X] == [panic!(); 2];
+   |             --- ^^ ------------- [_; 2]
+   |             |
+   |             [X; 1]
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr b/tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr
new file mode 100644
index 00000000000..ff189e36ba0
--- /dev/null
+++ b/tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr
@@ -0,0 +1,11 @@
+error[E0369]: binary operation `==` cannot be applied to type `[X; 1]`
+  --> $DIR/rhs-ty-hint-134162.rs:16:17
+   |
+LL |     let _ = [X] == [panic!(); 2];
+   |             --- ^^ ------------- [_; 2]
+   |             |
+   |             [X; 1]
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr b/tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr
new file mode 100644
index 00000000000..ff189e36ba0
--- /dev/null
+++ b/tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr
@@ -0,0 +1,11 @@
+error[E0369]: binary operation `==` cannot be applied to type `[X; 1]`
+  --> $DIR/rhs-ty-hint-134162.rs:16:17
+   |
+LL |     let _ = [X] == [panic!(); 2];
+   |             --- ^^ ------------- [_; 2]
+   |             |
+   |             [X; 1]
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/typeck/rhs-ty-hint-134162.rs b/tests/ui/typeck/rhs-ty-hint-134162.rs
new file mode 100644
index 00000000000..a14b4bcfd26
--- /dev/null
+++ b/tests/ui/typeck/rhs-ty-hint-134162.rs
@@ -0,0 +1,18 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/134162>.
+//!
+//! <https://github.com/rust-lang/rust/pull/110877> introduced RHS type hints for when a ty doesn't
+//! support a bin op. In the suggestion path, there was a `delay_bug`.
+//! <https://github.com/rust-lang/rust/pull/121208> converted this `delay_bug` to `bug`, which did
+//! not trigger any test failures as we did not have test coverage for this particular case. This
+//! manifested in an ICE as reported in <https://github.com/rust-lang/rust/issues/134162>.
+
+//@ revisions: e2018 e2021 e2024
+//@[e2018] edition: 2018
+//@[e2021] edition: 2021
+//@[e2024] edition: 2024
+
+fn main() {
+    struct X;
+    let _ = [X] == [panic!(); 2];
+    //[e2018,e2021,e2024]~^ ERROR binary operation `==` cannot be applied to type `[X; 1]`
+}
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/tests/ui/unsafe-binders/expr.rs b/tests/ui/unsafe-binders/expr.rs
new file mode 100644
index 00000000000..d8c4c2df2cd
--- /dev/null
+++ b/tests/ui/unsafe-binders/expr.rs
@@ -0,0 +1,13 @@
+#![feature(unsafe_binders)]
+//~^ WARN the feature `unsafe_binders` is incomplete
+
+use std::unsafe_binder::{wrap_binder, unwrap_binder};
+
+fn main() {
+    let x = 1;
+    let binder: unsafe<'a> &'a i32 = wrap_binder!(x);
+    //~^ ERROR unsafe binders are not yet implemented
+    //~| ERROR unsafe binders are not yet implemented
+    let rx = *unwrap_binder!(binder);
+    //~^ ERROR unsafe binders are not yet implemented
+}
diff --git a/tests/ui/unsafe-binders/expr.stderr b/tests/ui/unsafe-binders/expr.stderr
new file mode 100644
index 00000000000..26fae1958b0
--- /dev/null
+++ b/tests/ui/unsafe-binders/expr.stderr
@@ -0,0 +1,29 @@
+warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/expr.rs:1:12
+   |
+LL | #![feature(unsafe_binders)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: unsafe binders are not yet implemented
+  --> $DIR/expr.rs:8:17
+   |
+LL |     let binder: unsafe<'a> &'a i32 = wrap_binder!(x);
+   |                 ^^^^^^^^^^^^^^^^^^
+
+error: unsafe binders are not yet implemented
+  --> $DIR/expr.rs:8:51
+   |
+LL |     let binder: unsafe<'a> &'a i32 = wrap_binder!(x);
+   |                                                   ^
+
+error: unsafe binders are not yet implemented
+  --> $DIR/expr.rs:11:30
+   |
+LL |     let rx = *unwrap_binder!(binder);
+   |                              ^^^^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
diff --git a/tests/ui/unsafe-binders/lifetime-resolution.rs b/tests/ui/unsafe-binders/lifetime-resolution.rs
new file mode 100644
index 00000000000..aebed9599d4
--- /dev/null
+++ b/tests/ui/unsafe-binders/lifetime-resolution.rs
@@ -0,0 +1,19 @@
+#![feature(unsafe_binders)]
+//~^ WARN the feature `unsafe_binders` is incomplete
+
+fn foo<'a>() {
+    let good: unsafe<'b> &'a &'b ();
+    //~^ ERROR unsafe binders are not yet implemented
+
+    let missing: unsafe<> &'missing ();
+    //~^ ERROR unsafe binders are not yet implemented
+    //~| ERROR use of undeclared lifetime name `'missing`
+
+    fn inner<'b>() {
+        let outer: unsafe<> &'a &'b ();
+        //~^ ERROR unsafe binders are not yet implemented
+        //~| can't use generic parameters from outer item
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/unsafe-binders/lifetime-resolution.stderr b/tests/ui/unsafe-binders/lifetime-resolution.stderr
new file mode 100644
index 00000000000..7a8ce929df1
--- /dev/null
+++ b/tests/ui/unsafe-binders/lifetime-resolution.stderr
@@ -0,0 +1,65 @@
+error[E0261]: use of undeclared lifetime name `'missing`
+  --> $DIR/lifetime-resolution.rs:8:28
+   |
+LL |     let missing: unsafe<> &'missing ();
+   |                            ^^^^^^^^ undeclared lifetime
+   |
+   = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the type lifetime-generic with a new `'missing` lifetime
+   |
+LL |     let missing: unsafe<'missing, > &'missing ();
+   |                         +++++++++
+help: consider introducing lifetime `'missing` here
+   |
+LL | fn foo<'missing, 'a>() {
+   |        +++++++++
+
+error[E0401]: can't use generic parameters from outer item
+  --> $DIR/lifetime-resolution.rs:13:30
+   |
+LL | fn foo<'a>() {
+   |        -- lifetime parameter from outer item
+...
+LL |         let outer: unsafe<> &'a &'b ();
+   |                              ^^ use of generic parameter from outer item
+   |
+help: consider making the type lifetime-generic with a new `'a` lifetime
+   |
+LL |         let outer: unsafe<'a, > &'a &'b ();
+   |                           +++
+help: consider introducing lifetime `'a` here
+   |
+LL |     fn inner<'a, 'b>() {
+   |              +++
+
+warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/lifetime-resolution.rs:1:12
+   |
+LL | #![feature(unsafe_binders)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: unsafe binders are not yet implemented
+  --> $DIR/lifetime-resolution.rs:5:15
+   |
+LL |     let good: unsafe<'b> &'a &'b ();
+   |               ^^^^^^^^^^^^^^^^^^^^^
+
+error: unsafe binders are not yet implemented
+  --> $DIR/lifetime-resolution.rs:8:18
+   |
+LL |     let missing: unsafe<> &'missing ();
+   |                  ^^^^^^^^^^^^^^^^^^^^^
+
+error: unsafe binders are not yet implemented
+  --> $DIR/lifetime-resolution.rs:13:20
+   |
+LL |         let outer: unsafe<> &'a &'b ();
+   |                    ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0261, E0401.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/unsafe-binders/simple.rs b/tests/ui/unsafe-binders/simple.rs
new file mode 100644
index 00000000000..cebff2cbfb8
--- /dev/null
+++ b/tests/ui/unsafe-binders/simple.rs
@@ -0,0 +1,7 @@
+#![feature(unsafe_binders)]
+//~^ WARN the feature `unsafe_binders` is incomplete
+
+fn main() {
+    let x: unsafe<'a> &'a ();
+    //~^ ERROR unsafe binders are not yet implemented
+}
diff --git a/tests/ui/unsafe-binders/simple.stderr b/tests/ui/unsafe-binders/simple.stderr
new file mode 100644
index 00000000000..a21dbd00b4c
--- /dev/null
+++ b/tests/ui/unsafe-binders/simple.stderr
@@ -0,0 +1,17 @@
+warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/simple.rs:1:12
+   |
+LL | #![feature(unsafe_binders)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: unsafe binders are not yet implemented
+  --> $DIR/simple.rs:5:12
+   |
+LL |     let x: unsafe<'a> &'a ();
+   |            ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error; 1 warning emitted
+
diff --git a/tests/ui/while/while-else-err.stderr b/tests/ui/while/while-else-err.stderr
index b937956108f..face0c73925 100644
--- a/tests/ui/while/while-else-err.stderr
+++ b/tests/ui/while/while-else-err.stderr
@@ -6,8 +6,7 @@ LL |       while false {
 LL |
 LL |       } else {
    |  _______^
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
diff --git a/tests/ui/while/while-else-let-else-err.stderr b/tests/ui/while/while-else-let-else-err.stderr
index 27d68ffdb24..4fc99409f78 100644
--- a/tests/ui/while/while-else-let-else-err.stderr
+++ b/tests/ui/while/while-else-let-else-err.stderr
@@ -6,8 +6,7 @@ LL |       let _ = while false {
 LL |
 LL |       } else {
    |  _______^
-LL | |
-LL | |
+...  |
 LL | |     };
    | |_____^
    |
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",