about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
-rw-r--r--Cargo.lock54
-rw-r--r--compiler/rustc_abi/src/layout.rs20
-rw-r--r--compiler/rustc_ast/src/ast.rs22
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs44
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs30
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs53
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs40
-rw-r--r--compiler/rustc_borrowck/src/lib.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs55
-rw-r--r--compiler/rustc_codegen_gcc/src/allocator.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/gcc_util.rs8
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs5
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml1
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs18
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs34
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs34
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs23
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/assert_module_sources.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs23
-rw-r--r--compiler/rustc_codegen_ssa/src/size_of_val.rs (renamed from compiler/rustc_codegen_ssa/src/glue.rs)96
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs434
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs43
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs29
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/visitor.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs3
-rw-r--r--compiler/rustc_data_structures/src/sorted_map.rs2
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs144
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs4
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs5
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs20
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs6
-rw-r--r--compiler/rustc_errors/src/emitter.rs7
-rw-r--r--compiler/rustc_errors/src/lib.rs129
-rw-r--r--compiler/rustc_expand/src/base.rs2
-rw-r--r--compiler/rustc_expand/src/expand.rs126
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs32
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs65
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs15
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir/src/target.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs171
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/object_safety.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs383
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/entry.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs58
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs24
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs52
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs9
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs33
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs45
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/prelude2021.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs38
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/rvalue_scopes.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs4
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs2
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs236
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/substitute.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs111
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs30
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs27
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs7
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs5
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs (renamed from compiler/rustc_infer/src/infer/combine.rs)32
-rw-r--r--compiler/rustc_infer/src/infer/relate/equate.rs (renamed from compiler/rustc_infer/src/infer/equate.rs)8
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs (renamed from compiler/rustc_infer/src/infer/generalize.rs)12
-rw-r--r--compiler/rustc_infer/src/infer/relate/glb.rs (renamed from compiler/rustc_infer/src/infer/glb.rs)11
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs (renamed from compiler/rustc_infer/src/infer/higher_ranked/mod.rs)2
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs (renamed from compiler/rustc_infer/src/infer/lattice.rs)6
-rw-r--r--compiler/rustc_infer/src/infer/relate/lub.rs (renamed from compiler/rustc_infer/src/infer/lub.rs)7
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs12
-rw-r--r--compiler/rustc_infer/src/infer/relate/nll.rs (renamed from compiler/rustc_infer/src/infer/nll_relate/mod.rs)12
-rw-r--r--compiler/rustc_infer/src/infer/relate/sub.rs (renamed from compiler/rustc_infer/src/infer/sub.rs)4
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs2
-rw-r--r--compiler/rustc_interface/src/tests.rs13
-rw-r--r--compiler/rustc_lint/src/builtin.rs2
-rw-r--r--compiler/rustc_lint/src/context.rs90
-rw-r--r--compiler/rustc_lint/src/early.rs8
-rw-r--r--compiler/rustc_lint/src/internal.rs2
-rw-r--r--compiler/rustc_lint/src/levels.rs11
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint/src/lints.rs56
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs3
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs138
-rw-r--r--compiler/rustc_lint/src/types.rs6
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs42
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs6
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs108
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs64
-rw-r--r--compiler/rustc_middle/src/lint.rs36
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs11
-rw-r--r--compiler/rustc_middle/src/middle/region.rs2
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs5
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs2
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs4
-rw-r--r--compiler/rustc_middle/src/traits/solve/cache.rs2
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs73
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs6
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs51
-rw-r--r--compiler/rustc_middle/src/ty/error.rs20
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs14
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs26
-rw-r--r--compiler/rustc_middle/src/ty/util.rs7
-rw-r--r--compiler/rustc_middle/src/values.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs10
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs5
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs6
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs147
-rw-r--r--compiler/rustc_mir_transform/src/cross_crate_inline.rs19
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs22
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs2
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs16
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs14
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs8
-rw-r--r--compiler/rustc_parse/src/errors.rs4
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs3
-rw-r--r--compiler/rustc_parse/src/lib.rs8
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs4
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs27
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs14
-rw-r--r--compiler/rustc_passes/src/dead.rs4
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs3
-rw-r--r--compiler/rustc_passes/src/entry.rs2
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs6
-rw-r--r--compiler/rustc_passes/src/lang_items.rs378
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_passes/src/loops.rs15
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs4
-rw-r--r--compiler/rustc_passes/src/stability.rs3
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs30
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs5
-rw-r--r--compiler/rustc_privacy/src/lib.rs4
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs4
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs14
-rw-r--r--compiler/rustc_resolve/src/imports.rs8
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs13
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs3
-rw-r--r--compiler/rustc_session/src/config.rs37
-rw-r--r--compiler/rustc_session/src/errors.rs2
-rw-r--r--compiler/rustc_session/src/options.rs75
-rw-r--r--compiler/rustc_session/src/parse.rs11
-rw-r--r--compiler/rustc_session/src/session.rs10
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs10
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs3
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mod.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs1
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs13
-rw-r--r--compiler/rustc_target/src/spec/mod.rs6
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs5
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs5
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/i386_apple_ios.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/target_features.rs429
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/build.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs5
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs34
-rw-r--r--compiler/rustc_trait_selection/src/solve/search_graph.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs23
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs114
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs76
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs42
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs5
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs3
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs2
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs5
-rw-r--r--compiler/rustc_ty_utils/src/sig_types.rs8
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs4
-rw-r--r--compiler/rustc_type_ir/src/debug.rs6
-rw-r--r--compiler/rustc_type_ir/src/infcx.rs16
-rw-r--r--compiler/rustc_type_ir/src/interner.rs7
-rw-r--r--compiler/rustc_type_ir/src/lib.rs42
-rw-r--r--compiler/rustc_type_ir/src/macros.rs2
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs46
-rw-r--r--compiler/stable_mir/src/mir/body.rs69
-rw-r--r--compiler/stable_mir/src/mir/mono.rs7
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs52
-rw-r--r--compiler/stable_mir/src/mir/visit.rs2
-rw-r--r--compiler/stable_mir/src/ty.rs14
-rw-r--r--library/alloc/src/ffi/c_str.rs6
-rw-r--r--library/core/src/any.rs39
-rw-r--r--library/core/src/ffi/c_str.rs4
-rw-r--r--library/core/src/fmt/num.rs6
-rw-r--r--library/core/src/net/ip_addr.rs2
-rw-r--r--library/core/src/ptr/mod.rs7
-rw-r--r--library/core/src/slice/ascii.rs3
-rw-r--r--library/core/src/str/mod.rs79
-rw-r--r--library/core/src/task/wake.rs6
-rw-r--r--library/core/src/tuple.rs143
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle_dyn.rs2
-rw-r--r--library/std/Cargo.toml5
-rw-r--r--library/std/src/env.rs50
-rw-r--r--library/std/src/fs/tests.rs27
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/panicking.rs4
-rw-r--r--library/std/src/process.rs2
-rw-r--r--library/std/src/rt.rs3
-rw-r--r--library/std/src/sys/personality/mod.rs2
-rw-r--r--library/std/src/sys/unix/args.rs16
-rw-r--r--library/std/src/sys/unix/fs.rs2
-rw-r--r--library/std/src/sys/unix/mod.rs7
-rw-r--r--library/std/src/sys/unix/process/process_common.rs9
-rw-r--r--library/std/src/sys/unix/thread.rs3
-rw-r--r--library/std/src/sys/windows/c.rs4
-rw-r--r--library/std/src/sys/windows/compat.rs6
-rw-r--r--library/std/src/sys/windows/fs.rs33
-rw-r--r--library/std/src/sys/windows/mod.rs4
-rw-r--r--src/bootstrap/src/bin/main.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs10
-rw-r--r--src/bootstrap/src/core/builder.rs8
-rw-r--r--src/bootstrap/src/core/config/config.rs48
-rw-r--r--src/bootstrap/src/tests/config.rs6
-rw-r--r--src/bootstrap/src/utils/helpers.rs8
-rw-r--r--src/doc/rustdoc/src/write-documentation/the-doc-attribute.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/default-hidden-visibility.md12
-rw-r--r--src/librustdoc/clean/blanket_impl.rs3
-rw-r--r--src/librustdoc/clean/mod.rs100
-rw-r--r--src/librustdoc/clean/types.rs8
-rw-r--r--src/librustdoc/clean/utils.rs5
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/html/markdown.rs102
-rw-r--r--src/librustdoc/html/render/print_item.rs13
-rw-r--r--src/librustdoc/html/render/search_index.rs2
-rw-r--r--src/librustdoc/html/render/span_map.rs4
-rw-r--r--src/librustdoc/html/render/type_layout.rs3
-rw-r--r--src/librustdoc/html/render/write_shared.rs29
-rw-r--r--src/librustdoc/html/static/css/noscript.css6
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css171
-rw-r--r--src/librustdoc/html/static/js/externs.js3
-rw-r--r--src/librustdoc/html/static/js/main.js268
-rw-r--r--src/librustdoc/html/static/js/search.js455
-rw-r--r--src/librustdoc/html/static/js/settings.js19
-rw-r--r--src/librustdoc/html/static/js/src-script.js50
-rw-r--r--src/librustdoc/html/static/js/storage.js28
-rw-r--r--src/librustdoc/html/templates/page.html10
-rw-r--r--src/librustdoc/lint.rs4
-rw-r--r--src/librustdoc/passes/check_custom_code_classes.rs2
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs6
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs2
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs2
-rw-r--r--src/librustdoc/passes/lint/html_tags.rs4
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs4
-rw-r--r--src/librustdoc/passes/lint/unescaped_backticks.rs2
-rw-r--r--src/librustdoc/visit_ast.rs11
m---------src/llvm-project0
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/absolute_paths.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_drop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/exit.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_next.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/self_named_constructors.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs16
-rw-r--r--src/tools/compiletest/src/runtest.rs4
-rw-r--r--src/tools/miri/src/bin/miri.rs2
-rw-r--r--src/tools/miri/src/diagnostics.rs2
-rw-r--r--src/tools/miri/tests/fail/extern-type-field-offset.rs29
-rw-r--r--src/tools/miri/tests/fail/extern-type-field-offset.stderr14
-rw-r--r--src/tools/miri/tests/pass/packed-struct-dyn-trait.rs21
-rw-r--r--src/tools/rustfmt/src/parse/session.rs6
-rw-r--r--src/tools/tidy/src/deps.rs2
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/assembly/stack-probes.rs (renamed from tests/assembly/x86-stack-probes.rs)12
-rw-r--r--tests/codegen/debug-accessibility/crate-enum.rs26
-rw-r--r--tests/codegen/debug-accessibility/crate-struct.rs23
-rw-r--r--tests/codegen/debug-accessibility/private-enum.rs21
-rw-r--r--tests/codegen/debug-accessibility/private-struct.rs17
-rw-r--r--tests/codegen/debug-accessibility/public-enum.rs21
-rw-r--r--tests/codegen/debug-accessibility/public-struct.rs17
-rw-r--r--tests/codegen/debug-accessibility/struct-fields.rs30
-rw-r--r--tests/codegen/debug-accessibility/super-enum.rs27
-rw-r--r--tests/codegen/debug-accessibility/super-struct.rs23
-rw-r--r--tests/codegen/debug-accessibility/tuple-fields.rs24
-rw-r--r--tests/codegen/default-hidden-visibility.rs31
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs2
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs2
-rw-r--r--tests/codegen/stack-probes-inline.rs4
-rw-r--r--tests/coverage/async.cov-map152
-rw-r--r--tests/coverage/async.coverage43
-rw-r--r--tests/coverage/async.rs26
-rw-r--r--tests/coverage/async2.cov-map96
-rw-r--r--tests/coverage/async2.coverage80
-rw-r--r--tests/coverage/async2.rs24
-rw-r--r--tests/coverage/closure_macro_async.cov-map16
-rw-r--r--tests/coverage/closure_macro_async.coverage26
-rw-r--r--tests/coverage/closure_macro_async.rs26
-rw-r--r--tests/rustdoc-gui/globals.goml24
-rw-r--r--tests/rustdoc-gui/hide-mobile-topbar.goml20
-rw-r--r--tests/rustdoc-gui/links-color.goml4
-rw-r--r--tests/rustdoc-gui/sidebar-links-color.goml4
-rw-r--r--tests/rustdoc-gui/sidebar-resize-setting.goml23
-rw-r--r--tests/rustdoc-gui/sidebar-resize-window.goml37
-rw-r--r--tests/rustdoc-gui/sidebar-resize.goml28
-rw-r--r--tests/rustdoc-gui/sidebar-source-code.goml3
-rw-r--r--tests/rustdoc-gui/sidebar.goml4
-rw-r--r--tests/rustdoc-gui/src/theme_css/custom-theme.css2
-rw-r--r--tests/rustdoc-js/assoc-type.js6
-rw-r--r--tests/rustdoc-js/big-result.js39
-rw-r--r--tests/rustdoc-js/big-result.rs61
-rw-r--r--tests/rustdoc-js/full-path-function.js4
-rw-r--r--tests/rustdoc-js/generics.js1
-rw-r--r--tests/rustdoc-js/impl-trait.js2
-rw-r--r--tests/rustdoc-js/type-parameters.js19
-rw-r--r--tests/rustdoc-ui/check-cfg/check-cfg.stderr2
-rw-r--r--tests/rustdoc-ui/doctest/check-attr-test.stderr36
-rw-r--r--tests/rustdoc-ui/doctest/check-cfg-test.stderr2
-rw-r--r--tests/rustdoc-ui/lints/check-attr.rs17
-rw-r--r--tests/rustdoc-ui/lints/check-attr.stderr80
-rw-r--r--tests/rustdoc-ui/lints/check-fail.stderr6
-rw-r--r--tests/rustdoc/reexport-cfg.rs30
-rw-r--r--tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs4
-rw-r--r--tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs4
-rw-r--r--tests/ui-fulldeps/stable-mir/check_defs.rs2
-rw-r--r--tests/ui/abi/stack-probes-lto.rs4
-rw-r--r--tests/ui/abi/stack-probes.rs4
-rw-r--r--tests/ui/associated-inherent-types/inference.rs2
-rw-r--r--tests/ui/async-await/future-sizes/async-awaiting-fut.stdout6
-rw-r--r--tests/ui/async-await/in-trait/async-default-fn-overridden.rs24
-rw-r--r--tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs25
-rw-r--r--tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr26
-rw-r--r--tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr8
-rw-r--r--tests/ui/async-await/normalize-output-in-signature-deduction.rs2
-rw-r--r--tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs2
-rw-r--r--tests/ui/auto-traits/issue-23080-2.rs2
-rw-r--r--tests/ui/check-cfg/allow-same-level.stderr2
-rw-r--r--tests/ui/check-cfg/cargo-feature.none.stderr31
-rw-r--r--tests/ui/check-cfg/cargo-feature.rs17
-rw-r--r--tests/ui/check-cfg/cargo-feature.some.stderr35
-rw-r--r--tests/ui/check-cfg/cargo-feature.stderr11
-rw-r--r--tests/ui/check-cfg/compact-names.stderr2
-rw-r--r--tests/ui/check-cfg/compact-values.stderr2
-rw-r--r--tests/ui/check-cfg/concat-values.stderr4
-rw-r--r--tests/ui/check-cfg/diagnotics.cargo.stderr71
-rw-r--r--tests/ui/check-cfg/diagnotics.rs3
-rw-r--r--tests/ui/check-cfg/diagnotics.rustc.stderr74
-rw-r--r--tests/ui/check-cfg/diagnotics.stderr61
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr10
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr33
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.feature.stderr6
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.full.stderr6
-rw-r--r--tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr11
-rw-r--r--tests/ui/check-cfg/exhaustive-names.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-values.without_names.stderr2
-rw-r--r--tests/ui/check-cfg/mix.cfg.stderr184
-rw-r--r--tests/ui/check-cfg/mix.stderr65
-rw-r--r--tests/ui/check-cfg/no-expected-values.empty.stderr4
-rw-r--r--tests/ui/check-cfg/no-expected-values.mixed.stderr4
-rw-r--r--tests/ui/check-cfg/no-expected-values.simple.stderr4
-rw-r--r--tests/ui/check-cfg/order-independant.values_after.stderr2
-rw-r--r--tests/ui/check-cfg/order-independant.values_before.stderr2
-rw-r--r--tests/ui/check-cfg/stmt-no-ice.stderr2
-rw-r--r--tests/ui/check-cfg/unexpected-cfg-name.stderr2
-rw-r--r--tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr21
-rw-r--r--tests/ui/check-cfg/unexpected-cfg-value.stderr4
-rw-r--r--tests/ui/check-cfg/well-known-names.stderr10
-rw-r--r--tests/ui/check-cfg/well-known-values.rs6
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr84
-rw-r--r--tests/ui/closures/infer-signature-from-impl.rs2
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream-inherent.rs2
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream.rs2
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs2
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516.rs2
-rw-r--r--tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs2
-rw-r--r--tests/ui/coherence/normalize-for-errors.rs2
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.next.stderr16
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.old.stderr16
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.rs2
-rw-r--r--tests/ui/coherence/occurs-check/opaques.rs2
-rw-r--r--tests/ui/coinduction/canonicalization-rerun.rs2
-rw-r--r--tests/ui/const-generics/defaults/default-param-wf-concrete.rs2
-rw-r--r--tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs43
-rw-r--r--tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr9
-rw-r--r--tests/ui/consts/const-eval/issue-91827-extern-types.rs59
-rw-r--r--tests/ui/consts/const-len-underflow-separate-spans.rs2
-rw-r--r--tests/ui/coroutine/async-gen-deduce-yield.rs14
-rw-r--r--tests/ui/coroutine/async_gen_fn_iter.rs24
-rw-r--r--tests/ui/coroutine/clone-rpit.rs2
-rw-r--r--tests/ui/coroutine/gen_block_is_iter.rs2
-rw-r--r--tests/ui/coroutine/gen_block_iterate.rs2
-rw-r--r--tests/ui/coroutine/non-static-is-unpin.rs2
-rw-r--r--tests/ui/coroutine/static-not-unpin.rs2
-rw-r--r--tests/ui/coroutine/uninhabited-field.rs37
-rw-r--r--tests/ui/destructuring-assignment/bad-expr-lhs.rs2
-rw-r--r--tests/ui/destructuring-assignment/bad-expr-lhs.stderr10
-rw-r--r--tests/ui/destructuring-assignment/non-exhaustive-destructure.rs4
-rw-r--r--tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr17
-rw-r--r--tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs6
-rw-r--r--tests/ui/diagnostic-width/long-E0308.stderr10
-rw-r--r--tests/ui/duplicate_entry_error.stderr7
-rw-r--r--tests/ui/dyn-star/box.rs2
-rw-r--r--tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs2
-rw-r--r--tests/ui/dyn-star/dispatch-on-pin-mut.rs24
-rw-r--r--tests/ui/dyn-star/param-env-region-infer.rs2
-rw-r--r--tests/ui/error-codes/E0152.stderr2
-rw-r--r--tests/ui/error-codes/E0264.stderr2
-rw-r--r--tests/ui/error-codes/E0476.rs2
-rw-r--r--tests/ui/extern/extern-types-field-offset.rs33
-rw-r--r--tests/ui/extern/extern-types-field-offset.run.stderr4
-rw-r--r--tests/ui/extern/extern-types-size_of_val.align.run.stderr4
-rw-r--r--tests/ui/extern/extern-types-size_of_val.rs14
-rw-r--r--tests/ui/extern/extern-types-size_of_val.size.run.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr32
-rw-r--r--tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr14
-rw-r--r--tests/ui/feature-gates/feature-gate-gen_blocks.rs15
-rw-r--r--tests/ui/feature-gates/feature-gate-trivial_bounds.stderr2
-rw-r--r--tests/ui/fmt/send-sync.stderr10
-rw-r--r--tests/ui/for/issue-20605.rs4
-rw-r--r--tests/ui/function-pointer/unsized-ret.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-102114.rs2
-rw-r--r--tests/ui/higher-ranked/leak-check-in-selection.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/fn-ptr.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/future.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-95230.rs2
-rw-r--r--tests/ui/hygiene/cross-crate-define-and-use.rs1
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.rs2
-rw-r--r--tests/ui/impl-trait/autoderef.rs2
-rw-r--r--tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr4
-rw-r--r--tests/ui/impl-trait/erased-regions-in-hidden-ty.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety-sized.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-variances.rs2
-rw-r--r--tests/ui/impl-trait/issue-103181-1.rs2
-rw-r--r--tests/ui/impl-trait/recursive-coroutine.rs2
-rw-r--r--tests/ui/impl-trait/reveal-during-codegen.rs2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other.rs2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.rs2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other3.rs2
-rw-r--r--tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs2
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs5
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr43
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs5
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr45
-rw-r--r--tests/ui/inference/issue-103587.stderr6
-rw-r--r--tests/ui/inference/type-infer-generalize-ty-var.rs2
-rw-r--r--tests/ui/issues/issue-13167.rs2
-rw-r--r--tests/ui/issues/issue-13407.rs4
-rw-r--r--tests/ui/issues/issue-13407.stderr15
-rw-r--r--tests/ui/issues/issue-15734.rs2
-rw-r--r--tests/ui/issues/issue-21763.stderr2
-rw-r--r--tests/ui/kindck/kindck-send-object1.stderr2
-rw-r--r--tests/ui/lang-items/lang-item-generic-requirements.rs3
-rw-r--r--tests/ui/lang-items/lang-item-generic-requirements.stderr37
-rw-r--r--tests/ui/lazy-type-alias/coerce-behind-lazy.rs2
-rw-r--r--tests/ui/lint/ptr_null_checks.rs2
-rw-r--r--tests/ui/lint/ptr_null_checks.stderr54
-rw-r--r--tests/ui/lint/reference_casting.rs9
-rw-r--r--tests/ui/lint/reference_casting.stderr102
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs60
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs28
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs2
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr4
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs14
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs14
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr10
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs8
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr28
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs34
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr206
-rw-r--r--tests/ui/never_type/never-from-impl-is-reserved.rs2
-rw-r--r--tests/ui/nll/issue-53119.rs2
-rw-r--r--tests/ui/object-safety/call-when-assoc-ty-is-sized.rs2
-rw-r--r--tests/ui/packed/dyn-trait.rs21
-rw-r--r--tests/ui/panic-handler/panic-handler-duplicate.stderr12
-rw-r--r--tests/ui/panic-handler/panic-handler-std.stderr6
-rw-r--r--tests/ui/panics/abort-on-panic.rs2
-rw-r--r--tests/ui/print_type_sizes/coroutine_discr_placement.stdout6
-rw-r--r--tests/ui/regions/resolve-re-error-ice.rs6
-rw-r--r--tests/ui/regions/resolve-re-error-ice.stderr42
-rw-r--r--tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs2
-rw-r--r--tests/ui/specialization/specialization-default-items-drop-coherence.rs4
-rw-r--r--tests/ui/stable-mir-print/basic_function.rs15
-rw-r--r--tests/ui/stable-mir-print/basic_function.stdout234
-rw-r--r--tests/ui/structs-enums/type-sizes.rs1
-rw-r--r--tests/ui/traits/deny-builtin-object-impl.rs2
-rw-r--r--tests/ui/traits/issue-102989.rs1
-rw-r--r--tests/ui/traits/issue-102989.stderr22
-rw-r--r--tests/ui/traits/issue-24010.rs2
-rw-r--r--tests/ui/traits/negative-impls/negated-auto-traits-error.stderr8
-rw-r--r--tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr9
-rw-r--r--tests/ui/traits/next-solver/alias-bound-preference.rs (renamed from tests/ui/traits/new-solver/alias-bound-preference.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.rs (renamed from tests/ui/traits/new-solver/alias-bound-unsound.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.stderr (renamed from tests/ui/traits/new-solver/alias-bound-unsound.stderr)0
-rw-r--r--tests/ui/traits/next-solver/alias-eq-in-canonical-response.rs (renamed from tests/ui/traits/new-solver/alias-eq-in-canonical-response.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias-relate/deeply-nested-no-hang.rs (renamed from tests/ui/traits/new-solver/alias-relate/deeply-nested-no-hang.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs (renamed from tests/ui/traits/new-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias-sub.rs (renamed from tests/ui/traits/new-solver/alias-sub.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs (renamed from tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs (renamed from tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias_eq_simple.rs (renamed from tests/ui/traits/new-solver/alias_eq_simple.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs (renamed from tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr (renamed from tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr)0
-rw-r--r--tests/ui/traits/next-solver/array-default.rs (renamed from tests/ui/traits/new-solver/array-default.rs)2
-rw-r--r--tests/ui/traits/next-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs (renamed from tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs)2
-rw-r--r--tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.rs (renamed from tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs)2
-rw-r--r--tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr (renamed from tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr)0
-rw-r--r--tests/ui/traits/next-solver/async.fail.stderr (renamed from tests/ui/traits/new-solver/async.fail.stderr)0
-rw-r--r--tests/ui/traits/next-solver/async.rs (renamed from tests/ui/traits/new-solver/async.rs)2
-rw-r--r--tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr (renamed from tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr)0
-rw-r--r--tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs (renamed from tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs)2
-rw-r--r--tests/ui/traits/next-solver/borrowck-error.rs (renamed from tests/ui/traits/new-solver/borrowck-error.rs)2
-rw-r--r--tests/ui/traits/next-solver/borrowck-error.stderr (renamed from tests/ui/traits/new-solver/borrowck-error.stderr)0
-rw-r--r--tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs (renamed from tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs)2
-rw-r--r--tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr (renamed from tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr)0
-rw-r--r--tests/ui/traits/next-solver/canonical-int-var-eq-in-response.rs (renamed from tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs)2
-rw-r--r--tests/ui/traits/next-solver/canonical-ty-var-eq-in-response.rs (renamed from tests/ui/traits/new-solver/canonical-ty-var-eq-in-response.rs)2
-rw-r--r--tests/ui/traits/next-solver/canonicalize-effect-var.rs (renamed from tests/ui/traits/new-solver/canonicalize-effect-var.rs)2
-rw-r--r--tests/ui/traits/next-solver/cast-checks-handling-projections.rs (renamed from tests/ui/traits/new-solver/cast-checks-handling-projections.rs)2
-rw-r--r--tests/ui/traits/next-solver/closure-inference-guidance.rs (renamed from tests/ui/traits/new-solver/closure-inference-guidance.rs)2
-rw-r--r--tests/ui/traits/next-solver/closure-signature-inference-2.rs21
-rw-r--r--tests/ui/traits/next-solver/closure-signature-inference.rs15
-rw-r--r--tests/ui/traits/next-solver/closure-substs-ambiguity.rs (renamed from tests/ui/traits/new-solver/closure-substs-ambiguity.rs)2
-rw-r--r--tests/ui/traits/next-solver/coherence/issue-102048.rs (renamed from tests/ui/traits/new-solver/coherence/issue-102048.rs)2
-rw-r--r--tests/ui/traits/next-solver/coherence/issue-102048.stderr (renamed from tests/ui/traits/new-solver/coherence/issue-102048.stderr)0
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs (renamed from tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs)2
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr (renamed from tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr)0
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-1.rs (renamed from tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs)2
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-2.rs (renamed from tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs)2
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs (renamed from tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs)2
-rw-r--r--tests/ui/traits/next-solver/const-param-placeholder.fail.stderr (renamed from tests/ui/traits/new-solver/const-param-placeholder.fail.stderr)0
-rw-r--r--tests/ui/traits/next-solver/const-param-placeholder.rs (renamed from tests/ui/traits/new-solver/const-param-placeholder.rs)2
-rw-r--r--tests/ui/traits/next-solver/coroutine.fail.stderr (renamed from tests/ui/traits/new-solver/coroutine.fail.stderr)0
-rw-r--r--tests/ui/traits/next-solver/coroutine.rs (renamed from tests/ui/traits/new-solver/coroutine.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.rs (renamed from tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr (renamed from tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr)0
-rw-r--r--tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs (renamed from tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr (renamed from tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr)0
-rw-r--r--tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs (renamed from tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr (renamed from tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr)0
-rw-r--r--tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs (renamed from tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr (renamed from tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr)0
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs (renamed from tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr (renamed from tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr)0
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-cycle-but-ok.rs (renamed from tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs (renamed from tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs (renamed from tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr (renamed from tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr)0
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs (renamed from tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr (renamed from tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr)0
-rw-r--r--tests/ui/traits/next-solver/cycles/leak-check-coinductive-cycle.rs (renamed from tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs)2
-rw-r--r--tests/ui/traits/next-solver/cycles/provisional-result-done.rs (renamed from tests/ui/traits/new-solver/cycles/provisional-result-done.rs)2
-rw-r--r--tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs (renamed from tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs)2
-rw-r--r--tests/ui/traits/next-solver/deduce-ty-from-object.rs (renamed from tests/ui/traits/new-solver/deduce-ty-from-object.rs)2
-rw-r--r--tests/ui/traits/next-solver/dedup-regions.rs (renamed from tests/ui/traits/new-solver/dedup-regions.rs)2
-rw-r--r--tests/ui/traits/next-solver/destruct.rs (renamed from tests/ui/traits/new-solver/destruct.rs)2
-rw-r--r--tests/ui/traits/next-solver/dont-coerce-infer-to-dyn.rs (renamed from tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs)2
-rw-r--r--tests/ui/traits/next-solver/dont-elaborate-for-projections.rs (renamed from tests/ui/traits/new-solver/dont-elaborate-for-projections.rs)2
-rw-r--r--tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs (renamed from tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs)2
-rw-r--r--tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr (renamed from tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr)0
-rw-r--r--tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs (renamed from tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs)2
-rw-r--r--tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs (renamed from tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs)2
-rw-r--r--tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr (renamed from tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr)0
-rw-r--r--tests/ui/traits/next-solver/dont-remap-tait-substs.rs (renamed from tests/ui/traits/new-solver/dont-remap-tait-substs.rs)2
-rw-r--r--tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr (renamed from tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr)0
-rw-r--r--tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs (renamed from tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs)2
-rw-r--r--tests/ui/traits/next-solver/dyn-any-dont-prefer-impl.rs (renamed from tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs)2
-rw-r--r--tests/ui/traits/next-solver/elaborate-item-bounds.rs (renamed from tests/ui/traits/new-solver/elaborate-item-bounds.rs)2
-rw-r--r--tests/ui/traits/next-solver/equating-projection-cyclically.rs (renamed from tests/ui/traits/new-solver/equating-projection-cyclically.rs)2
-rw-r--r--tests/ui/traits/next-solver/escaping-bound-vars-in-writeback-normalization.rs (renamed from tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs)2
-rw-r--r--tests/ui/traits/next-solver/float-canonical.rs (renamed from tests/ui/traits/new-solver/float-canonical.rs)2
-rw-r--r--tests/ui/traits/next-solver/fn-trait-closure.rs (renamed from tests/ui/traits/new-solver/fn-trait-closure.rs)2
-rw-r--r--tests/ui/traits/next-solver/fn-trait.rs (renamed from tests/ui/traits/new-solver/fn-trait.rs)2
-rw-r--r--tests/ui/traits/next-solver/fn-trait.stderr (renamed from tests/ui/traits/new-solver/fn-trait.stderr)0
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs (renamed from tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs)2
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs (renamed from tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs)2
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr19
-rw-r--r--tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr (renamed from tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.next.stderr)0
-rw-r--r--tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs (renamed from tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.rs)2
-rw-r--r--tests/ui/traits/next-solver/higher-ranked-dyn-bounds.rs (renamed from tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs)2
-rw-r--r--tests/ui/traits/next-solver/int-var-alias-eq.rs (renamed from tests/ui/traits/new-solver/int-var-alias-eq.rs)2
-rw-r--r--tests/ui/traits/next-solver/int-var-is-send.rs (renamed from tests/ui/traits/new-solver/int-var-is-send.rs)2
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.rs22
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.stderr36
-rw-r--r--tests/ui/traits/next-solver/iter-filter-projection.rs (renamed from tests/ui/traits/new-solver/iter-filter-projection.rs)2
-rw-r--r--tests/ui/traits/next-solver/lazy-nested-obligations-1.rs (renamed from tests/ui/traits/new-solver/lazy-nested-obligations-1.rs)2
-rw-r--r--tests/ui/traits/next-solver/lazy-nested-obligations-2.rs (renamed from tests/ui/traits/new-solver/lazy-nested-obligations-2.rs)2
-rw-r--r--tests/ui/traits/next-solver/lazy-nested-obligations-3.rs (renamed from tests/ui/traits/new-solver/lazy-nested-obligations-3.rs)2
-rw-r--r--tests/ui/traits/next-solver/member-constraints-in-root-universe.rs (renamed from tests/ui/traits/new-solver/member-constraints-in-root-universe.rs)2
-rw-r--r--tests/ui/traits/next-solver/more-object-bound.rs (renamed from tests/ui/traits/new-solver/more-object-bound.rs)2
-rw-r--r--tests/ui/traits/next-solver/more-object-bound.stderr (renamed from tests/ui/traits/new-solver/more-object-bound.stderr)0
-rw-r--r--tests/ui/traits/next-solver/negative-coherence-bounds.rs (renamed from tests/ui/traits/new-solver/negative-coherence-bounds.rs)0
-rw-r--r--tests/ui/traits/next-solver/negative-coherence-bounds.stderr (renamed from tests/ui/traits/new-solver/negative-coherence-bounds.stderr)0
-rw-r--r--tests/ui/traits/next-solver/nested-alias-bound.rs (renamed from tests/ui/traits/new-solver/nested-alias-bound.rs)2
-rw-r--r--tests/ui/traits/next-solver/nested-obligations-with-bound-vars-gat.rs (renamed from tests/ui/traits/new-solver/nested-obligations-with-bound-vars-gat.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalize-async-closure-in-trait.rs (renamed from tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-1.rs (renamed from tests/ui/traits/new-solver/normalize-param-env-1.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-2.rs (renamed from tests/ui/traits/new-solver/normalize-param-env-2.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-3.rs (renamed from tests/ui/traits/new-solver/normalize-param-env-3.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalize-rcvr-for-inherent.rs (renamed from tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalize-unsize-rhs.rs (renamed from tests/ui/traits/new-solver/normalize-unsize-rhs.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalized-const-built-in-op.rs (renamed from tests/ui/traits/new-solver/normalized-const-built-in-op.rs)2
-rw-r--r--tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs (renamed from tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs)4
-rw-r--r--tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr (renamed from tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr)0
-rw-r--r--tests/ui/traits/next-solver/object-soundness-requires-generalization.rs (renamed from tests/ui/traits/new-solver/object-soundness-requires-generalization.rs)2
-rw-r--r--tests/ui/traits/next-solver/object-unsafety.rs (renamed from tests/ui/traits/new-solver/object-unsafety.rs)4
-rw-r--r--tests/ui/traits/next-solver/object-unsafety.stderr (renamed from tests/ui/traits/new-solver/object-unsafety.stderr)0
-rw-r--r--tests/ui/traits/next-solver/opportunistic-region-resolve.rs (renamed from tests/ui/traits/new-solver/opportunistic-region-resolve.rs)2
-rw-r--r--tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs (renamed from tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs)2
-rw-r--r--tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr (renamed from tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr)0
-rw-r--r--tests/ui/traits/next-solver/overflow/global-cache.rs (renamed from tests/ui/traits/new-solver/overflow/global-cache.rs)2
-rw-r--r--tests/ui/traits/next-solver/overflow/global-cache.stderr (renamed from tests/ui/traits/new-solver/overflow/global-cache.stderr)0
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs (renamed from tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.rs)2
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr (renamed from tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.stderr)0
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs (renamed from tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs)2
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr (renamed from tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr)0
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs (renamed from tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs)2
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr (renamed from tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr)0
-rw-r--r--tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs (renamed from tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs)2
-rw-r--r--tests/ui/traits/next-solver/param-discr-kind.rs (renamed from tests/ui/traits/new-solver/param-discr-kind.rs)2
-rw-r--r--tests/ui/traits/next-solver/pointee.rs (renamed from tests/ui/traits/new-solver/pointee.rs)2
-rw-r--r--tests/ui/traits/next-solver/pointer-like.rs (renamed from tests/ui/traits/new-solver/pointer-like.rs)2
-rw-r--r--tests/ui/traits/next-solver/pointer-like.stderr (renamed from tests/ui/traits/new-solver/pointer-like.stderr)0
-rw-r--r--tests/ui/traits/next-solver/prefer-candidate-no-constraints.rs (renamed from tests/ui/traits/new-solver/prefer-candidate-no-constraints.rs)2
-rw-r--r--tests/ui/traits/next-solver/prefer-param-env-on-ambiguity.rs (renamed from tests/ui/traits/new-solver/prefer-param-env-on-ambiguity.rs)2
-rw-r--r--tests/ui/traits/next-solver/projection-discr-kind.rs (renamed from tests/ui/traits/new-solver/projection-discr-kind.rs)2
-rw-r--r--tests/ui/traits/next-solver/projection-discr-kind.stderr (renamed from tests/ui/traits/new-solver/projection-discr-kind.stderr)0
-rw-r--r--tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs (renamed from tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs)2
-rw-r--r--tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs (renamed from tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs)2
-rw-r--r--tests/ui/traits/next-solver/slice-match-byte-lit.rs (renamed from tests/ui/traits/new-solver/slice-match-byte-lit.rs)2
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.rs (renamed from tests/ui/traits/new-solver/specialization-transmute.rs)2
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.stderr (renamed from tests/ui/traits/new-solver/specialization-transmute.stderr)0
-rw-r--r--tests/ui/traits/next-solver/specialization-unconstrained.rs (renamed from tests/ui/traits/new-solver/specialization-unconstrained.rs)2
-rw-r--r--tests/ui/traits/next-solver/specialization-unconstrained.stderr (renamed from tests/ui/traits/new-solver/specialization-unconstrained.stderr)0
-rw-r--r--tests/ui/traits/next-solver/stall-num-var-auto-trait.fallback.stderr (renamed from tests/ui/traits/new-solver/stall-num-var-auto-trait.fallback.stderr)0
-rw-r--r--tests/ui/traits/next-solver/stall-num-var-auto-trait.rs (renamed from tests/ui/traits/new-solver/stall-num-var-auto-trait.rs)2
-rw-r--r--tests/ui/traits/next-solver/structural-resolve-field.rs (renamed from tests/ui/traits/new-solver/structural-resolve-field.rs)2
-rw-r--r--tests/ui/traits/next-solver/tait-eq-proj-2.rs (renamed from tests/ui/traits/new-solver/tait-eq-proj-2.rs)4
-rw-r--r--tests/ui/traits/next-solver/tait-eq-proj.rs (renamed from tests/ui/traits/new-solver/tait-eq-proj.rs)2
-rw-r--r--tests/ui/traits/next-solver/tait-eq-tait.rs (renamed from tests/ui/traits/new-solver/tait-eq-tait.rs)2
-rw-r--r--tests/ui/traits/next-solver/temporary-ambiguity.rs (renamed from tests/ui/traits/new-solver/temporary-ambiguity.rs)2
-rw-r--r--tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs (renamed from tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs)2
-rw-r--r--tests/ui/traits/next-solver/try-example.rs (renamed from tests/ui/traits/new-solver/try-example.rs)2
-rw-r--r--tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.rs (renamed from tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs)2
-rw-r--r--tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.stderr (renamed from tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr)0
-rw-r--r--tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr (renamed from tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.fails.stderr)0
-rw-r--r--tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs (renamed from tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.rs)2
-rw-r--r--tests/ui/traits/next-solver/unsafe-auto-trait-impl.rs (renamed from tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs)2
-rw-r--r--tests/ui/traits/next-solver/unsize-although-ambiguous.rs (renamed from tests/ui/traits/new-solver/unsize-although-ambiguous.rs)2
-rw-r--r--tests/ui/traits/next-solver/unsize-good.rs (renamed from tests/ui/traits/new-solver/unsize-good.rs)2
-rw-r--r--tests/ui/traits/next-solver/upcast-right-substs.rs (renamed from tests/ui/traits/new-solver/upcast-right-substs.rs)2
-rw-r--r--tests/ui/traits/next-solver/upcast-wrong-substs.rs (renamed from tests/ui/traits/new-solver/upcast-wrong-substs.rs)2
-rw-r--r--tests/ui/traits/next-solver/upcast-wrong-substs.stderr (renamed from tests/ui/traits/new-solver/upcast-wrong-substs.stderr)0
-rw-r--r--tests/ui/traits/next-solver/winnow-specializing-impls.rs (renamed from tests/ui/traits/new-solver/winnow-specializing-impls.rs)2
-rw-r--r--tests/ui/traits/non-lifetime-via-dyn-builtin.rs2
-rw-r--r--tests/ui/traits/reservation-impl/coherence-conflict.rs2
-rw-r--r--tests/ui/traits/reservation-impl/no-use.rs2
-rw-r--r--tests/ui/traits/reservation-impl/non-lattice-ok.rs2
-rw-r--r--tests/ui/traits/reservation-impl/ok.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/fewer-associated.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/issue-11515.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/normalization.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs2
-rw-r--r--tests/ui/transmutability/primitives/bool-mut.rs2
-rw-r--r--tests/ui/transmutability/primitives/bool.rs2
-rw-r--r--tests/ui/transmutability/primitives/numbers.rs2
-rw-r--r--tests/ui/transmutability/primitives/unit.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-type-const.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-78450.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/normalize-hidden-types.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/wf-in-associated-type.rs2
-rw-r--r--tests/ui/unsized/issue-71659.rs2
-rw-r--r--tests/ui/unsized/issue-75899.rs2
-rw-r--r--triagebot.toml14
839 files changed, 7684 insertions, 5252 deletions
diff --git a/.gitmodules b/.gitmodules
index f5025097a18..9bb68b37081 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -33,7 +33,7 @@
 [submodule "src/llvm-project"]
 	path = src/llvm-project
 	url = https://github.com/rust-lang/llvm-project.git
-	branch = rustc/17.0-2023-09-19
+	branch = rustc/17.0-2023-12-14
 	shallow = true
 [submodule "src/doc/embedded-book"]
 	path = src/doc/embedded-book
diff --git a/Cargo.lock b/Cargo.lock
index 9f82b2e1640..98c030b3996 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -548,7 +548,7 @@ dependencies = [
  "futures",
  "if_chain",
  "itertools",
- "parking_lot 0.12.1",
+ "parking_lot",
  "quote",
  "regex",
  "rustc_tools_util",
@@ -867,16 +867,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "cstr"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b"
-dependencies = [
- "proc-macro2",
- "quote",
-]
-
-[[package]]
 name = "ctrlc"
 version = "3.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2366,13 +2356,13 @@ dependencies = [
 
 [[package]]
 name = "measureme"
-version = "10.1.1"
+version = "10.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1930d162935fecd56fc4e0f6729eb3483bac1264542eb4ea31570b86a434b6bc"
+checksum = "45e381dcdad44c3c435f8052b08c5c4a1449c48ab56f312345eae12d7a693dbe"
 dependencies = [
  "log",
  "memmap2",
- "parking_lot 0.11.2",
+ "parking_lot",
  "perf-event-open-sys",
  "rustc-hash",
  "smallvec",
@@ -2792,37 +2782,12 @@ dependencies = [
 
 [[package]]
 name = "parking_lot"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
-dependencies = [
- "instant",
- "lock_api",
- "parking_lot_core 0.8.6",
-]
-
-[[package]]
-name = "parking_lot"
 version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.8",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
-dependencies = [
- "cfg-if",
- "instant",
- "libc",
- "redox_syscall 0.2.16",
- "smallvec",
- "winapi",
+ "parking_lot_core",
 ]
 
 [[package]]
@@ -3582,7 +3547,6 @@ name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.3.2",
- "cstr",
  "itertools",
  "libc",
  "measureme",
@@ -3693,7 +3657,7 @@ dependencies = [
  "libc",
  "measureme",
  "memmap2",
- "parking_lot 0.12.1",
+ "parking_lot",
  "portable-atomic",
  "rustc-hash",
  "rustc-rayon",
@@ -4428,7 +4392,7 @@ dependencies = [
 name = "rustc_query_system"
 version = "0.0.0"
 dependencies = [
- "parking_lot 0.12.1",
+ "parking_lot",
  "rustc-rayon-core",
  "rustc_ast",
  "rustc_data_structures",
@@ -5145,7 +5109,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
 dependencies = [
  "new_debug_unreachable",
  "once_cell",
- "parking_lot 0.12.1",
+ "parking_lot",
  "phf_shared",
  "precomputed-hash",
  "serde",
@@ -5670,7 +5634,7 @@ dependencies = [
  "matchers",
  "nu-ansi-term",
  "once_cell",
- "parking_lot 0.12.1",
+ "parking_lot",
  "regex",
  "sharded-slab",
  "smallvec",
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 050366b081f..5252472261f 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -382,7 +382,7 @@ pub trait LayoutCalculator {
                             *offset += this_offset;
                         }
                     }
-                    _ => {
+                    FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
                         panic!("Layout of fields should be Arbitrary for variants")
                     }
                 }
@@ -600,7 +600,9 @@ pub trait LayoutCalculator {
                             variant.size = new_ity_size;
                         }
                     }
-                    _ => panic!(),
+                    FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
+                        panic!("encountered a non-arbitrary layout during enum layout")
+                    }
                 }
             }
         }
@@ -628,7 +630,7 @@ pub trait LayoutCalculator {
             let mut common_prim_initialized_in_all_variants = true;
             for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
                 let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
-                    panic!();
+                    panic!("encountered a non-arbitrary layout during enum layout");
                 };
                 // We skip *all* ZST here and later check if we are good in terms of alignment.
                 // This lets us handle some cases involving aligned ZST.
@@ -681,7 +683,7 @@ pub trait LayoutCalculator {
                         assert_eq!(memory_index.raw, [0, 1]);
                         offsets
                     }
-                    _ => panic!(),
+                    _ => panic!("encountered a non-arbitrary layout during enum layout"),
                 };
                 if pair_offsets[FieldIdx::new(0)] == Size::ZERO
                     && pair_offsets[FieldIdx::new(1)] == *offset
@@ -758,7 +760,9 @@ pub trait LayoutCalculator {
             Variants::Multiple { tag, tag_encoding, tag_field, .. } => {
                 Variants::Multiple { tag, tag_encoding, tag_field, variants: best_layout.variants }
             }
-            _ => panic!(),
+            Variants::Single { .. } => {
+                panic!("encountered a single-variant enum during multi-variant layout")
+            }
         };
         Some(best_layout.layout)
     }
@@ -1154,7 +1158,11 @@ fn univariant<
                                 assert_eq!(memory_index.raw, [0, 1]);
                                 offsets
                             }
-                            _ => panic!(),
+                            FieldsShape::Primitive
+                            | FieldsShape::Array { .. }
+                            | FieldsShape::Union(..) => {
+                                panic!("encountered a non-arbitrary layout during enum layout")
+                            }
                         };
                         if offsets[i] == pair_offsets[FieldIdx::new(0)]
                             && offsets[j] == pair_offsets[FieldIdx::new(1)]
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5755ae8a8bc..9d543563c0f 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2845,6 +2845,28 @@ impl Item {
     pub fn span_with_attributes(&self) -> Span {
         self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
     }
+
+    pub fn opt_generics(&self) -> Option<&Generics> {
+        match &self.kind {
+            ItemKind::ExternCrate(_)
+            | ItemKind::Use(_)
+            | ItemKind::Mod(_, _)
+            | ItemKind::ForeignMod(_)
+            | ItemKind::GlobalAsm(_)
+            | ItemKind::MacCall(_)
+            | ItemKind::MacroDef(_) => None,
+            ItemKind::Static(_) => None,
+            ItemKind::Const(i) => Some(&i.generics),
+            ItemKind::Fn(i) => Some(&i.generics),
+            ItemKind::TyAlias(i) => Some(&i.generics),
+            ItemKind::TraitAlias(generics, _)
+            | ItemKind::Enum(_, generics)
+            | ItemKind::Struct(_, generics)
+            | ItemKind::Union(_, generics) => Some(&generics),
+            ItemKind::Trait(i) => Some(&i.generics),
+            ItemKind::Impl(i) => Some(&i.generics),
+        }
+    }
 }
 
 /// `extern` qualifier on a function item or function type.
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 7111daa2ea9..4c81983c242 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -336,7 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         hir::InlineAsmOperand::Const { .. }
                         | hir::InlineAsmOperand::SymFn { .. }
                         | hir::InlineAsmOperand::SymStatic { .. } => {
-                            unreachable!()
+                            unreachable!("{op:?} is not a register operand");
                         }
                     };
 
@@ -380,7 +380,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                     {
                                         reg_sym.as_str()
                                     } else {
-                                        unreachable!();
+                                        unreachable!("{op:?} is not a register operand");
                                     }
                                 };
 
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index a44b408feec..11b5131b8d7 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1222,6 +1222,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 | ExprKind::Struct(..)
                 | ExprKind::Tup(..)
                 | ExprKind::Underscore => false,
+                // Check for unit struct constructor.
+                ExprKind::Path(..) => lower_ctx.extract_unit_struct_path(lhs).is_none(),
                 // Check for tuple struct constructor.
                 ExprKind::Call(callee, ..) => lower_ctx.extract_tuple_struct_path(callee).is_none(),
                 ExprKind::Paren(e) => {
@@ -1258,9 +1260,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         );
 
         // `a = lhs1; b = lhs2;`.
-        let stmts = self
-            .arena
-            .alloc_from_iter(std::iter::once(destructure_let).chain(assignments.into_iter()));
+        let stmts = self.arena.alloc_from_iter(std::iter::once(destructure_let).chain(assignments));
 
         // Wrap everything in a block.
         hir::ExprKind::Block(self.block_all(whole_span, stmts, None), None)
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 7c05724f64c..83452c22280 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -421,8 +421,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
             ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
                 let body = P(self.lower_delim_args(body));
-                let DefKind::Macro(macro_kind) = self.tcx.def_kind(self.local_def_id(id)) else {
-                    unreachable!()
+                let def_id = self.local_def_id(id);
+                let def_kind = self.tcx.def_kind(def_id);
+                let DefKind::Macro(macro_kind) = def_kind else {
+                    unreachable!(
+                        "expected DefKind::Macro for macro item, found {}",
+                        def_kind.descr(def_id.to_def_id())
+                    );
                 };
                 let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
                 hir::ItemKind::Macro(macro_def, macro_kind)
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d9663d50c59..5c9e43f1e06 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -453,6 +453,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
     tcx.ensure_with_value().output_filenames(());
     tcx.ensure_with_value().early_lint_checks(());
     tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
+    tcx.ensure_with_value().get_lang_items(());
     let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal();
 
     let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
@@ -765,6 +766,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.resolver.get_import_res(id).present_items()
     }
 
+    fn make_lang_item_path(
+        &mut self,
+        lang_item: hir::LangItem,
+        span: Span,
+        args: Option<&'hir hir::GenericArgs<'hir>>,
+    ) -> &'hir hir::Path<'hir> {
+        let def_id = self.tcx.require_lang_item(lang_item, Some(span));
+        let def_kind = self.tcx.def_kind(def_id);
+        let res = Res::Def(def_kind, def_id);
+        self.arena.alloc(hir::Path {
+            span,
+            res,
+            segments: self.arena.alloc_from_iter([hir::PathSegment {
+                ident: Ident::new(lang_item.name(), span),
+                hir_id: self.next_id(),
+                res,
+                args,
+                infer_args: false,
+            }]),
+        })
+    }
+
     /// Reuses the span but adds information like the kind of the desugaring and features that are
     /// allowed inside this span.
     fn mark_span_with_reason(
@@ -1976,18 +1999,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
         };
 
-        let future_args = self.arena.alloc(hir::GenericArgs {
+        let bound_args = self.arena.alloc(hir::GenericArgs {
             args: &[],
             bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
             parenthesized: hir::GenericArgsParentheses::No,
             span_ext: DUMMY_SP,
         });
 
-        hir::GenericBound::LangItemTrait(
-            trait_lang_item,
-            opaque_ty_span,
-            self.next_id(),
-            future_args,
+        hir::GenericBound::Trait(
+            hir::PolyTraitRef {
+                bound_generic_params: &[],
+                trait_ref: hir::TraitRef {
+                    path: self.make_lang_item_path(
+                        trait_lang_item,
+                        opaque_ty_span,
+                        Some(bound_args),
+                    ),
+                    hir_ref_id: self.next_id(),
+                },
+                span: opaque_ty_span,
+            },
+            hir::TraitBoundModifier::None,
         )
     }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 7e62bb9793d..2f366001d4b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -18,7 +18,7 @@ use rustc_middle::mir::{
     PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
     VarBindingForm,
 };
-use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
+use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty, TyCtxt};
 use rustc_middle::util::CallKind;
 use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
 use rustc_span::def_id::LocalDefId;
@@ -398,7 +398,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 }
                 let typeck = self.infcx.tcx.typeck(self.mir_def_id());
                 let hir_id = hir.parent_id(expr.hir_id);
-                if let Some(parent) = hir.find(hir_id) {
+                if let Some(parent) = self.infcx.tcx.opt_hir_node(hir_id) {
                     let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
                         && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
                         && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
@@ -413,7 +413,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         (None, &[][..], 0)
                     };
                     if let Some(def_id) = def_id
-                        && let Some(node) = hir.find(self.infcx.tcx.local_def_id_to_hir_id(def_id))
+                        && let Some(node) = self
+                            .infcx
+                            .tcx
+                            .opt_hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
                         && let Some(fn_sig) = node.fn_sig()
                         && let Some(ident) = node.ident()
                         && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
@@ -1317,7 +1320,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let tcx = self.infcx.tcx;
         let hir = tcx.hir();
 
-        let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return };
+        let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
         let typeck_results = tcx.typeck(self.mir_def_id());
 
         struct ExprFinder<'hir> {
@@ -1509,7 +1512,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let local_ty = self.body.local_decls[local].ty;
 
         // Get the body the error happens in
-        let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return };
+        let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
 
         let body_expr = hir.body(body_id).value;
 
@@ -1558,7 +1561,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // Check that the parent of the closure is a method call,
         // with receiver matching with local's type (modulo refs)
         let parent = hir.parent_id(closure_expr.hir_id);
-        if let hir::Node::Expr(parent) = hir.get(parent) {
+        if let hir::Node::Expr(parent) = tcx.hir_node(parent) {
             if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind {
                 let recv_ty = typeck_results.expr_ty(recv);
 
@@ -1635,15 +1638,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         issued_spans: &UseSpans<'tcx>,
     ) {
         let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return };
-        let hir = self.infcx.tcx.hir();
 
-        struct ExpressionFinder<'hir> {
+        struct ExpressionFinder<'tcx> {
             capture_span: Span,
             closure_change_spans: Vec<Span>,
             closure_arg_span: Option<Span>,
             in_closure: bool,
             suggest_arg: String,
-            hir: rustc_middle::hir::map::Map<'hir>,
+            tcx: TyCtxt<'tcx>,
             closure_local_id: Option<hir::HirId>,
             closure_call_changes: Vec<(Span, String)>,
         }
@@ -1657,7 +1659,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         fn_decl: hir::FnDecl { inputs, .. },
                         ..
                     }) = e.kind
-                        && let Some(hir::Node::Expr(body)) = self.hir.find(body.hir_id)
+                        && let Some(hir::Node::Expr(body)) = self.tcx.opt_hir_node(body.hir_id)
                     {
                         self.suggest_arg = "this: &Self".to_string();
                         if inputs.len() > 0 {
@@ -1722,8 +1724,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         if let Some(hir::Node::ImplItem(hir::ImplItem {
             kind: hir::ImplItemKind::Fn(_fn_sig, body_id),
             ..
-        })) = hir.find(self.mir_hir_id())
-            && let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id)
+        })) = self.infcx.tcx.opt_hir_node(self.mir_hir_id())
+            && let Some(hir::Node::Expr(expr)) = self.infcx.tcx.opt_hir_node(body_id.hir_id)
         {
             let mut finder = ExpressionFinder {
                 capture_span: *capture_kind_span,
@@ -1733,7 +1735,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 suggest_arg: String::new(),
                 closure_local_id: None,
                 closure_call_changes: vec![],
-                hir,
+                tcx: self.infcx.tcx,
             };
             finder.visit_expr(expr);
 
@@ -2294,7 +2296,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 let proper_span = proper_span.source_callsite();
                 if let Some(scope) = self.body.source_scopes.get(source_info.scope)
                     && let ClearCrossCrate::Set(scope_data) = &scope.local_data
-                    && let Some(node) = self.infcx.tcx.hir().find(scope_data.lint_root)
+                    && let Some(node) = self.infcx.tcx.opt_hir_node(scope_data.lint_root)
                     && let Some(id) = node.body_id()
                     && let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir().body(id).value.kind
                 {
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index bed3df4809d..f1e712d814a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -87,7 +87,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
                     if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
                         && let [hir::PathSegment { ident, args: None, .. }] = p.segments
                         && let hir::def::Res::Local(hir_id) = p.res
-                        && let Some(hir::Node::Pat(pat)) = tcx.hir().find(hir_id)
+                        && let Some(hir::Node::Pat(pat)) = tcx.opt_hir_node(hir_id)
                     {
                         err.span_label(pat.span, format!("binding `{ident}` declared here"));
                     }
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 8fe552708ed..c3c1f1293d2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -396,7 +396,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
                 let upvar_hir_id = captured_place.get_root_variable();
 
-                if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id)
+                if let Some(Node::Pat(pat)) = self.infcx.tcx.opt_hir_node(upvar_hir_id)
                     && let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) =
                         pat.kind
                 {
@@ -661,7 +661,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         if self.body.local_kind(local) != LocalKind::Arg {
             return (false, None);
         }
-        let hir_map = self.infcx.tcx.hir();
         let my_def = self.body.source.def_id();
         let my_hir = self.infcx.tcx.local_def_id_to_hir_id(my_def.as_local().unwrap());
         let Some(td) =
@@ -671,7 +670,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         };
         (
             true,
-            td.as_local().and_then(|tld| match hir_map.find_by_def_id(tld) {
+            td.as_local().and_then(|tld| match self.infcx.tcx.opt_hir_node_by_def_id(tld) {
                 Some(Node::Item(hir::Item {
                     kind: hir::ItemKind::Trait(_, _, _, _, items),
                     ..
@@ -682,25 +681,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         if !matches!(k, hir::AssocItemKind::Fn { .. }) {
                             continue;
                         }
-                        if hir_map.name(hi) != hir_map.name(my_hir) {
+                        if self.infcx.tcx.hir().name(hi) != self.infcx.tcx.hir().name(my_hir) {
                             continue;
                         }
                         f_in_trait_opt = Some(hi);
                         break;
                     }
-                    f_in_trait_opt.and_then(|f_in_trait| match hir_map.find(f_in_trait) {
-                        Some(Node::TraitItem(hir::TraitItem {
-                            kind:
-                                hir::TraitItemKind::Fn(
-                                    hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
-                                    _,
-                                ),
-                            ..
-                        })) => {
-                            let hir::Ty { span, .. } = inputs[local.index() - 1];
-                            Some(span)
+                    f_in_trait_opt.and_then(|f_in_trait| {
+                        match self.infcx.tcx.opt_hir_node(f_in_trait) {
+                            Some(Node::TraitItem(hir::TraitItem {
+                                kind:
+                                    hir::TraitItemKind::Fn(
+                                        hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
+                                        _,
+                                    ),
+                                ..
+                            })) => {
+                                let hir::Ty { span, .. } = inputs[local.index() - 1];
+                                Some(span)
+                            }
+                            _ => None,
                         }
-                        _ => None,
                     })
                 }
                 _ => None,
@@ -741,12 +742,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             }
         }
 
-        let hir_map = self.infcx.tcx.hir();
         let def_id = self.body.source.def_id();
         let hir_id = if let Some(local_def_id) = def_id.as_local()
-            && let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id)
+            && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
         {
-            let body = hir_map.body(body_id);
+            let body = self.infcx.tcx.hir().body(body_id);
             let mut v = BindingFinder { span: pat_span, hir_id: None };
             v.visit_body(body);
             v.hir_id
@@ -762,7 +762,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             && let Some(hir::Node::Local(hir::Local {
                 pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
                 ..
-            })) = hir_map.find(hir_id)
+            })) = self.infcx.tcx.opt_hir_node(hir_id)
             && let Ok(name) =
                 self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
         {
@@ -942,7 +942,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let closure_id = self.mir_hir_id();
         let closure_span = self.infcx.tcx.def_span(self.mir_def_id());
         let fn_call_id = hir.parent_id(closure_id);
-        let node = hir.get(fn_call_id);
+        let node = self.infcx.tcx.hir_node(fn_call_id);
         let def_id = hir.enclosing_body_owner(fn_call_id);
         let mut look_at_return = true;
         // If we can detect the expression to be an `fn` call where the closure was an argument,
@@ -1001,7 +1001,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         if look_at_return && hir.get_return_block(closure_id).is_some() {
             // ...otherwise we are probably in the tail expression of the function, point at the
             // return type.
-            match hir.get_by_def_id(hir.get_parent_item(fn_call_id).def_id) {
+            match self.infcx.tcx.hir_node_by_def_id(hir.get_parent_item(fn_call_id).def_id) {
                 hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. })
                 | hir::Node::TraitItem(hir::TraitItem {
                     ident,
@@ -1199,12 +1199,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         hir::intravisit::walk_stmt(self, s);
                     }
                 }
-                let hir_map = self.infcx.tcx.hir();
                 let def_id = self.body.source.def_id();
                 let hir_id = if let Some(local_def_id) = def_id.as_local()
-                    && let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id)
+                    && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
                 {
-                    let body = hir_map.body(body_id);
+                    let body = self.infcx.tcx.hir().body(body_id);
                     let mut v = BindingFinder { span: err_label_span, hir_id: None };
                     v.visit_body(body);
                     v.hir_id
@@ -1213,7 +1212,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 };
 
                 if let Some(hir_id) = hir_id
-                    && let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
+                    && let Some(hir::Node::Local(local)) = self.infcx.tcx.opt_hir_node(hir_id)
                 {
                     let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap());
                     if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()
@@ -1496,7 +1495,7 @@ fn get_mut_span_in_struct_field<'tcx>(
         && let ty::Adt(def, _) = ty.kind()
         && let field = def.all_fields().nth(field.index())?
         // Use the HIR types to construct the diagnostic message.
-        && let node = tcx.hir().find_by_def_id(field.did.as_local()?)?
+        && let node = tcx.opt_hir_node_by_def_id(field.did.as_local()?)?
         // Now we're dealing with the actual struct that we're going to suggest a change to,
         // we can expect a field that is an immutable reference to a type.
         && let hir::Node::Field(field) = node
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index a17c3bc3a78..8441dfaa7df 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -672,7 +672,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
 
         let mir_hir_id = self.mir_hir_id();
 
-        let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) {
+        let (return_span, mir_description, hir_ty) = match tcx.hir_node(mir_hir_id) {
             hir::Node::Expr(hir::Expr {
                 kind: hir::ExprKind::Closure(&hir::Closure { fn_decl, body, fn_decl_span, .. }),
                 ..
@@ -689,7 +689,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                         hir::CoroutineSource::Closure => " of async closure",
                         hir::CoroutineSource::Fn => {
                             let parent_item =
-                                hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
+                                tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
                             let output = &parent_item
                                 .fn_decl()
                                 .expect("coroutine lowered from async fn should be in fn")
@@ -706,7 +706,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                         hir::CoroutineSource::Closure => " of gen closure",
                         hir::CoroutineSource::Fn => {
                             let parent_item =
-                                hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
+                                tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
                             let output = &parent_item
                                 .fn_decl()
                                 .expect("coroutine lowered from gen fn should be in fn")
@@ -721,7 +721,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                         hir::CoroutineSource::Closure => " of async gen closure",
                         hir::CoroutineSource::Fn => {
                             let parent_item =
-                                hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
+                                tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
                             let output = &parent_item
                                 .fn_decl()
                                 .expect("coroutine lowered from async gen fn should be in fn")
@@ -788,28 +788,18 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         };
         let opaque_ty = hir.item(id);
         if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-            bounds:
-                [
-                    hir::GenericBound::LangItemTrait(
-                        hir::LangItem::Future,
-                        _,
-                        _,
-                        hir::GenericArgs {
-                            bindings:
-                                [
-                                    hir::TypeBinding {
-                                        ident: Ident { name: sym::Output, .. },
-                                        kind:
-                                            hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
-                                        ..
-                                    },
-                                ],
-                            ..
-                        },
-                    ),
-                ],
+            bounds: [hir::GenericBound::Trait(trait_ref, _)],
             ..
         }) = opaque_ty.kind
+            && let Some(segment) = trait_ref.trait_ref.path.segments.last()
+            && let Some(args) = segment.args
+            && let [
+                hir::TypeBinding {
+                    ident: Ident { name: sym::Output, .. },
+                    kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
+                    ..
+                },
+            ] = args.bindings
         {
             ty
         } else {
@@ -841,7 +831,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         let type_name =
             self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).name;
 
-        let yield_span = match tcx.hir().get(self.mir_hir_id()) {
+        let yield_span = match tcx.hir_node(self.mir_hir_id()) {
             hir::Node::Expr(hir::Expr {
                 kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
                 ..
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 3d3fd412ae0..7e0e598cd9f 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -2502,8 +2502,8 @@ mod error {
             if !self.errors.buffered.is_empty() {
                 self.errors.buffered.sort_by_key(|diag| diag.sort_span);
 
-                for mut diag in self.errors.buffered.drain(..) {
-                    self.infcx.tcx.sess.diagnostic().emit_diagnostic(&mut diag);
+                for diag in self.errors.buffered.drain(..) {
+                    self.infcx.tcx.sess.diagnostic().emit_diagnostic(diag);
                 }
             }
 
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index c93cfa78832..3764e4c4008 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -315,7 +315,7 @@ fn check_opaque_type_well_formed<'tcx>(
         parent_def_id = tcx.local_parent(parent_def_id);
     }
 
-    // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
+    // FIXME(-Znext-solver): We probably should use `DefiningAnchor::Error`
     // and prepopulate this `InferCtxt` with known opaque values, rather than
     // using the `Bind` anchor here. For now it's fine.
     let infcx = tcx
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index e782221a4c2..98c21693cf0 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1003,16 +1003,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             reported_errors: Default::default(),
         };
 
-        // FIXME(-Ztrait-solver=next): A bit dubious that we're only registering
+        // FIXME(-Znext-solver): A bit dubious that we're only registering
         // predefined opaques in the typeck root.
         if infcx.next_trait_solver() && !infcx.tcx.is_typeck_child(body.source.def_id()) {
-            checker.register_predefined_opaques_in_new_solver();
+            checker.register_predefined_opaques_for_next_solver();
         }
 
         checker
     }
 
-    pub(super) fn register_predefined_opaques_in_new_solver(&mut self) {
+    pub(super) fn register_predefined_opaques_for_next_solver(&mut self) {
         // OK to use the identity arguments for each opaque type key, since
         // we remap opaques from HIR typeck back to their definition params.
         let opaques: Vec<_> = self
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 0a3af2c2e13..3d02cd72e54 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -453,7 +453,7 @@ impl<'a> IntoDiagnostic<'a> for EnvNotDefinedWithUserMessage {
             rustc::untranslatable_diagnostic,
             reason = "cannot translate user-provided messages"
         )]
-        let mut diag = handler.struct_diagnostic(self.msg_from_user.to_string());
+        let mut diag = handler.struct_err(self.msg_from_user.to_string());
         diag.set_span(self.span);
         diag
     }
@@ -804,7 +804,7 @@ pub(crate) struct AsmClobberNoReg {
 impl<'a> IntoDiagnostic<'a> for AsmClobberNoReg {
     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
         let mut diag =
-            handler.struct_diagnostic(crate::fluent_generated::builtin_macros_asm_clobber_no_reg);
+            handler.struct_err(crate::fluent_generated::builtin_macros_asm_clobber_no_reg);
         diag.set_span(self.spans.clone());
         // eager translation as `span_labels` takes `AsRef<str>`
         let lbl1 = handler.eagerly_translate_to_string(
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index 3309a0a6abd..1a38d5967f4 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -75,11 +75,6 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
         "example/arbitrary_self_types_pointers_and_wrappers.rs",
         &[],
     ),
-    TestCase::build_bin_and_run(
-        "aot.issue_91827_extern_types",
-        "example/issue-91827-extern-types.rs",
-        &[],
-    ),
     TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"),
     TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]),
     TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""),
diff --git a/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs b/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs
index 14bd23e77ea..25bfe542d22 100644
--- a/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs
+++ b/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs
@@ -1,7 +1,7 @@
 // Copied from https://github.com/rust-lang/rust/blob/46455dc65069387f2dc46612f13fd45452ab301a/tests/ui/coroutine/gen_block_iterate.rs
 // revisions: next old
 //compile-flags: --edition 2024 -Zunstable-options
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // run-pass
 #![feature(gen_blocks)]
 
diff --git a/compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs b/compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs
deleted file mode 100644
index 6f39c5edcad..00000000000
--- a/compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copied from rustc ui test suite
-
-// run-pass
-//
-// Test that we can handle unsized types with an extern type tail part.
-// Regression test for issue #91827.
-
-#![feature(extern_types)]
-
-use std::ptr::addr_of;
-
-extern "C" {
-    type Opaque;
-}
-
-unsafe impl Sync for Opaque {}
-
-#[repr(C)]
-pub struct List<T> {
-    len: usize,
-    data: [T; 0],
-    tail: Opaque,
-}
-
-#[repr(C)]
-pub struct ListImpl<T, const N: usize> {
-    len: usize,
-    data: [T; N],
-}
-
-impl<T> List<T> {
-    const fn as_slice(&self) -> &[T] {
-        unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
-    }
-}
-
-impl<T, const N: usize> ListImpl<T, N> {
-    const fn as_list(&self) -> &List<T> {
-        unsafe { std::mem::transmute(self) }
-    }
-}
-
-pub static A: ListImpl<u128, 3> = ListImpl { len: 3, data: [5, 6, 7] };
-pub static A_REF: &'static List<u128> = A.as_list();
-pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
-
-const fn tail_offset<T>(list: &List<T>) -> isize {
-    unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
-}
-
-fn main() {
-    assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
-    // Check that interpreter and code generation agree about the position of the tail field.
-    assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
-}
diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs
index c8c098e2973..7c7044830f3 100644
--- a/compiler/rustc_codegen_gcc/src/allocator.rs
+++ b/compiler/rustc_codegen_gcc/src/allocator.rs
@@ -90,7 +90,7 @@ fn create_wrapper_function(
         .collect();
     let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, from_name, false);
 
-    if tcx.sess.target.options.default_hidden_visibility {
+    if tcx.sess.default_hidden_visibility() {
         #[cfg(feature="master")]
         func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
     }
diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs
index 1248fdcd259..2aa84f26797 100644
--- a/compiler/rustc_codegen_gcc/src/gcc_util.rs
+++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs
@@ -2,12 +2,10 @@
 use gccjit::Context;
 use smallvec::{smallvec, SmallVec};
 
-use rustc_codegen_ssa::target_features::{
-    supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES,
-};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::bug;
 use rustc_session::Session;
+use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
 
 use crate::errors::{PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature, UnknownCTargetFeaturePrefix};
 
@@ -44,7 +42,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
     );
 
     // -Ctarget-features
-    let supported_features = supported_target_features(sess);
+    let supported_features = sess.target.supported_target_features();
     let mut featsmap = FxHashMap::default();
     let feats = sess.opts.cg.target_feature
         .split(',')
@@ -187,7 +185,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
 // Given a map from target_features to whether they are enabled or disabled,
 // ensure only valid combinations are allowed.
 pub fn check_tied_features(sess: &Session, features: &FxHashMap<&str, bool>) -> Option<&'static [&'static str]> {
-    for tied in tied_target_features(sess) {
+    for tied in sess.target.tied_target_features() {
         // Tied features must be set to the same value, or not set at all
         let mut tied_iter = tied.iter();
         let enabled = features.get(tied_iter.next().unwrap());
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index d54057615d2..0ececc5dda0 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -97,7 +97,6 @@ use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
 use rustc_codegen_ssa::base::codegen_crate;
 use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn};
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
-use rustc_codegen_ssa::target_features::supported_target_features;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::IntoDynSyncSend;
 use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods};
@@ -397,7 +396,9 @@ fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel {
 }
 
 pub fn target_features(sess: &Session, allow_unstable: bool, target_info: &LockedTargetInfo) -> Vec<Symbol> {
-    supported_target_features(sess)
+    sess
+        .target
+        .supported_target_features()
         .iter()
         .filter_map(
             |&(feature, gate)| {
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index 580ef9b06e7..7122c055e7e 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -9,7 +9,6 @@ test = false
 [dependencies]
 # tidy-alphabetical-start
 bitflags = "1.0"
-cstr = "0.2"
 itertools = "0.11"
 libc = "0.2"
 measureme = "10.0.0"
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index 798014d668e..58b3aa438c5 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -76,7 +76,7 @@ pub(crate) unsafe fn codegen(
     // __rust_alloc_error_handler_should_panic
     let name = OomStrategy::SYMBOL;
     let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
-    if tcx.sess.target.default_hidden_visibility {
+    if tcx.sess.default_hidden_visibility() {
         llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
     }
     let val = tcx.sess.opts.unstable_opts.oom.should_panic();
@@ -85,7 +85,7 @@ pub(crate) unsafe fn codegen(
 
     let name = NO_ALLOC_SHIM_IS_UNSTABLE;
     let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
-    if tcx.sess.target.default_hidden_visibility {
+    if tcx.sess.default_hidden_visibility() {
         llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
     }
     let llval = llvm::LLVMConstInt(i8, 0, False);
@@ -130,7 +130,7 @@ fn create_wrapper_function(
             None
         };
 
-        if tcx.sess.target.default_hidden_visibility {
+        if tcx.sess.default_hidden_visibility() {
             llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
         }
         if tcx.sess.must_emit_unwind_tables() {
@@ -146,7 +146,7 @@ fn create_wrapper_function(
         }
         llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
 
-        let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
+        let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr().cast());
 
         let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
         llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 97444f1a5bd..c9e109a5d23 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -631,7 +631,7 @@ pub(crate) fn run_pass_manager(
             llvm::LLVMRustAddModuleFlag(
                 module.module_llvm.llmod(),
                 llvm::LLVMModFlagBehavior::Error,
-                "LTOPostLink\0".as_ptr().cast(),
+                c"LTOPostLink".as_ptr().cast(),
                 1,
             );
         }
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index bdabb9129a7..048f66ad148 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -916,6 +916,7 @@ fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
     cgcx.opts.target_triple.triple().contains("-aix")
 }
 
+//FIXME use c string literals here too
 pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) -> &'static str {
     if target_is_apple(cgcx) {
         "__LLVM,__bitcode\0"
@@ -994,7 +995,7 @@ unsafe fn embed_bitcode(
         let llglobal = llvm::LLVMAddGlobal(
             llmod,
             common::val_ty(llconst),
-            "rustc.embedded.module\0".as_ptr().cast(),
+            c"rustc.embedded.module".as_ptr().cast(),
         );
         llvm::LLVMSetInitializer(llglobal, llconst);
 
@@ -1007,15 +1008,15 @@ unsafe fn embed_bitcode(
         let llglobal = llvm::LLVMAddGlobal(
             llmod,
             common::val_ty(llconst),
-            "rustc.embedded.cmdline\0".as_ptr().cast(),
+            c"rustc.embedded.cmdline".as_ptr().cast(),
         );
         llvm::LLVMSetInitializer(llglobal, llconst);
         let section = if is_apple {
-            "__LLVM,__cmdline\0"
+            c"__LLVM,__cmdline"
         } else if is_aix {
-            ".info\0"
+            c".info"
         } else {
-            ".llvmcmd\0"
+            c".llvmcmd"
         };
         llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
         llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index b659fd02eec..5dc271ccddb 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -19,8 +19,6 @@ use crate::context::CodegenCx;
 use crate::llvm;
 use crate::value::Value;
 
-use cstr::cstr;
-
 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
 use rustc_codegen_ssa::traits::*;
@@ -110,11 +108,11 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
 
             // Create the llvm.used and llvm.compiler.used variables.
             if !cx.used_statics.borrow().is_empty() {
-                cx.create_used_variable_impl(cstr!("llvm.used"), &*cx.used_statics.borrow());
+                cx.create_used_variable_impl(c"llvm.used", &*cx.used_statics.borrow());
             }
             if !cx.compiler_used_statics.borrow().is_empty() {
                 cx.create_used_variable_impl(
-                    cstr!("llvm.compiler.used"),
+                    c"llvm.compiler.used",
                     &*cx.compiler_used_statics.borrow(),
                 );
             }
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index acd85dd9a2d..8f60175a603 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -7,7 +7,6 @@ use crate::llvm_util;
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use cstr::cstr;
 use libc::{c_char, c_uint};
 use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind};
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
@@ -27,7 +26,6 @@ use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
 use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
 use smallvec::SmallVec;
 use std::borrow::Cow;
-use std::ffi::CStr;
 use std::iter;
 use std::ops::Deref;
 use std::ptr;
@@ -47,13 +45,10 @@ impl Drop for Builder<'_, '_, '_> {
     }
 }
 
-// FIXME(eddyb) use a checked constructor when they become `const fn`.
-const EMPTY_C_STR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"\0") };
-
 /// Empty string, to be used where LLVM expects an instruction name, indicating
 /// that the instruction is to be left unnamed (i.e. numbered, in textual IR).
 // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer.
-const UNNAMED: *const c_char = EMPTY_C_STR.as_ptr();
+const UNNAMED: *const c_char = c"".as_ptr();
 
 impl<'ll, 'tcx> BackendTypes for Builder<'_, 'll, 'tcx> {
     type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
@@ -358,7 +353,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         let new_kind = match ty.kind() {
             Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
             Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)),
-            t @ (Uint(_) | Int(_)) => t.clone(),
+            t @ (Uint(_) | Int(_)) => *t,
             _ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
         };
 
@@ -1012,14 +1007,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {
-        let name = cstr!("cleanuppad");
         let ret = unsafe {
             llvm::LLVMBuildCleanupPad(
                 self.llbuilder,
                 parent,
                 args.as_ptr(),
                 args.len() as c_uint,
-                name.as_ptr(),
+                c"cleanuppad".as_ptr(),
             )
         };
         Funclet::new(ret.expect("LLVM does not have support for cleanuppad"))
@@ -1033,14 +1027,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {
-        let name = cstr!("catchpad");
         let ret = unsafe {
             llvm::LLVMBuildCatchPad(
                 self.llbuilder,
                 parent,
                 args.as_ptr(),
                 args.len() as c_uint,
-                name.as_ptr(),
+                c"catchpad".as_ptr(),
             )
         };
         Funclet::new(ret.expect("LLVM does not have support for catchpad"))
@@ -1052,14 +1045,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         unwind: Option<&'ll BasicBlock>,
         handlers: &[&'ll BasicBlock],
     ) -> &'ll Value {
-        let name = cstr!("catchswitch");
         let ret = unsafe {
             llvm::LLVMBuildCatchSwitch(
                 self.llbuilder,
                 parent,
                 unwind,
                 handlers.len() as c_uint,
-                name.as_ptr(),
+                c"catchswitch".as_ptr(),
             )
         };
         let ret = ret.expect("LLVM does not have support for catchswitch");
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 21ff267ca67..77e893c815f 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -8,7 +8,6 @@ use crate::llvm::{self, True};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use cstr::cstr;
 use rustc_codegen_ssa::traits::*;
 use rustc_hir::def_id::DefId;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@@ -473,9 +472,9 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
                             .all(|&byte| byte == 0);
 
                     let sect_name = if all_bytes_are_zero {
-                        cstr!("__DATA,__thread_bss")
+                        c"__DATA,__thread_bss"
                     } else {
-                        cstr!("__DATA,__thread_data")
+                        c"__DATA,__thread_data"
                     };
                     llvm::LLVMSetSection(g, sect_name.as_ptr());
                 }
@@ -504,7 +503,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
                     let val = llvm::LLVMMetadataAsValue(self.llcx, meta);
                     llvm::LLVMAddNamedMetadataOperand(
                         self.llmod,
-                        "wasm.custom_sections\0".as_ptr().cast(),
+                        c"wasm.custom_sections".as_ptr().cast(),
                         val,
                     );
                 }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index ed0d5e68cbf..3053c4e0daa 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -8,7 +8,6 @@ use crate::llvm_util;
 use crate::type_::Type;
 use crate::value::Value;
 
-use cstr::cstr;
 use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
 use rustc_codegen_ssa::errors as ssa_errors;
 use rustc_codegen_ssa::traits::*;
@@ -215,13 +214,13 @@ pub unsafe fn create_module<'ll>(
     // If skipping the PLT is enabled, we need to add some module metadata
     // to ensure intrinsic calls don't use it.
     if !sess.needs_plt() {
-        let avoid_plt = "RtLibUseGOT\0".as_ptr().cast();
+        let avoid_plt = c"RtLibUseGOT".as_ptr().cast();
         llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
     }
 
     // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
     if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
-        let canonical_jump_tables = "CFI Canonical Jump Tables\0".as_ptr().cast();
+        let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast();
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
@@ -232,7 +231,7 @@ pub unsafe fn create_module<'ll>(
 
     // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
     if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
-        let enable_split_lto_unit = "EnableSplitLTOUnit\0".as_ptr().cast();
+        let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast();
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
@@ -243,7 +242,7 @@ pub unsafe fn create_module<'ll>(
 
     // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
     if sess.is_sanitizer_kcfi_enabled() {
-        let kcfi = "kcfi\0".as_ptr().cast();
+        let kcfi = c"kcfi".as_ptr().cast();
         llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
     }
 
@@ -256,7 +255,7 @@ pub unsafe fn create_module<'ll>(
                 llvm::LLVMRustAddModuleFlag(
                     llmod,
                     llvm::LLVMModFlagBehavior::Warning,
-                    "cfguard\0".as_ptr() as *const _,
+                    c"cfguard".as_ptr() as *const _,
                     1,
                 )
             }
@@ -265,7 +264,7 @@ pub unsafe fn create_module<'ll>(
                 llvm::LLVMRustAddModuleFlag(
                     llmod,
                     llvm::LLVMModFlagBehavior::Warning,
-                    "cfguard\0".as_ptr() as *const _,
+                    c"cfguard".as_ptr() as *const _,
                     2,
                 )
             }
@@ -283,26 +282,26 @@ pub unsafe fn create_module<'ll>(
             llvm::LLVMRustAddModuleFlag(
                 llmod,
                 behavior,
-                "branch-target-enforcement\0".as_ptr().cast(),
+                c"branch-target-enforcement".as_ptr().cast(),
                 bti.into(),
             );
             llvm::LLVMRustAddModuleFlag(
                 llmod,
                 behavior,
-                "sign-return-address\0".as_ptr().cast(),
+                c"sign-return-address".as_ptr().cast(),
                 pac_ret.is_some().into(),
             );
             let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
             llvm::LLVMRustAddModuleFlag(
                 llmod,
                 behavior,
-                "sign-return-address-all\0".as_ptr().cast(),
+                c"sign-return-address-all".as_ptr().cast(),
                 pac_opts.leaf.into(),
             );
             llvm::LLVMRustAddModuleFlag(
                 llmod,
                 behavior,
-                "sign-return-address-with-bkey\0".as_ptr().cast(),
+                c"sign-return-address-with-bkey".as_ptr().cast(),
                 u32::from(pac_opts.key == PAuthKey::B),
             );
         } else {
@@ -318,7 +317,7 @@ pub unsafe fn create_module<'ll>(
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
-            "cf-protection-branch\0".as_ptr().cast(),
+            c"cf-protection-branch".as_ptr().cast(),
             1,
         )
     }
@@ -326,7 +325,7 @@ pub unsafe fn create_module<'ll>(
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
-            "cf-protection-return\0".as_ptr().cast(),
+            c"cf-protection-return".as_ptr().cast(),
             1,
         )
     }
@@ -335,7 +334,7 @@ pub unsafe fn create_module<'ll>(
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Error,
-            "Virtual Function Elim\0".as_ptr().cast(),
+            c"Virtual Function Elim".as_ptr().cast(),
             1,
         );
     }
@@ -345,7 +344,7 @@ pub unsafe fn create_module<'ll>(
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Warning,
-            "ehcontguard\0".as_ptr() as *const _,
+            c"ehcontguard".as_ptr() as *const _,
             1,
         )
     }
@@ -363,7 +362,7 @@ pub unsafe fn create_module<'ll>(
     );
     llvm::LLVMAddNamedMetadataOperand(
         llmod,
-        cstr!("llvm.ident").as_ptr(),
+        c"llvm.ident".as_ptr(),
         llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
     );
 
@@ -511,14 +510,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     }
 
     pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
-        let section = cstr!("llvm.metadata");
         let array = self.const_array(self.type_ptr(), values);
 
         unsafe {
             let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr());
             llvm::LLVMSetInitializer(g, array);
             llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
-            llvm::LLVMSetSection(g, section.as_ptr());
+            llvm::LLVMSetSection(g, c"llvm.metadata".as_ptr());
         }
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
index 425e935bc9f..d82b1e1e721 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
@@ -30,14 +30,13 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_,
 /// Allocates the global variable responsible for the .debug_gdb_scripts binary
 /// section.
 pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Value {
-    let c_section_var_name = "__rustc_debug_gdb_scripts_section__\0";
-    let section_var_name = &c_section_var_name[..c_section_var_name.len() - 1];
+    let c_section_var_name = c"__rustc_debug_gdb_scripts_section__";
+    let section_var_name = c_section_var_name.to_str().unwrap();
 
     let section_var =
         unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr().cast()) };
 
     section_var.unwrap_or_else(|| {
-        let section_name = b".debug_gdb_scripts\0";
         let mut section_contents = Vec::new();
 
         // Add the pretty printers for the standard library first.
@@ -70,7 +69,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '
             let section_var = cx
                 .define_global(section_var_name, llvm_type)
                 .unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
-            llvm::LLVMSetSection(section_var, section_name.as_ptr().cast());
+            llvm::LLVMSetSection(section_var, c".debug_gdb_scripts".as_ptr().cast());
             llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents));
             llvm::LLVMSetGlobalConstant(section_var, llvm::True);
             llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index acd5a1ff5c6..883f82caa80 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -21,7 +21,6 @@ use crate::llvm::debuginfo::{
 };
 use crate::value::Value;
 
-use cstr::cstr;
 use rustc_codegen_ssa::debuginfo::type_names::cpp_like_debuginfo;
 use rustc_codegen_ssa::debuginfo::type_names::VTableNameKind;
 use rustc_codegen_ssa::traits::*;
@@ -608,7 +607,7 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) ->
 
                     if let Ok(rel_path) = abs_path.strip_prefix(working_directory) {
                         (
-                            working_directory.to_string_lossy().into(),
+                            working_directory.to_string_lossy(),
                             rel_path.to_string_lossy().into_owned(),
                         )
                     } else {
@@ -856,7 +855,6 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
     use rustc_session::RemapFileNameExt;
     let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
     let work_dir = tcx.sess.opts.working_dir.for_codegen(tcx.sess).to_string_lossy();
-    let flags = "\0";
     let output_filenames = tcx.output_filenames(());
     let split_name = if tcx.sess.target_can_use_split_dwarf() {
         output_filenames
@@ -910,7 +908,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
             producer.as_ptr().cast(),
             producer.len(),
             tcx.sess.opts.optimize != config::OptLevel::No,
-            flags.as_ptr().cast(),
+            c"".as_ptr().cast(),
             0,
             // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead
             // put the path supplied to `MCSplitDwarfFile` into the debug info of the final
@@ -940,8 +938,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
             );
             let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata);
 
-            let llvm_gcov_ident = cstr!("llvm.gcov");
-            llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, llvm_gcov_ident.as_ptr(), val);
+            llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, c"llvm.gcov".as_ptr(), val);
         }
 
         return unit_metadata;
@@ -980,6 +977,27 @@ fn build_field_di_node<'ll, 'tcx>(
     }
 }
 
+/// Returns the `DIFlags` corresponding to the visibility of the item identified by `did`.
+///
+/// `DIFlags::Flag{Public,Protected,Private}` correspond to `DW_AT_accessibility`
+/// (public/protected/private) aren't exactly right for Rust, but neither is `DW_AT_visibility`
+/// (local/exported/qualified), and there's no way to set `DW_AT_visibility` in LLVM's API.
+fn visibility_di_flags<'ll, 'tcx>(
+    cx: &CodegenCx<'ll, 'tcx>,
+    did: DefId,
+    type_did: DefId,
+) -> DIFlags {
+    let parent_did = cx.tcx.parent(type_did);
+    let visibility = cx.tcx.visibility(did);
+    match visibility {
+        Visibility::Public => DIFlags::FlagPublic,
+        // Private fields have a restricted visibility of the module containing the type.
+        Visibility::Restricted(did) if did == parent_did => DIFlags::FlagPrivate,
+        // `pub(crate)`/`pub(super)` visibilities are any other restricted visibility.
+        Visibility::Restricted(..) => DIFlags::FlagProtected,
+    }
+}
+
 /// Creates the debuginfo node for a Rust struct type. Maybe be a regular struct or a tuple-struct.
 fn build_struct_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
@@ -1003,7 +1021,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
             &compute_debuginfo_type_name(cx.tcx, struct_type, false),
             size_and_align_of(struct_type_and_layout),
             Some(containing_scope),
-            DIFlags::FlagZero,
+            visibility_di_flags(cx, adt_def.did(), adt_def.did()),
         ),
         // Fields:
         |cx, owner| {
@@ -1026,7 +1044,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
                         &field_name[..],
                         (field_layout.size, field_layout.align.abi),
                         struct_type_and_layout.fields.offset(i),
-                        DIFlags::FlagZero,
+                        visibility_di_flags(cx, f.did, adt_def.did()),
                         type_di_node(cx, field_layout.ty),
                     )
                 })
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index 7ef185250a3..4a2861af44c 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -26,8 +26,8 @@ use crate::{
             enums::{tag_base_type, DiscrResult},
             file_metadata, size_and_align_of, type_di_node,
             type_map::{self, Stub, UniqueTypeId},
-            unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA,
-            UNKNOWN_LINE_NUMBER,
+            unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec,
+            NO_GENERICS, NO_SCOPE_METADATA, UNKNOWN_LINE_NUMBER,
         },
         utils::DIB,
     },
@@ -215,7 +215,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
             &enum_type_name,
             cx.size_and_align_of(enum_type),
             NO_SCOPE_METADATA,
-            DIFlags::FlagZero,
+            visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()),
         ),
         |cx, enum_type_di_node| {
             match enum_type_and_layout.variants {
@@ -320,6 +320,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
     variant_index: VariantIdx,
 ) -> SmallVec<&'ll DIType> {
     let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
+    let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
     let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
         cx,
         enum_type_and_layout,
@@ -327,6 +328,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
         variant_index,
         enum_adt_def.variant(variant_index),
         variant_layout,
+        visibility_flags,
     );
 
     let tag_base_type = cx.tcx.types.u32;
@@ -364,7 +366,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
             //       since the later is sometimes smaller (if it has fewer fields).
             size_and_align_of(enum_type_and_layout),
             Size::ZERO,
-            DIFlags::FlagZero,
+            visibility_flags,
             variant_struct_type_wrapper_di_node,
         ),
         unsafe {
@@ -376,7 +378,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
                 unknown_file_metadata(cx),
                 UNKNOWN_LINE_NUMBER,
                 variant_names_type_di_node,
-                DIFlags::FlagZero,
+                visibility_flags,
                 Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)),
                 tag_base_type_align.bits() as u32,
             )
@@ -403,6 +405,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
             (variant_index, variant_name)
         }),
     );
+    let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
 
     let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices
         .map(|variant_index| {
@@ -417,6 +420,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
                 variant_index,
                 variant_def,
                 variant_layout,
+                visibility_flags,
             );
 
             VariantFieldInfo {
@@ -437,6 +441,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
         tag_base_type,
         tag_field,
         untagged_variant_index,
+        visibility_flags,
     )
 }
 
@@ -744,6 +749,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
         tag_base_type,
         tag_field,
         None,
+        DIFlags::FlagZero,
     )
 }
 
@@ -758,6 +764,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
     tag_base_type: Ty<'tcx>,
     tag_field: usize,
     untagged_variant_index: Option<VariantIdx>,
+    di_flags: DIFlags,
 ) -> SmallVec<&'ll DIType> {
     let tag_base_type_di_node = type_di_node(cx, tag_base_type);
     let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1);
@@ -801,7 +808,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
                 align.bits() as u32,
                 // Union fields are always at offset zero
                 Size::ZERO.bits(),
-                DIFlags::FlagZero,
+                di_flags,
                 variant_struct_type_wrapper,
             )
         }
@@ -835,7 +842,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
             TAG_FIELD_NAME_128_LO,
             size_and_align,
             lo_offset,
-            DIFlags::FlagZero,
+            di_flags,
             type_di_node,
         ));
 
@@ -855,7 +862,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
             TAG_FIELD_NAME,
             cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
             enum_type_and_layout.fields.offset(tag_field),
-            DIFlags::FlagZero,
+            di_flags,
             tag_base_type_di_node,
         ));
     }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index df1df6d197e..eef8dbb33b4 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -250,6 +250,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
     variant_index: VariantIdx,
     variant_def: &VariantDef,
     variant_layout: TyAndLayout<'tcx>,
+    di_flags: DIFlags,
 ) -> &'ll DIType {
     debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
 
@@ -267,7 +268,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
             // NOTE: We use size and align of enum_type, not from variant_layout:
             size_and_align_of(enum_type_and_layout),
             Some(enum_type_di_node),
-            DIFlags::FlagZero,
+            di_flags,
         ),
         |cx, struct_type_di_node| {
             (0..variant_layout.fields.count())
@@ -289,7 +290,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
                         &field_name,
                         (field_layout.size, field_layout.align.abi),
                         variant_layout.fields.offset(field_index),
-                        DIFlags::FlagZero,
+                        di_flags,
                         type_di_node(cx, field_layout.ty),
                     )
                 })
@@ -395,7 +396,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
                 })
                 .collect();
 
-            state_specific_fields.into_iter().chain(common_fields.into_iter()).collect()
+            state_specific_fields.into_iter().chain(common_fields).collect()
         },
         |cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty),
     )
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
index 130ca2727e4..cba4e3811d5 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
@@ -7,8 +7,8 @@ use crate::{
             enums::tag_base_type,
             file_metadata, size_and_align_of, type_di_node,
             type_map::{self, Stub, StubInfo, UniqueTypeId},
-            unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS,
-            UNKNOWN_LINE_NUMBER,
+            unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec,
+            NO_GENERICS, UNKNOWN_LINE_NUMBER,
         },
         utils::{create_DIArray, get_namespace_for_item, DIB},
     },
@@ -63,6 +63,8 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
     let enum_type_and_layout = cx.layout_of(enum_type);
     let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
 
+    let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
+
     debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
 
     type_map::build_type_with_children(
@@ -74,7 +76,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
             &enum_type_name,
             size_and_align_of(enum_type_and_layout),
             Some(containing_scope),
-            DIFlags::FlagZero,
+            visibility_flags,
         ),
         |cx, enum_type_di_node| {
             // Build the struct type for each variant. These will be referenced by the
@@ -92,6 +94,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
                         variant_index,
                         enum_adt_def.variant(variant_index),
                         enum_type_and_layout.for_variant(cx, variant_index),
+                        visibility_flags,
                     ),
                     source_info: None,
                 })
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index a0ae1e9bf5d..31631e8a864 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -112,7 +112,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
                 llvm::LLVMRustAddModuleFlag(
                     self.llmod,
                     llvm::LLVMModFlagBehavior::Warning,
-                    "Dwarf Version\0".as_ptr().cast(),
+                    c"Dwarf Version".as_ptr().cast(),
                     dwarf_version,
                 );
             } else {
@@ -120,17 +120,16 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
                 llvm::LLVMRustAddModuleFlag(
                     self.llmod,
                     llvm::LLVMModFlagBehavior::Warning,
-                    "CodeView\0".as_ptr().cast(),
+                    c"CodeView".as_ptr().cast(),
                     1,
                 )
             }
 
             // Prevent bitcode readers from deleting the debug info.
-            let ptr = "Debug Info Version\0".as_ptr();
             llvm::LLVMRustAddModuleFlag(
                 self.llmod,
                 llvm::LLVMModFlagBehavior::Warning,
-                ptr.cast(),
+                c"Debug Info Version".as_ptr().cast(),
                 llvm::LLVMRustDebugMetadataVersion(),
             );
         }
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 164b12cf8d4..78c0725a637 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -84,7 +84,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
         fn_type: &'ll Type,
     ) -> &'ll Value {
         // Declare C ABI functions with the visibility used by C by default.
-        let visibility = if self.tcx.sess.target.default_hidden_visibility {
+        let visibility = if self.tcx.sess.default_hidden_visibility() {
             llvm::Visibility::Hidden
         } else {
             llvm::Visibility::Default
@@ -107,7 +107,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
         unnamed: llvm::UnnamedAddr,
         fn_type: &'ll Type,
     ) -> &'ll Value {
-        let visibility = if self.tcx.sess.target.default_hidden_visibility {
+        let visibility = if self.tcx.sess.default_hidden_visibility() {
             llvm::Visibility::Hidden
         } else {
             llvm::Visibility::Default
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 57ea13ddcd6..e6e37a02335 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -107,7 +107,8 @@ impl IntoDiagnostic<'_, FatalError> for ParseTargetMachineConfig<'_> {
         let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message");
         let message = handler.eagerly_translate_to_string(message.clone(), diag.args());
 
-        let mut diag = handler.struct_diagnostic(fluent::codegen_llvm_parse_target_machine_config);
+        let mut diag =
+            handler.struct_almost_fatal(fluent::codegen_llvm_parse_target_machine_config);
         diag.set_arg("error", message);
         diag
     }
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 23b424f25ba..58e68a64907 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1568,7 +1568,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
         // Alignment of T, must be a constant integer value:
         let alignment_ty = bx.type_i32();
-        let alignment = bx.const_i32(bx.align_of(values_ty).bytes() as i32);
+        let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32);
 
         // Truncate the mask vector to a vector of i1s:
         let (mask, mask_ty) = {
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 116108ae5a9..dfef2fbab56 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![cfg_attr(bootstrap, feature(c_str_literals))]
 #![feature(exact_size_is_empty)]
 #![feature(extern_types)]
 #![feature(hash_raw_entry)]
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 93cb7327a01..08519723eba 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -5,9 +5,6 @@ use crate::errors::{
 };
 use crate::llvm;
 use libc::c_int;
-use rustc_codegen_ssa::target_features::{
-    supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES,
-};
 use rustc_codegen_ssa::traits::PrintBackendInfo;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::small_c_str::SmallCStr;
@@ -17,6 +14,7 @@ use rustc_session::config::{PrintKind, PrintRequest};
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::{MergeFunctions, PanicStrategy};
+use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
 
 use std::ffi::{c_char, c_void, CStr, CString};
 use std::path::Path;
@@ -278,7 +276,7 @@ pub fn check_tied_features(
     features: &FxHashMap<&str, bool>,
 ) -> Option<&'static [&'static str]> {
     if !features.is_empty() {
-        for tied in tied_target_features(sess) {
+        for tied in sess.target.tied_target_features() {
             // Tied features must be set to the same value, or not set at all
             let mut tied_iter = tied.iter();
             let enabled = features.get(tied_iter.next().unwrap());
@@ -294,7 +292,8 @@ pub fn check_tied_features(
 /// Must express features in the way Rust understands them
 pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
     let target_machine = create_informational_target_machine(sess);
-    supported_target_features(sess)
+    sess.target
+        .supported_target_features()
         .iter()
         .filter_map(|&(feature, gate)| {
             if sess.is_nightly_build() || allow_unstable || gate.is_stable() {
@@ -362,7 +361,9 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
 fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) {
     let mut llvm_target_features = llvm_target_features(tm);
     let mut known_llvm_target_features = FxHashSet::<&'static str>::default();
-    let mut rustc_target_features = supported_target_features(sess)
+    let mut rustc_target_features = sess
+        .target
+        .supported_target_features()
         .iter()
         .map(|(feature, _gate)| {
             // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
@@ -515,7 +516,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
     );
 
     // -Ctarget-features
-    let supported_features = supported_target_features(sess);
+    let supported_features = sess.target.supported_target_features();
     let mut featsmap = FxHashMap::default();
     let feats = sess
         .opts
diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
index 3d479c5c22d..01d1b1059b9 100644
--- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
+++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
@@ -199,8 +199,8 @@ impl fmt::Display for CguReuse {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             CguReuse::No => write!(f, "No"),
-            CguReuse::PreLto => write!(f, "PreLto "),
-            CguReuse::PostLto => write!(f, "PostLto "),
+            CguReuse::PreLto => write!(f, "PreLto"),
+            CguReuse::PostLto => write!(f, "PostLto"),
         }
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 618a72272e5..40fd8c5c1d6 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1848,7 +1848,7 @@ impl SharedEmitterMain {
                         d.code(code);
                     }
                     d.replace_args(diag.args);
-                    handler.emit_diagnostic(&mut d);
+                    handler.emit_diagnostic(d);
                 }
                 Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
                     let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 40a985cf255..015ea10d721 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -578,7 +578,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     hir_id,
                     no_sanitize_span,
                     "`no_sanitize` will have no effect after inlining",
-                    |lint| lint.span_note(inline_span, "inlining requested here"),
+                    |lint| {
+                        lint.span_note(inline_span, "inlining requested here");
+                    },
                 )
             }
         }
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index cd5eb77e06e..9b60f0844a0 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -51,10 +51,10 @@ pub mod codegen_attrs;
 pub mod common;
 pub mod debuginfo;
 pub mod errors;
-pub mod glue;
 pub mod meth;
 pub mod mir;
 pub mod mono_item;
+pub mod size_of_val;
 pub mod target_features;
 pub mod traits;
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 136d06d561a..a5bffc33d39 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -4,8 +4,8 @@ use super::FunctionCx;
 use crate::common::IntPredicate;
 use crate::errors;
 use crate::errors::InvalidMonomorphization;
-use crate::glue;
 use crate::meth;
+use crate::size_of_val;
 use crate::traits::*;
 use crate::MemFlags;
 
@@ -88,21 +88,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             sym::va_end => bx.va_end(args[0].immediate()),
             sym::size_of_val => {
                 let tp_ty = fn_args.type_at(0);
-                if let OperandValue::Pair(_, meta) = args[0].val {
-                    let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
-                    llsize
-                } else {
-                    bx.const_usize(bx.layout_of(tp_ty).size.bytes())
-                }
+                let meta =
+                    if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
+                let (llsize, _) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
+                llsize
             }
             sym::min_align_of_val => {
                 let tp_ty = fn_args.type_at(0);
-                if let OperandValue::Pair(_, meta) = args[0].val {
-                    let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
-                    llalign
-                } else {
-                    bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes())
-                }
+                let meta =
+                    if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
+                let (_, llalign) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
+                llalign
             }
             sym::vtable_size | sym::vtable_align => {
                 let vtable = args[0].immediate();
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index feee3ac03d0..e8c58f6b6f8 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -2,7 +2,7 @@ use super::place::PlaceRef;
 use super::{FunctionCx, LocalRef};
 
 use crate::base;
-use crate::glue;
+use crate::size_of_val;
 use crate::traits::*;
 use crate::MemFlags;
 
@@ -466,13 +466,13 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
             .ty;
 
         let OperandValue::Ref(llptr, Some(llextra), _) = self else {
-            bug!("store_unsized called with a sized value")
+            bug!("store_unsized called with a sized value (or with an extern type)")
         };
 
         // Allocate an appropriate region on the stack, and copy the value into it. Since alloca
         // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
         // pointer manually.
-        let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
+        let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
         let one = bx.const_usize(1);
         let align_minus_1 = bx.sub(align, one);
         let size_extra = bx.add(size, align_minus_1);
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 83425dee1a8..c0bb3ac5661 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -2,7 +2,7 @@ use super::operand::OperandValue;
 use super::{FunctionCx, LocalRef};
 
 use crate::common::IntPredicate;
-use crate::glue;
+use crate::size_of_val;
 use crate::traits::*;
 
 use rustc_middle::mir;
@@ -99,6 +99,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         let offset = self.layout.fields.offset(ix);
         let effective_field_align = self.align.restrict_for_offset(offset);
 
+        // `simple` is called when we don't need to adjust the offset to
+        // the dynamic alignment of the field.
         let mut simple = || {
             let llval = match self.layout.abi {
                 _ if offset.bytes() == 0 => {
@@ -141,28 +143,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         };
 
         // Simple cases, which don't need DST adjustment:
-        //   * no metadata available - just log the case
-        //   * known alignment - sized types, `[T]`, `str` or a foreign type
+        //   * known alignment - sized types, `[T]`, `str`
+        //   * offset 0 -- rounding up to alignment cannot change the offset
         // Note that looking at `field.align` is incorrect since that is not necessarily equal
         // to the dynamic alignment of the type.
         match field.ty.kind() {
-            _ if self.llextra.is_none() => {
-                debug!(
-                    "unsized field `{}`, of `{:?}` has no metadata for adjustment",
-                    ix, self.llval
-                );
-                return simple();
-            }
             _ if field.is_sized() => return simple(),
-            ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
+            ty::Slice(..) | ty::Str => return simple(),
+            _ if offset.bytes() == 0 => return simple(),
             _ => {}
         }
 
         // We need to get the pointer manually now.
         // We do this by casting to a `*i8`, then offsetting it by the appropriate amount.
         // We do this instead of, say, simply adjusting the pointer from the result of a GEP
-        // because the field may have an arbitrary alignment in the LLVM representation
-        // anyway.
+        // because the field may have an arbitrary alignment in the LLVM representation.
         //
         // To demonstrate:
         //
@@ -179,7 +174,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         let unaligned_offset = bx.cx().const_usize(offset.bytes());
 
         // Get the alignment of the field
-        let (_, mut unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta);
+        let (_, mut unsized_align) = size_of_val::size_and_align_of_dst(bx, field.ty, meta);
 
         // For packed types, we need to cap alignment.
         if let ty::Adt(def, _) = self.layout.ty.kind()
diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index c34f1dbf856..087836ca37d 100644
--- a/compiler/rustc_codegen_ssa/src/glue.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -1,10 +1,11 @@
-//!
-//
-// Code relating to drop glue.
+//! Computing the size and alignment of a value.
 
+use crate::common;
 use crate::common::IntPredicate;
 use crate::meth;
 use crate::traits::*;
+use rustc_hir::LangItem;
+use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Ty};
 use rustc_target::abi::WrappingRange;
 
@@ -14,7 +15,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     info: Option<Bx::Value>,
 ) -> (Bx::Value, Bx::Value) {
     let layout = bx.layout_of(t);
-    debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout);
+    trace!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout);
     if layout.is_sized() {
         let size = bx.const_usize(layout.size.bytes());
         let align = bx.const_usize(layout.align.abi.bytes());
@@ -51,7 +52,31 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 bx.const_usize(unit.align.abi.bytes()),
             )
         }
-        _ => {
+        ty::Foreign(_) => {
+            // `extern` type. We cannot compute the size, so panic.
+            let msg_str = with_no_visible_paths!({
+                with_no_trimmed_paths!({
+                    format!("attempted to compute the size or alignment of extern type `{t}`")
+                })
+            });
+            let msg = bx.const_str(&msg_str);
+
+            // Obtain the panic entry point.
+            let (fn_abi, llfn) = common::build_langcall(bx, None, LangItem::PanicNounwind);
+
+            // Generate the call.
+            // Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`.
+            // (But we are in good company, this code is duplicated plenty of times.)
+            let fn_ty = bx.fn_decl_backend_type(fn_abi);
+
+            bx.call(fn_ty, /* fn_attrs */ None, Some(fn_abi), llfn, &[msg.0, msg.1], None);
+
+            // This function does not return so we can now return whatever we want.
+            let size = bx.const_usize(layout.size.bytes());
+            let align = bx.const_usize(layout.align.abi.bytes());
+            (size, align)
+        }
+        ty::Adt(..) | ty::Tuple(..) => {
             // First get the size of all statically known fields.
             // Don't use size_of because it also rounds up to alignment, which we
             // want to avoid, as the unsized field's alignment could be smaller.
@@ -59,10 +84,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             debug!("DST {} layout: {:?}", t, layout);
 
             let i = layout.fields.count() - 1;
-            let sized_size = layout.fields.offset(i).bytes();
+            let unsized_offset_unadjusted = layout.fields.offset(i).bytes();
             let sized_align = layout.align.abi.bytes();
-            debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align);
-            let sized_size = bx.const_usize(sized_size);
+            debug!(
+                "DST {} offset of dyn field: {}, statically sized align: {}",
+                t, unsized_offset_unadjusted, sized_align
+            );
+            let unsized_offset_unadjusted = bx.const_usize(unsized_offset_unadjusted);
             let sized_align = bx.const_usize(sized_align);
 
             // Recurse to get the size of the dynamically sized field (must be
@@ -70,26 +98,26 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let field_ty = layout.field(bx, i).ty;
             let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info);
 
-            // FIXME (#26403, #27023): We should be adding padding
-            // to `sized_size` (to accommodate the `unsized_align`
-            // required of the unsized field that follows) before
-            // summing it with `sized_size`. (Note that since #26403
-            // is unfixed, we do not yet add the necessary padding
-            // here. But this is where the add would go.)
+            // # First compute the dynamic alignment
 
-            // Return the sum of sizes and max of aligns.
-            let size = bx.add(sized_size, unsized_size);
-
-            // Packed types ignore the alignment of their fields.
-            if let ty::Adt(def, _) = t.kind() {
-                if def.repr().packed() {
-                    unsized_align = sized_align;
+            // For packed types, we need to cap the alignment.
+            if let ty::Adt(def, _) = t.kind()
+                && let Some(packed) = def.repr().pack
+            {
+                if packed.bytes() == 1 {
+                    // We know this will be capped to 1.
+                    unsized_align = bx.const_usize(1);
+                } else {
+                    // We have to dynamically compute `min(unsized_align, packed)`.
+                    let packed = bx.const_usize(packed.bytes());
+                    let cmp = bx.icmp(IntPredicate::IntULT, unsized_align, packed);
+                    unsized_align = bx.select(cmp, unsized_align, packed);
                 }
             }
 
             // Choose max of two known alignments (combined value must
             // be aligned according to more restrictive of the two).
-            let align = match (
+            let full_align = match (
                 bx.const_to_opt_u128(sized_align, false),
                 bx.const_to_opt_u128(unsized_align, false),
             ) {
@@ -104,6 +132,19 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 }
             };
 
+            // # Then compute the dynamic size
+
+            // The full formula for the size would be:
+            // let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align);
+            // let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align);
+            // However, `unsized_size` is a multiple of `unsized_align`.
+            // Therefore, we can equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`:
+            // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(unsized_align).align_to(full_align);
+            // Furthermore, `align >= unsized_align`, and therefore we only need to do:
+            // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(full_align);
+
+            let full_size = bx.add(unsized_offset_unadjusted, unsized_size);
+
             // Issue #27023: must add any necessary padding to `size`
             // (to make it a multiple of `align`) before returning it.
             //
@@ -115,12 +156,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             //
             //   `(size + (align-1)) & -align`
             let one = bx.const_usize(1);
-            let addend = bx.sub(align, one);
-            let add = bx.add(size, addend);
-            let neg = bx.neg(align);
-            let size = bx.and(add, neg);
+            let addend = bx.sub(full_align, one);
+            let add = bx.add(full_size, addend);
+            let neg = bx.neg(full_align);
+            let full_size = bx.and(add, neg);
 
-            (size, align)
+            (full_size, full_align)
         }
+        _ => bug!("size_and_align_of_dst: {t} not supported"),
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index c3b8859c779..0b9b08c6a24 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -11,436 +11,10 @@ use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
-use rustc_session::Session;
 use rustc_span::symbol::sym;
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 
-/// Features that control behaviour of rustc, rather than the codegen.
-pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
-
-/// Stability information for target features.
-#[derive(Debug, Clone, Copy)]
-pub enum Stability {
-    /// 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),
-}
-use Stability::*;
-
-impl Stability {
-    fn as_feature_name(self) -> Option<Symbol> {
-        match self {
-            Stable => None,
-            Unstable(s) => Some(s),
-        }
-    }
-
-    pub fn is_stable(self) -> bool {
-        matches!(self, Stable)
-    }
-}
-
-// 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`.
-//
-// When adding features to the below lists
-// check whether they're named already elsewhere in rust
-// e.g. in stdarch and whether the given name matches LLVM's
-// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted.
-//
-// Also note that all target features listed here must be purely additive: for target_feature 1.1 to
-// be sound, we can never allow features like `+soft-float` (on x86) to be controlled on a
-// per-function level, since we would then allow safe calls from functions with `+soft-float` to
-// functions without that feature!
-//
-// When adding a new feature, be particularly mindful of features that affect function ABIs. Those
-// need to be treated very carefully to avoid introducing unsoundness! This often affects features
-// that enable/disable hardfloat support (see https://github.com/rust-lang/rust/issues/116344 for an
-// example of this going wrong), but features enabling new SIMD registers are also a concern (see
-// https://github.com/rust-lang/rust/issues/116558 for an example of this going wrong).
-//
-// Stabilizing a target feature requires t-lang approval.
-
-const ARM_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("aclass", Unstable(sym::arm_target_feature)),
-    ("aes", Unstable(sym::arm_target_feature)),
-    ("crc", Unstable(sym::arm_target_feature)),
-    ("d32", Unstable(sym::arm_target_feature)),
-    ("dotprod", Unstable(sym::arm_target_feature)),
-    ("dsp", Unstable(sym::arm_target_feature)),
-    ("fp-armv8", Unstable(sym::arm_target_feature)),
-    ("i8mm", Unstable(sym::arm_target_feature)),
-    ("mclass", Unstable(sym::arm_target_feature)),
-    ("neon", Unstable(sym::arm_target_feature)),
-    ("rclass", Unstable(sym::arm_target_feature)),
-    ("sha2", Unstable(sym::arm_target_feature)),
-    // 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)),
-    ("v6k", Unstable(sym::arm_target_feature)),
-    ("v6t2", Unstable(sym::arm_target_feature)),
-    ("v7", Unstable(sym::arm_target_feature)),
-    ("v8", Unstable(sym::arm_target_feature)),
-    ("vfp2", Unstable(sym::arm_target_feature)),
-    ("vfp3", Unstable(sym::arm_target_feature)),
-    ("vfp4", Unstable(sym::arm_target_feature)),
-    ("virtualization", Unstable(sym::arm_target_feature)),
-    // tidy-alphabetical-end
-];
-
-const AARCH64_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    // FEAT_AES
-    ("aes", Stable),
-    // FEAT_BF16
-    ("bf16", Stable),
-    // FEAT_BTI
-    ("bti", Stable),
-    // FEAT_CRC
-    ("crc", Stable),
-    // FEAT_DIT
-    ("dit", Stable),
-    // FEAT_DotProd
-    ("dotprod", Stable),
-    // FEAT_DPB
-    ("dpb", Stable),
-    // FEAT_DPB2
-    ("dpb2", Stable),
-    // FEAT_F32MM
-    ("f32mm", Stable),
-    // FEAT_F64MM
-    ("f64mm", Stable),
-    // FEAT_FCMA
-    ("fcma", Stable),
-    // FEAT_FHM
-    ("fhm", Stable),
-    // FEAT_FLAGM
-    ("flagm", Stable),
-    // FEAT_FP16
-    ("fp16", Stable),
-    // FEAT_FRINTTS
-    ("frintts", Stable),
-    // FEAT_I8MM
-    ("i8mm", Stable),
-    // FEAT_JSCVT
-    ("jsconv", Stable),
-    // FEAT_LOR
-    ("lor", Stable),
-    // FEAT_LSE
-    ("lse", Stable),
-    // FEAT_MTE
-    ("mte", Stable),
-    // FEAT_AdvSimd & FEAT_FP
-    ("neon", Stable),
-    // FEAT_PAUTH (address authentication)
-    ("paca", Stable),
-    // FEAT_PAUTH (generic authentication)
-    ("pacg", Stable),
-    // FEAT_PAN
-    ("pan", Stable),
-    // FEAT_PMUv3
-    ("pmuv3", Stable),
-    // FEAT_RAND
-    ("rand", Stable),
-    // FEAT_RAS
-    ("ras", Stable),
-    // FEAT_RCPC
-    ("rcpc", Stable),
-    // FEAT_RCPC2
-    ("rcpc2", Stable),
-    // FEAT_RDM
-    ("rdm", Stable),
-    // FEAT_SB
-    ("sb", Stable),
-    // FEAT_SHA1 & FEAT_SHA256
-    ("sha2", Stable),
-    // FEAT_SHA512 & FEAT_SHA3
-    ("sha3", Stable),
-    // FEAT_SM3 & FEAT_SM4
-    ("sm4", Stable),
-    // FEAT_SPE
-    ("spe", Stable),
-    // FEAT_SSBS
-    ("ssbs", Stable),
-    // FEAT_SVE
-    ("sve", Stable),
-    // FEAT_SVE2
-    ("sve2", Stable),
-    // FEAT_SVE2_AES
-    ("sve2-aes", Stable),
-    // FEAT_SVE2_BitPerm
-    ("sve2-bitperm", Stable),
-    // FEAT_SVE2_SHA3
-    ("sve2-sha3", Stable),
-    // FEAT_SVE2_SM4
-    ("sve2-sm4", Stable),
-    // FEAT_TME
-    ("tme", Stable),
-    ("v8.1a", Unstable(sym::aarch64_ver_target_feature)),
-    ("v8.2a", Unstable(sym::aarch64_ver_target_feature)),
-    ("v8.3a", Unstable(sym::aarch64_ver_target_feature)),
-    ("v8.4a", Unstable(sym::aarch64_ver_target_feature)),
-    ("v8.5a", Unstable(sym::aarch64_ver_target_feature)),
-    ("v8.6a", Unstable(sym::aarch64_ver_target_feature)),
-    ("v8.7a", Unstable(sym::aarch64_ver_target_feature)),
-    // FEAT_VHE
-    ("vh", Stable),
-    // tidy-alphabetical-end
-];
-
-const AARCH64_TIED_FEATURES: &[&[&str]] = &[
-    &["paca", "pacg"], // Together these represent `pauth` in LLVM
-];
-
-const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("adx", Stable),
-    ("aes", Stable),
-    ("avx", Stable),
-    ("avx2", Stable),
-    ("avx512bf16", Unstable(sym::avx512_target_feature)),
-    ("avx512bitalg", Unstable(sym::avx512_target_feature)),
-    ("avx512bw", Unstable(sym::avx512_target_feature)),
-    ("avx512cd", Unstable(sym::avx512_target_feature)),
-    ("avx512dq", Unstable(sym::avx512_target_feature)),
-    ("avx512er", Unstable(sym::avx512_target_feature)),
-    ("avx512f", Unstable(sym::avx512_target_feature)),
-    ("avx512ifma", Unstable(sym::avx512_target_feature)),
-    ("avx512pf", Unstable(sym::avx512_target_feature)),
-    ("avx512vbmi", Unstable(sym::avx512_target_feature)),
-    ("avx512vbmi2", Unstable(sym::avx512_target_feature)),
-    ("avx512vl", Unstable(sym::avx512_target_feature)),
-    ("avx512vnni", Unstable(sym::avx512_target_feature)),
-    ("avx512vp2intersect", Unstable(sym::avx512_target_feature)),
-    ("avx512vpopcntdq", Unstable(sym::avx512_target_feature)),
-    ("bmi1", Stable),
-    ("bmi2", Stable),
-    ("cmpxchg16b", Stable),
-    ("ermsb", Unstable(sym::ermsb_target_feature)),
-    ("f16c", Stable),
-    ("fma", Stable),
-    ("fxsr", Stable),
-    ("gfni", Unstable(sym::avx512_target_feature)),
-    ("lzcnt", Stable),
-    ("movbe", Stable),
-    ("pclmulqdq", Stable),
-    ("popcnt", Stable),
-    ("rdrand", Stable),
-    ("rdseed", Stable),
-    ("rtm", Unstable(sym::rtm_target_feature)),
-    ("sha", Stable),
-    ("sse", Stable),
-    ("sse2", Stable),
-    ("sse3", Stable),
-    ("sse4.1", Stable),
-    ("sse4.2", Stable),
-    ("sse4a", Unstable(sym::sse4a_target_feature)),
-    ("ssse3", Stable),
-    ("tbm", Unstable(sym::tbm_target_feature)),
-    ("vaes", Unstable(sym::avx512_target_feature)),
-    ("vpclmulqdq", Unstable(sym::avx512_target_feature)),
-    ("xsave", Stable),
-    ("xsavec", Stable),
-    ("xsaveopt", Stable),
-    ("xsaves", Stable),
-    // tidy-alphabetical-end
-];
-
-const HEXAGON_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("hvx", Unstable(sym::hexagon_target_feature)),
-    ("hvx-length128b", Unstable(sym::hexagon_target_feature)),
-    // tidy-alphabetical-end
-];
-
-const POWERPC_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("altivec", Unstable(sym::powerpc_target_feature)),
-    ("power10-vector", Unstable(sym::powerpc_target_feature)),
-    ("power8-altivec", Unstable(sym::powerpc_target_feature)),
-    ("power8-vector", Unstable(sym::powerpc_target_feature)),
-    ("power9-altivec", Unstable(sym::powerpc_target_feature)),
-    ("power9-vector", Unstable(sym::powerpc_target_feature)),
-    ("vsx", Unstable(sym::powerpc_target_feature)),
-    // tidy-alphabetical-end
-];
-
-const MIPS_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("fp64", Unstable(sym::mips_target_feature)),
-    ("msa", Unstable(sym::mips_target_feature)),
-    ("virt", Unstable(sym::mips_target_feature)),
-    // tidy-alphabetical-end
-];
-
-const RISCV_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("a", Stable),
-    ("c", Stable),
-    ("d", Unstable(sym::riscv_target_feature)),
-    ("e", Unstable(sym::riscv_target_feature)),
-    ("f", Unstable(sym::riscv_target_feature)),
-    ("fast-unaligned-access", Unstable(sym::riscv_target_feature)),
-    ("m", Stable),
-    ("relax", Unstable(sym::riscv_target_feature)),
-    ("v", 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)),
-    ("zfh", Unstable(sym::riscv_target_feature)),
-    ("zfhmin", Unstable(sym::riscv_target_feature)),
-    ("zfinx", Unstable(sym::riscv_target_feature)),
-    ("zhinx", Unstable(sym::riscv_target_feature)),
-    ("zhinxmin", Unstable(sym::riscv_target_feature)),
-    ("zk", Stable),
-    ("zkn", Stable),
-    ("zknd", Stable),
-    ("zkne", Stable),
-    ("zknh", Stable),
-    ("zkr", Stable),
-    ("zks", Stable),
-    ("zksed", Stable),
-    ("zksh", Stable),
-    ("zkt", Stable),
-    // tidy-alphabetical-end
-];
-
-const WASM_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("atomics", Unstable(sym::wasm_target_feature)),
-    ("bulk-memory", Unstable(sym::wasm_target_feature)),
-    ("exception-handling", Unstable(sym::wasm_target_feature)),
-    ("multivalue", Unstable(sym::wasm_target_feature)),
-    ("mutable-globals", Unstable(sym::wasm_target_feature)),
-    ("nontrapping-fptoint", Unstable(sym::wasm_target_feature)),
-    ("reference-types", Unstable(sym::wasm_target_feature)),
-    ("relaxed-simd", Unstable(sym::wasm_target_feature)),
-    ("sign-ext", Unstable(sym::wasm_target_feature)),
-    ("simd128", Stable),
-    // tidy-alphabetical-end
-];
-
-const BPF_ALLOWED_FEATURES: &[(&str, Stability)] = &[("alu32", Unstable(sym::bpf_target_feature))];
-
-const CSKY_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("10e60", Unstable(sym::csky_target_feature)),
-    ("2e3", Unstable(sym::csky_target_feature)),
-    ("3e3r1", Unstable(sym::csky_target_feature)),
-    ("3e3r2", Unstable(sym::csky_target_feature)),
-    ("3e3r3", Unstable(sym::csky_target_feature)),
-    ("3e7", Unstable(sym::csky_target_feature)),
-    ("7e10", Unstable(sym::csky_target_feature)),
-    ("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)),
-    ("e2", Unstable(sym::csky_target_feature)),
-    ("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)),
-    ("mp1e2", Unstable(sym::csky_target_feature)),
-    ("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)),
-    // tidy-alphabetical-end
-];
-
-const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[
-    // tidy-alphabetical-start
-    ("d", Unstable(sym::loongarch_target_feature)),
-    ("f", Unstable(sym::loongarch_target_feature)),
-    ("lasx", Unstable(sym::loongarch_target_feature)),
-    ("lbt", Unstable(sym::loongarch_target_feature)),
-    ("lsx", Unstable(sym::loongarch_target_feature)),
-    ("lvz", Unstable(sym::loongarch_target_feature)),
-    ("ual", Unstable(sym::loongarch_target_feature)),
-    // tidy-alphabetical-end
-];
-
-/// When rustdoc is running, provide a list of all known features so that all their respective
-/// primitives may be documented.
-///
-/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
-pub fn all_known_features() -> impl Iterator<Item = (&'static str, Stability)> {
-    std::iter::empty()
-        .chain(ARM_ALLOWED_FEATURES.iter())
-        .chain(AARCH64_ALLOWED_FEATURES.iter())
-        .chain(X86_ALLOWED_FEATURES.iter())
-        .chain(HEXAGON_ALLOWED_FEATURES.iter())
-        .chain(POWERPC_ALLOWED_FEATURES.iter())
-        .chain(MIPS_ALLOWED_FEATURES.iter())
-        .chain(RISCV_ALLOWED_FEATURES.iter())
-        .chain(WASM_ALLOWED_FEATURES.iter())
-        .chain(BPF_ALLOWED_FEATURES.iter())
-        .chain(CSKY_ALLOWED_FEATURES)
-        .chain(LOONGARCH_ALLOWED_FEATURES)
-        .cloned()
-}
-
-pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Stability)] {
-    match &*sess.target.arch {
-        "arm" => ARM_ALLOWED_FEATURES,
-        "aarch64" => AARCH64_ALLOWED_FEATURES,
-        "x86" | "x86_64" => X86_ALLOWED_FEATURES,
-        "hexagon" => HEXAGON_ALLOWED_FEATURES,
-        "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES,
-        "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
-        "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
-        "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
-        "bpf" => BPF_ALLOWED_FEATURES,
-        "csky" => CSKY_ALLOWED_FEATURES,
-        "loongarch64" => LOONGARCH_ALLOWED_FEATURES,
-        _ => &[],
-    }
-}
-
-pub fn tied_target_features(sess: &Session) -> &'static [&'static [&'static str]] {
-    match &*sess.target.arch {
-        "aarch64" => AARCH64_TIED_FEATURES,
-        _ => &[],
-    }
-}
-
 pub fn from_target_feature(
     tcx: TyCtxt<'_>,
     attr: &ast::Attribute,
@@ -562,9 +136,13 @@ pub(crate) fn provide(providers: &mut Providers) {
             if tcx.sess.opts.actually_rustdoc {
                 // rustdoc needs to be able to document functions that use all the features, so
                 // whitelist them all
-                all_known_features().map(|(a, b)| (a.to_string(), b.as_feature_name())).collect()
+                rustc_target::target_features::all_known_features()
+                    .map(|(a, b)| (a.to_string(), b.as_feature_name()))
+                    .collect()
             } else {
-                supported_target_features(tcx.sess)
+                tcx.sess
+                    .target
+                    .supported_target_features()
                     .iter()
                     .map(|&(a, b)| (a.to_string(), b.as_feature_name()))
                     .collect()
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 9e992637f46..dbc29e607ef 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -33,7 +33,7 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 /// 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`.
 fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
-    let node = tcx.hir().get_by_def_id(def_id);
+    let node = tcx.hir_node_by_def_id(def_id);
 
     match node {
         hir::Node::Ctor(_)
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index bbebf329d26..847d6503f20 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -686,14 +686,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 assert!(layout.fields.count() > 0);
                 trace!("DST layout: {:?}", layout);
 
-                let sized_size = layout.fields.offset(layout.fields.count() - 1);
+                let unsized_offset_unadjusted = layout.fields.offset(layout.fields.count() - 1);
                 let sized_align = layout.align.abi;
-                trace!(
-                    "DST {} statically sized prefix size: {:?} align: {:?}",
-                    layout.ty,
-                    sized_size,
-                    sized_align
-                );
 
                 // Recurse to get the size of the dynamically sized field (must be
                 // the last field). Can't have foreign types here, how would we
@@ -707,36 +701,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     return Ok(None);
                 };
 
-                // FIXME (#26403, #27023): We should be adding padding
-                // to `sized_size` (to accommodate the `unsized_align`
-                // required of the unsized field that follows) before
-                // summing it with `sized_size`. (Note that since #26403
-                // is unfixed, we do not yet add the necessary padding
-                // here. But this is where the add would go.)
-
-                // Return the sum of sizes and max of aligns.
-                let size = sized_size + unsized_size; // `Size` addition
+                // # First compute the dynamic alignment
 
-                // Packed types ignore the alignment of their fields.
+                // Packed type alignment needs to be capped.
                 if let ty::Adt(def, _) = layout.ty.kind() {
-                    if def.repr().packed() {
-                        unsized_align = sized_align;
+                    if let Some(packed) = def.repr().pack {
+                        unsized_align = unsized_align.min(packed);
                     }
                 }
 
                 // Choose max of two known alignments (combined value must
                 // be aligned according to more restrictive of the two).
-                let align = sized_align.max(unsized_align);
+                let full_align = sized_align.max(unsized_align);
+
+                // # Then compute the dynamic size
 
-                // Issue #27023: must add any necessary padding to `size`
-                // (to make it a multiple of `align`) before returning it.
-                let size = size.align_to(align);
+                let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align);
+                let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align);
+
+                // Just for our sanitiy's sake, assert that this is equal to what codegen would compute.
+                assert_eq!(
+                    full_size,
+                    (unsized_offset_unadjusted + unsized_size).align_to(full_align)
+                );
 
                 // Check if this brought us over the size limit.
-                if size > self.max_size_of_val() {
+                if full_size > self.max_size_of_val() {
                     throw_ub!(InvalidMeta(InvalidMetaKind::TooBig));
                 }
-                Ok(Some((size, align)))
+                Ok(Some((full_size, full_align)))
             }
             ty::Dynamic(_, _, ty::Dyn) => {
                 let vtable = metadata.unwrap_meta().to_pointer(self)?;
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 4d9e296d544..9a034ba22b9 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -174,12 +174,15 @@ where
                     };
                     (base_meta, offset.align_to(align))
                 }
-                None => {
-                    // For unsized types with an extern type tail we perform no adjustments.
-                    // NOTE: keep this in sync with `PlaceRef::project_field` in the codegen backend.
-                    assert!(matches!(base_meta, MemPlaceMeta::None));
+                None if offset == Size::ZERO => {
+                    // If the offset is 0, then rounding it up to alignment wouldn't change anything,
+                    // so we can do this even for types where we cannot determine the alignment.
                     (base_meta, offset)
                 }
+                None => {
+                    // We don't know the alignment of this field, so we cannot adjust.
+                    throw_unsup_format!("`extern type` does not have a known offset")
+                }
             }
         } else {
             // base_meta could be present; we might be accessing a sized field of an unsized
@@ -205,6 +208,24 @@ where
         if layout.abi.is_uninhabited() {
             // `read_discriminant` should have excluded uninhabited variants... but ConstProp calls
             // us on dead code.
+            // In the future we might want to allow this to permit code like this:
+            // (this is a Rust/MIR pseudocode mix)
+            // ```
+            // enum Option2 {
+            //   Some(i32, !),
+            //   None,
+            // }
+            //
+            // fn panic() -> ! { panic!() }
+            //
+            // let x: Option2;
+            // x.Some.0 = 42;
+            // x.Some.1 = panic();
+            // SetDiscriminant(x, Some);
+            // ```
+            // However, for now we don't generate such MIR, and this check here *has* found real
+            // bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting
+            // it.
             throw_inval!(ConstPropNonsense)
         }
         // This cannot be `transmute` as variants *can* have a smaller size than the entire enum.
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 20f251d5c91..07500f74477 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -227,7 +227,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                         // Sometimes the index is beyond the number of upvars (seen
                         // for a coroutine).
                         let var_hir_id = captured_place.get_root_variable();
-                        let node = self.ecx.tcx.hir().get(var_hir_id);
+                        let node = self.ecx.tcx.hir_node(var_hir_id);
                         if let hir::Node::Pat(pat) = node {
                             if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
                                 name = Some(ident.name);
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index 5c5a6e8db57..de0590a4b14 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -21,7 +21,7 @@ pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized {
     /// `read_discriminant` can be hooked for better error messages.
     #[inline(always)]
     fn read_discriminant(&mut self, v: &Self::V) -> InterpResult<'tcx, VariantIdx> {
-        Ok(self.ecx().read_discriminant(&v.to_op(self.ecx())?)?)
+        self.ecx().read_discriminant(&v.to_op(self.ecx())?)
     }
 
     /// This function provides the chance to reorder the order in which fields are visited for
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 5380d3071d6..bb17602d3ba 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -277,8 +277,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         // "secondary" errors if they occurred.
         let secondary_errors = mem::take(&mut self.secondary_errors);
         if self.error_emitted.is_none() {
-            for mut error in secondary_errors {
-                self.tcx.sess.diagnostic().emit_diagnostic(&mut error);
+            for error in secondary_errors {
+                self.tcx.sess.diagnostic().emit_diagnostic(error);
             }
         } else {
             assert!(self.tcx.sess.has_errors().is_some());
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 5bf9911269c..2de6362b9fe 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -119,8 +119,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
             match self_ty.kind() {
                 Param(param_ty) => {
                     debug!(?param_ty);
-                    let caller_hir_id = tcx.local_def_id_to_hir_id(caller);
-                    if let Some(generics) = tcx.hir().get(caller_hir_id).generics() {
+                    if let Some(generics) = tcx.hir_node_by_def_id(caller).generics() {
                         let constraint = with_no_trimmed_paths!(format!(
                             "~const {}",
                             trait_ref.print_only_trait_path()
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 60b343afbed..ed2e558bffa 100644
--- a/compiler/rustc_data_structures/src/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -198,7 +198,7 @@ impl<K: Ord, V> SortedMap<K, V> {
                 if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 {
                     // We can copy the whole range without having to mix with
                     // existing elements.
-                    self.data.splice(index..index, elements.into_iter());
+                    self.data.splice(index..index, elements);
                     return;
                 }
 
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs
index cb7f7d318dc..cafa91c8b8b 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs
@@ -81,6 +81,7 @@
 ///     E::A,
 /// }
 /// ```
+#[cfg(bootstrap)]
 #[macro_export]
 macro_rules! impl_tag {
     (
@@ -140,5 +141,148 @@ macro_rules! impl_tag {
     };
 }
 
+/// Implements [`Tag`] for a given type.
+///
+/// You can use `impl_tag` on structs and enums.
+/// You need to specify the type and all its possible values,
+/// which can only be paths with optional fields.
+///
+/// [`Tag`]: crate::tagged_ptr::Tag
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// #![feature(macro_metavar_expr)]
+/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag};
+///
+/// #[derive(Copy, Clone, PartialEq, Debug)]
+/// enum SomeTag {
+///     A,
+///     B,
+///     X { v: bool },
+///     Y(bool, bool),
+/// }
+///
+/// impl_tag! {
+///     // The type for which the `Tag` will be implemented
+///     impl Tag for SomeTag;
+///     // You need to specify all possible tag values:
+///     SomeTag::A, // 0
+///     SomeTag::B, // 1
+///     // For variants with fields, you need to specify the fields:
+///     SomeTag::X { v: true  }, // 2
+///     SomeTag::X { v: false }, // 3
+///     // For tuple variants use named syntax:
+///     SomeTag::Y { 0: true,  1: true  }, // 4
+///     SomeTag::Y { 0: false, 1: true  }, // 5
+///     SomeTag::Y { 0: true,  1: false }, // 6
+///     SomeTag::Y { 0: false, 1: false }, // 7
+/// }
+///
+/// // Tag values are assigned in order:
+/// assert_eq!(SomeTag::A.into_usize(), 0);
+/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3);
+/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5);
+///
+/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B);
+/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true });
+/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false));
+/// ```
+///
+/// Structs are supported:
+///
+/// ```
+/// #![feature(macro_metavar_expr)]
+/// # use rustc_data_structures::impl_tag;
+/// #[derive(Copy, Clone)]
+/// struct Flags { a: bool, b: bool }
+///
+/// impl_tag! {
+///     impl Tag for Flags;
+///     Flags { a: true,  b: true  },
+///     Flags { a: false, b: true  },
+///     Flags { a: true,  b: false },
+///     Flags { a: false, b: false },
+/// }
+/// ```
+///
+/// Not specifying all values results in a compile error:
+///
+/// ```compile_fail,E0004
+/// #![feature(macro_metavar_expr)]
+/// # use rustc_data_structures::impl_tag;
+/// #[derive(Copy, Clone)]
+/// enum E {
+///     A,
+///     B,
+/// }
+///
+/// impl_tag! {
+///     impl Tag for E;
+///     E::A,
+/// }
+/// ```
+#[cfg(not(bootstrap))]
+#[macro_export]
+macro_rules! impl_tag {
+    (
+        impl Tag for $Self:ty;
+        $(
+            $($path:ident)::* $( { $( $fields:tt )* })?,
+        )*
+    ) => {
+        // Safety:
+        // `bits_for_tags` is called on the same `${index()}`-es as
+        // `into_usize` returns, thus `BITS` constant is correct.
+        unsafe impl $crate::tagged_ptr::Tag for $Self {
+            const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[
+                $(
+                    ${index()},
+                    $( ${ignore($path)} )*
+                )*
+            ]);
+
+            #[inline]
+            fn into_usize(self) -> usize {
+                // This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc)
+                // (or at least it should, see <https://github.com/rust-lang/rust/issues/110613>)
+                #[forbid(unreachable_patterns)]
+                match self {
+                    // `match` is doing heavy lifting here, by requiring exhaustiveness
+                    $(
+                        $($path)::* $( { $( $fields )* } )? => ${index()},
+                    )*
+                }
+            }
+
+            #[inline]
+            unsafe fn from_usize(tag: usize) -> Self {
+                match tag {
+                    $(
+                        ${index()} => $($path)::* $( { $( $fields )* } )?,
+                    )*
+
+                    // Safety:
+                    // `into_usize` only returns `${index()}` of the same
+                    // repetition as we are filtering above, thus if this is
+                    // reached, the safety contract of this function was
+                    // already breached.
+                    _ => unsafe {
+                        debug_assert!(
+                            false,
+                            "invalid tag: {tag}\
+                             (this is a bug in the caller of `from_usize`)"
+                        );
+                        std::hint::unreachable_unchecked()
+                    },
+                }
+            }
+
+        }
+    };
+}
+
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 8b7a4dbff9d..e49db64536f 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -587,10 +587,8 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
     let mut print_formatted = if pager_name == "less" {
         cmd.arg("-r");
         true
-    } else if ["bat", "catbat", "delta"].iter().any(|v| *v == pager_name) {
-        true
     } else {
-        false
+        ["bat", "catbat", "delta"].iter().any(|v| *v == pager_name)
     };
 
     if color == ColorConfig::Never {
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 4fb63d67e78..403e0ec7950 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -91,10 +91,7 @@ where
 #[rustc_diagnostic_item = "DecorateLint"]
 pub trait DecorateLint<'a, G: EmissionGuarantee> {
     /// Decorate and emit a lint.
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut DiagnosticBuilder<'a, G>,
-    ) -> &'b mut DiagnosticBuilder<'a, G>;
+    fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, G>);
 
     fn msg(&self) -> DiagnosticMessage;
 }
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index b8bd86a72e4..315e47c0971 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -132,7 +132,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
             DiagnosticBuilderState::Emittable(handler) => {
                 db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
 
-                let guar = handler.emit_diagnostic(&mut db.inner.diagnostic);
+                let guar = handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
 
                 // Only allow a guarantee if the `level` wasn't switched to a
                 // non-error - the field isn't `pub`, but the whole `Diagnostic`
@@ -181,7 +181,7 @@ impl EmissionGuarantee for () {
             DiagnosticBuilderState::Emittable(handler) => {
                 db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
 
-                handler.emit_diagnostic(&mut db.inner.diagnostic);
+                handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
             }
             // `.emit()` was previously called, disallowed from repeating it.
             DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
@@ -207,7 +207,7 @@ impl EmissionGuarantee for Noted {
             // First `.emit()` call, the `&Handler` is still available.
             DiagnosticBuilderState::Emittable(handler) => {
                 db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
-                handler.emit_diagnostic(&mut db.inner.diagnostic);
+                handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
             }
             // `.emit()` was previously called, disallowed from repeating it.
             DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
@@ -236,7 +236,7 @@ impl EmissionGuarantee for Bug {
             DiagnosticBuilderState::Emittable(handler) => {
                 db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
 
-                handler.emit_diagnostic(&mut db.inner.diagnostic);
+                handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
             }
             // `.emit()` was previously called, disallowed from repeating it.
             DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
@@ -260,7 +260,7 @@ impl EmissionGuarantee for ! {
             DiagnosticBuilderState::Emittable(handler) => {
                 db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
 
-                handler.emit_diagnostic(&mut db.inner.diagnostic);
+                handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
             }
             // `.emit()` was previously called, disallowed from repeating it.
             DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
@@ -284,7 +284,7 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
             DiagnosticBuilderState::Emittable(handler) => {
                 db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
 
-                handler.emit_diagnostic(&mut db.inner.diagnostic);
+                handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
             }
             // `.emit()` was previously called, disallowed from repeating it.
             DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
@@ -365,7 +365,9 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
         }
     }
 
-    /// Emit the diagnostic.
+    /// Emit the diagnostic. Does not consume `self`, which may be surprising,
+    /// but there are various places that rely on continuing to use `self`
+    /// after calling `emit`.
     #[track_caller]
     pub fn emit(&mut self) -> G {
         G::diagnostic_builder_emit_producing_guarantee(self)
@@ -640,13 +642,13 @@ impl Drop for DiagnosticBuilderInner<'_> {
             // No `.emit()` or `.cancel()` calls.
             DiagnosticBuilderState::Emittable(handler) => {
                 if !panicking() {
-                    handler.emit_diagnostic(&mut Diagnostic::new(
+                    handler.emit_diagnostic(Diagnostic::new(
                         Level::Bug,
                         DiagnosticMessage::from(
                             "the following error was constructed but not emitted",
                         ),
                     ));
-                    handler.emit_diagnostic(&mut self.diagnostic);
+                    handler.emit_diagnostic_without_consuming(&mut self.diagnostic);
                     panic!("error was constructed but not emitted");
                 }
             }
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 4f77f09b26e..558262460c7 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -378,3 +378,9 @@ pub struct IndicateAnonymousLifetime {
     pub count: usize,
     pub suggestion: String,
 }
+
+impl IntoDiagnosticArg for type_ir::ClosureKind {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(self.as_str().into())
+    }
+}
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 3f257fdd9cf..ec37240e394 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -581,7 +581,7 @@ impl Emitter for SilentEmitter {
             if let Some(ref note) = self.fatal_note {
                 d.note(note.clone());
             }
-            self.fatal_handler.emit_diagnostic(&mut d);
+            self.fatal_handler.emit_diagnostic(d);
         }
     }
 }
@@ -2677,10 +2677,7 @@ fn from_stderr(color: ColorConfig) -> Destination {
 /// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead.
 ///
 /// See #36178.
-#[cfg(windows)]
-const BRIGHT_BLUE: Color = Color::Cyan;
-#[cfg(not(windows))]
-const BRIGHT_BLUE: Color = Color::Blue;
+const BRIGHT_BLUE: Color = if cfg!(windows) { Color::Cyan } else { Color::Blue };
 
 impl Style {
     fn color_spec(&self, lvl: Level) -> ColorSpec {
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index daa8a7706eb..cf73c638d85 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -585,11 +585,6 @@ impl Handler {
         self
     }
 
-    pub fn treat_err_as_bug(mut self, treat_err_as_bug: NonZeroUsize) -> Self {
-        self.inner.get_mut().flags.treat_err_as_bug = Some(treat_err_as_bug);
-        self
-    }
-
     pub fn with_flags(mut self, flags: HandlerFlags) -> Self {
         self.inner.get_mut().flags = flags;
         self
@@ -727,7 +722,12 @@ impl Handler {
         self.inner.borrow_mut().emit_stashed_diagnostics()
     }
 
-    /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`.
+    /// Construct a builder with the `msg` at the level appropriate for the
+    /// specific `EmissionGuarantee`.
+    ///
+    /// Note: this is necessary for `derive(Diagnostic)`, but shouldn't be used
+    /// outside of that. Instead use `struct_err`, `struct_warn`, etc., which
+    /// make the diagnostic kind clearer.
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn struct_diagnostic<G: EmissionGuarantee>(
@@ -942,13 +942,23 @@ impl Handler {
         result
     }
 
-    /// Construct a builder at the `Error` level with the `msg`.
+    /// Construct a builder at the `Fatal` level with the `msg`.
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
         DiagnosticBuilder::new(self, Level::Fatal, msg)
     }
 
+    /// Construct a builder at the `Fatal` level with the `msg`, that doesn't abort.
+    #[rustc_lint_diagnostics]
+    #[track_caller]
+    pub fn struct_almost_fatal(
+        &self,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, FatalError> {
+        DiagnosticBuilder::new(self, Level::Fatal, msg)
+    }
+
     /// Construct a builder at the `Help` level with the `msg`.
     #[rustc_lint_diagnostics]
     pub fn struct_help(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
@@ -965,8 +975,7 @@ impl Handler {
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn span_fatal(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
-        self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span);
-        FatalError.raise()
+        self.struct_span_fatal(span, msg).emit()
     }
 
     #[rustc_lint_diagnostics]
@@ -977,8 +986,7 @@ impl Handler {
         msg: impl Into<DiagnosticMessage>,
         code: DiagnosticId,
     ) -> ! {
-        self.emit_diag_at_span(Diagnostic::new_with_code(Fatal, Some(code), msg), span);
-        FatalError.raise()
+        self.struct_span_fatal_with_code(span, msg, code).emit()
     }
 
     #[rustc_lint_diagnostics]
@@ -988,7 +996,7 @@ impl Handler {
         span: impl Into<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
     ) -> ErrorGuaranteed {
-        self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span).unwrap()
+        self.struct_span_err(span, msg).emit()
     }
 
     #[rustc_lint_diagnostics]
@@ -999,17 +1007,13 @@ impl Handler {
         msg: impl Into<DiagnosticMessage>,
         code: DiagnosticId,
     ) -> ErrorGuaranteed {
-        self.emit_diag_at_span(
-            Diagnostic::new_with_code(Error { lint: false }, Some(code), msg),
-            span,
-        )
-        .unwrap()
+        self.struct_span_err_with_code(span, msg, code).emit()
     }
 
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn span_warn(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
-        self.emit_diag_at_span(Diagnostic::new(Warning(None), msg), span);
+        self.struct_span_warn(span, msg).emit()
     }
 
     #[rustc_lint_diagnostics]
@@ -1020,10 +1024,10 @@ impl Handler {
         msg: impl Into<DiagnosticMessage>,
         code: DiagnosticId,
     ) {
-        self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span);
+        self.struct_span_warn_with_code(span, msg, code).emit()
     }
 
-    pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<String>) -> ! {
+    pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
         self.inner.borrow_mut().span_bug(span, msg)
     }
 
@@ -1035,7 +1039,7 @@ impl Handler {
     pub fn span_delayed_bug(
         &self,
         sp: impl Into<MultiSpan>,
-        msg: impl Into<String>,
+        msg: impl Into<DiagnosticMessage>,
     ) -> ErrorGuaranteed {
         let mut inner = self.inner.borrow_mut();
 
@@ -1046,11 +1050,11 @@ impl Handler {
             inner.err_count + inner.lint_err_count + inner.delayed_bug_count() + 1 >= c.get()
         }) {
             // FIXME: don't abort here if report_delayed_bugs is off
-            inner.span_bug(sp, msg.into());
+            inner.span_bug(sp, msg);
         }
-        let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg.into());
-        diagnostic.set_span(sp.into());
-        inner.emit_diagnostic(&mut diagnostic).unwrap()
+        let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
+        diagnostic.set_span(sp);
+        inner.emit_diagnostic(diagnostic).unwrap()
     }
 
     // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
@@ -1060,7 +1064,7 @@ impl Handler {
 
         let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
         if inner.flags.report_delayed_bugs {
-            inner.emit_diagnostic(&mut diagnostic);
+            inner.emit_diagnostic_without_consuming(&mut diagnostic);
         }
         let backtrace = std::backtrace::Backtrace::capture();
         inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
@@ -1068,20 +1072,22 @@ impl Handler {
 
     #[track_caller]
     pub fn span_bug_no_panic(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
-        self.emit_diag_at_span(Diagnostic::new(Bug, msg), span);
+        let mut diag = Diagnostic::new(Bug, msg);
+        diag.set_span(span);
+        self.emit_diagnostic(diag);
     }
 
     #[track_caller]
     #[rustc_lint_diagnostics]
     pub fn span_note(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
-        self.emit_diag_at_span(Diagnostic::new(Note, msg), span);
+        self.struct_span_note(span, msg).emit()
     }
 
     #[track_caller]
     #[rustc_lint_diagnostics]
     pub fn struct_span_note(
         &self,
-        span: Span,
+        span: impl Into<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
     ) -> DiagnosticBuilder<'_, ()> {
         let mut db = DiagnosticBuilder::new(self, Note, msg);
@@ -1091,22 +1097,22 @@ impl Handler {
 
     #[rustc_lint_diagnostics]
     pub fn fatal(&self, msg: impl Into<DiagnosticMessage>) -> ! {
-        DiagnosticBuilder::<FatalError>::new(self, Fatal, msg).emit().raise()
+        self.struct_fatal(msg).emit()
     }
 
     #[rustc_lint_diagnostics]
     pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
-        DiagnosticBuilder::<ErrorGuaranteed>::new(self, Error { lint: false }, msg).emit()
+        self.struct_err(msg).emit()
     }
 
     #[rustc_lint_diagnostics]
     pub fn warn(&self, msg: impl Into<DiagnosticMessage>) {
-        DiagnosticBuilder::<()>::new(self, Warning(None), msg).emit();
+        self.struct_warn(msg).emit()
     }
 
     #[rustc_lint_diagnostics]
     pub fn note(&self, msg: impl Into<DiagnosticMessage>) {
-        DiagnosticBuilder::<()>::new(self, Note, msg).emit();
+        self.struct_note(msg).emit()
     }
 
     pub fn bug(&self, msg: impl Into<DiagnosticMessage>) -> ! {
@@ -1181,10 +1187,10 @@ impl Handler {
                 DiagnosticMessage::Str(warnings),
             )),
             (_, 0) => {
-                inner.emit_diagnostic(&mut Diagnostic::new(Fatal, errors));
+                inner.emit_diagnostic(Diagnostic::new(Fatal, errors));
             }
             (_, _) => {
-                inner.emit_diagnostic(&mut Diagnostic::new(Fatal, format!("{errors}; {warnings}")));
+                inner.emit_diagnostic(Diagnostic::new(Fatal, format!("{errors}; {warnings}")));
             }
         }
 
@@ -1251,8 +1257,17 @@ impl Handler {
         self.inner.borrow_mut().emitter.emit_diagnostic(&db);
     }
 
-    pub fn emit_diagnostic(&self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> {
-        self.inner.borrow_mut().emit_diagnostic(diagnostic)
+    pub fn emit_diagnostic(&self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
+        self.emit_diagnostic_without_consuming(&mut diagnostic)
+    }
+
+    // It's unfortunate this exists. `emit_diagnostic` is preferred, because it
+    // consumes the diagnostic, thus ensuring it is emitted just once.
+    pub(crate) fn emit_diagnostic_without_consuming(
+        &self,
+        diagnostic: &mut Diagnostic,
+    ) -> Option<ErrorGuaranteed> {
+        self.inner.borrow_mut().emit_diagnostic_without_consuming(diagnostic)
     }
 
     pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed {
@@ -1327,14 +1342,6 @@ impl Handler {
         note.into_diagnostic(self)
     }
 
-    fn emit_diag_at_span(
-        &self,
-        mut diag: Diagnostic,
-        sp: impl Into<MultiSpan>,
-    ) -> Option<ErrorGuaranteed> {
-        self.emit_diagnostic(diag.set_span(sp))
-    }
-
     pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
         self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
     }
@@ -1374,7 +1381,7 @@ impl Handler {
                 // Here the diagnostic is given back to `emit_diagnostic` where it was first
                 // intercepted. Now it should be processed as usual, since the unstable expectation
                 // id is now stable.
-                inner.emit_diagnostic(&mut diag);
+                inner.emit_diagnostic(diag);
             }
         }
 
@@ -1416,7 +1423,7 @@ impl HandlerInner {
         let has_errors = self.has_errors();
         let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
         let mut reported = None;
-        for mut diag in diags {
+        for diag in diags {
             // Decrement the count tracking the stash; emitting will increment it.
             if diag.is_error() {
                 if matches!(diag.level, Level::Error { lint: true }) {
@@ -1436,14 +1443,20 @@ impl HandlerInner {
                     }
                 }
             }
-            let reported_this = self.emit_diagnostic(&mut diag);
+            let reported_this = self.emit_diagnostic(diag);
             reported = reported.or(reported_this);
         }
         reported
     }
 
-    // FIXME(eddyb) this should ideally take `diagnostic` by value.
-    fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> {
+    fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
+        self.emit_diagnostic_without_consuming(&mut diagnostic)
+    }
+
+    fn emit_diagnostic_without_consuming(
+        &mut self,
+        diagnostic: &mut Diagnostic,
+    ) -> Option<ErrorGuaranteed> {
         if matches!(diagnostic.level, Level::Error { .. } | Level::Fatal) && self.treat_err_as_bug()
         {
             diagnostic.level = Level::Bug;
@@ -1579,17 +1592,15 @@ impl HandlerInner {
     }
 
     #[track_caller]
-    fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: impl Into<String>) -> ! {
-        self.emit_diag_at_span(Diagnostic::new(Bug, msg.into()), sp);
+    fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
+        let mut diag = Diagnostic::new(Bug, msg);
+        diag.set_span(sp);
+        self.emit_diagnostic(diag);
         panic::panic_any(ExplicitBug);
     }
 
-    fn emit_diag_at_span(&mut self, mut diag: Diagnostic, sp: impl Into<MultiSpan>) {
-        self.emit_diagnostic(diag.set_span(sp));
-    }
-
     fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) {
-        self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg));
+        self.emit_diagnostic(Diagnostic::new(FailureNote, msg));
     }
 
     fn flush_delayed(
@@ -1621,7 +1632,7 @@ impl HandlerInner {
             if no_bugs {
                 // Put the overall explanation before the `DelayedBug`s, to
                 // frame them better (e.g. separate warnings from them).
-                self.emit_diagnostic(&mut Diagnostic::new(Bug, explanation));
+                self.emit_diagnostic(Diagnostic::new(Bug, explanation));
                 no_bugs = false;
             }
 
@@ -1636,7 +1647,7 @@ impl HandlerInner {
             }
             bug.level = Level::Bug;
 
-            self.emit_diagnostic(&mut bug);
+            self.emit_diagnostic(bug);
         }
 
         // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 11db4bb4017..d75556ac7c4 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1145,7 +1145,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
         self.sess.diagnostic().span_err(sp, msg);
     }
-    pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<String>) -> ! {
+    pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! {
         self.sess.diagnostic().span_bug(sp, msg);
     }
     pub fn trace_macros_diag(&mut self) {
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 47d4b802c0f..89caf8aa231 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -41,6 +41,7 @@ use std::path::PathBuf;
 use std::rc::Rc;
 use std::{iter, mem};
 
+#[cfg(bootstrap)]
 macro_rules! ast_fragments {
     (
         $($Kind:ident($AstTy:ty) {
@@ -165,6 +166,131 @@ macro_rules! ast_fragments {
     }
 }
 
+#[cfg(not(bootstrap))]
+macro_rules! ast_fragments {
+    (
+        $($Kind:ident($AstTy:ty) {
+            $kind_name:expr;
+            $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)?
+            $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)?
+            fn $make_ast:ident;
+        })*
+    ) => {
+        /// A fragment of AST that can be produced by a single macro expansion.
+        /// Can also serve as an input and intermediate result for macro expansion operations.
+        pub enum AstFragment {
+            OptExpr(Option<P<ast::Expr>>),
+            MethodReceiverExpr(P<ast::Expr>),
+            $($Kind($AstTy),)*
+        }
+
+        /// "Discriminant" of an AST fragment.
+        #[derive(Copy, Clone, PartialEq, Eq)]
+        pub enum AstFragmentKind {
+            OptExpr,
+            MethodReceiverExpr,
+            $($Kind,)*
+        }
+
+        impl AstFragmentKind {
+            pub fn name(self) -> &'static str {
+                match self {
+                    AstFragmentKind::OptExpr => "expression",
+                    AstFragmentKind::MethodReceiverExpr => "expression",
+                    $(AstFragmentKind::$Kind => $kind_name,)*
+                }
+            }
+
+            fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> {
+                match self {
+                    AstFragmentKind::OptExpr =>
+                        result.make_expr().map(Some).map(AstFragment::OptExpr),
+                    AstFragmentKind::MethodReceiverExpr =>
+                        result.make_expr().map(AstFragment::MethodReceiverExpr),
+                    $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
+                }
+            }
+        }
+
+        impl AstFragment {
+            pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
+                if placeholders.is_empty() {
+                    return;
+                }
+                match self {
+                    $($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
+                        ${ignore($flat_map_ast_elt)}
+                        placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
+                    })),)?)*
+                    _ => panic!("unexpected AST fragment kind")
+                }
+            }
+
+            pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
+                match self {
+                    AstFragment::OptExpr(expr) => expr,
+                    _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
+                }
+            }
+
+            pub fn make_method_receiver_expr(self) -> P<ast::Expr> {
+                match self {
+                    AstFragment::MethodReceiverExpr(expr) => expr,
+                    _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
+                }
+            }
+
+            $(pub fn $make_ast(self) -> $AstTy {
+                match self {
+                    AstFragment::$Kind(ast) => ast,
+                    _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
+                }
+            })*
+
+            fn make_ast<T: InvocationCollectorNode>(self) -> T::OutputTy {
+                T::fragment_to_output(self)
+            }
+
+            pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
+                match self {
+                    AstFragment::OptExpr(opt_expr) => {
+                        visit_clobber(opt_expr, |opt_expr| {
+                            if let Some(expr) = opt_expr {
+                                vis.filter_map_expr(expr)
+                            } else {
+                                None
+                            }
+                        });
+                    }
+                    AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr),
+                    $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)*
+                    $($(AstFragment::$Kind(ast) =>
+                        ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)*
+                }
+            }
+
+            pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
+                match self {
+                    AstFragment::OptExpr(Some(expr)) => visitor.visit_expr(expr),
+                    AstFragment::OptExpr(None) => {}
+                    AstFragment::MethodReceiverExpr(expr) => visitor.visit_method_receiver_expr(expr),
+                    $($(AstFragment::$Kind(ast) => visitor.$visit_ast(ast),)?)*
+                    $($(AstFragment::$Kind(ast) => for ast_elt in &ast[..] {
+                        visitor.$visit_ast_elt(ast_elt, $($args)*);
+                    })?)*
+                }
+            }
+        }
+
+        impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> {
+            $(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a>>)
+                           -> Option<$AstTy> {
+                Some(self.make(AstFragmentKind::$Kind).$make_ast())
+            })*
+        }
+    }
+}
+
 ast_fragments! {
     Expr(P<ast::Expr>) { "expression"; one fn visit_expr; fn visit_expr; fn make_expr; }
     Pat(P<ast::Pat>) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; }
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index c29edc3dc9f..4b8c6feb93e 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -10,9 +10,8 @@ use rustc_span::Span;
 /// A meta-variable expression, for expansions based on properties of meta-variables.
 #[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
 pub(crate) enum MetaVarExpr {
-    /// The number of repetitions of an identifier, optionally limited to a number
-    /// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited.
-    Count(Ident, Option<usize>),
+    /// The number of repetitions of an identifier.
+    Count(Ident, usize),
 
     /// Ignore a meta-variable for repetition without expansion.
     Ignore(Ident),
@@ -43,7 +42,10 @@ impl MetaVarExpr {
         let mut iter = args.trees();
         let rslt = match ident.as_str() {
             "count" => parse_count(&mut iter, sess, ident.span)?,
-            "ignore" => MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?),
+            "ignore" => {
+                eat_dollar(&mut iter, sess, ident.span)?;
+                MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?)
+            }
             "index" => MetaVarExpr::Index(parse_depth(&mut iter, sess, ident.span)?),
             "length" => MetaVarExpr::Length(parse_depth(&mut iter, sess, ident.span)?),
             _ => {
@@ -92,6 +94,7 @@ fn parse_count<'sess>(
     sess: &'sess ParseSess,
     span: Span,
 ) -> PResult<'sess, MetaVarExpr> {
+    eat_dollar(iter, sess, span)?;
     let ident = parse_ident(iter, sess, span)?;
     let depth = if try_eat_comma(iter) {
         if iter.look_ahead(0).is_none() {
@@ -100,9 +103,9 @@ fn parse_count<'sess>(
                 "`count` followed by a comma must have an associated index indicating its depth",
             ));
         }
-        Some(parse_depth(iter, sess, span)?)
+        parse_depth(iter, sess, span)?
     } else {
-        None
+        0
     };
     Ok(MetaVarExpr::Count(ident, depth))
 }
@@ -166,3 +169,20 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool {
     }
     false
 }
+
+/// Expects that the next item is a dollar sign.
+fn eat_dollar<'sess>(
+    iter: &mut RefTokenTreeCursor<'_>,
+    sess: &'sess ParseSess,
+    span: Span,
+) -> PResult<'sess, ()> {
+    if let Some(TokenTree::Token(token::Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0)
+    {
+        let _ = iter.next();
+        return Ok(());
+    }
+    Err(sess.span_diagnostic.struct_span_err(
+        span,
+        "meta-variables within meta-variable expressions must be referenced using a dollar sign",
+    ))
+}
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index 18707cebcd5..80fd82e0302 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -440,7 +440,7 @@ fn lockstep_iter_size(
 ///   declared inside a single repetition and the index `1` implies two nested repetitions.
 fn count_repetitions<'a>(
     cx: &ExtCtxt<'a>,
-    depth_opt: Option<usize>,
+    depth_user: usize,
     mut matched: &NamedMatch,
     repeats: &[(usize, usize)],
     sp: &DelimSpan,
@@ -449,37 +449,45 @@ fn count_repetitions<'a>(
     // (or at the top-level of `matched` if no depth is given).
     fn count<'a>(
         cx: &ExtCtxt<'a>,
-        declared_lhs_depth: usize,
-        depth_opt: Option<usize>,
+        depth_curr: usize,
+        depth_max: usize,
         matched: &NamedMatch,
         sp: &DelimSpan,
     ) -> PResult<'a, usize> {
         match matched {
-            MatchedTokenTree(_) | MatchedNonterminal(_) => {
-                if declared_lhs_depth == 0 {
-                    return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
-                }
-                match depth_opt {
-                    None => Ok(1),
-                    Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")),
-                }
-            }
+            MatchedTokenTree(_) | MatchedNonterminal(_) => Ok(1),
             MatchedSeq(named_matches) => {
-                let new_declared_lhs_depth = declared_lhs_depth + 1;
-                match depth_opt {
-                    None => named_matches
-                        .iter()
-                        .map(|elem| count(cx, new_declared_lhs_depth, None, elem, sp))
-                        .sum(),
-                    Some(0) => Ok(named_matches.len()),
-                    Some(depth) => named_matches
+                if depth_curr == depth_max {
+                    Ok(named_matches.len())
+                } else {
+                    named_matches
                         .iter()
-                        .map(|elem| count(cx, new_declared_lhs_depth, Some(depth - 1), elem, sp))
-                        .sum(),
+                        .map(|elem| count(cx, depth_curr + 1, depth_max, elem, sp))
+                        .sum()
                 }
             }
         }
     }
+
+    /// Maximum depth
+    fn depth(counter: usize, matched: &NamedMatch) -> usize {
+        match matched {
+            MatchedTokenTree(_) | MatchedNonterminal(_) => counter,
+            MatchedSeq(named_matches) => {
+                let rslt = counter + 1;
+                if let Some(elem) = named_matches.first() { depth(rslt, elem) } else { rslt }
+            }
+        }
+    }
+
+    let depth_max = depth(0, matched)
+        .checked_sub(1)
+        .and_then(|el| el.checked_sub(repeats.len()))
+        .unwrap_or_default();
+    if depth_user > depth_max {
+        return Err(out_of_bounds_err(cx, depth_max + 1, sp.entire(), "count"));
+    }
+
     // `repeats` records all of the nested levels at which we are currently
     // matching meta-variables. The meta-var-expr `count($x)` only counts
     // matches that occur in this "subtree" of the `NamedMatch` where we
@@ -491,7 +499,12 @@ fn count_repetitions<'a>(
             matched = &ads[idx];
         }
     }
-    count(cx, 0, depth_opt, matched, sp)
+
+    if let MatchedTokenTree(_) | MatchedNonterminal(_) = matched {
+        return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
+    }
+
+    count(cx, depth_user, depth_max, matched, sp)
 }
 
 /// Returns a `NamedMatch` item declared on the LHS given an arbitrary [Ident]
@@ -523,7 +536,7 @@ fn out_of_bounds_err<'a>(
         )
     } else {
         format!(
-            "depth parameter on meta-variable expression `{ty}` \
+            "depth parameter of meta-variable expression `{ty}` \
              must be less than {max}"
         )
     };
@@ -545,9 +558,9 @@ fn transcribe_metavar_expr<'a>(
         span
     };
     match *expr {
-        MetaVarExpr::Count(original_ident, depth_opt) => {
+        MetaVarExpr::Count(original_ident, depth) => {
             let matched = matched_from_ident(cx, original_ident, interp)?;
-            let count = count_repetitions(cx, depth_opt, matched, repeats, sp)?;
+            let count = count_repetitions(cx, depth, matched, repeats, sp)?;
             let tt = TokenTree::token_alone(
                 TokenKind::lit(token::Integer, sym::integer(count), None),
                 visited_span(),
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 5308e338d7f..d2c26668ea8 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -502,7 +502,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
                 None,
             );
         }
-        self.sess().span_diagnostic.emit_diagnostic(&mut diag);
+        self.sess().span_diagnostic.emit_diagnostic(diag);
     }
 }
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 01508375b1a..760945554f0 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -435,8 +435,6 @@ pub enum TraitBoundModifier {
 #[derive(Clone, Copy, Debug, HashStable_Generic)]
 pub enum GenericBound<'hir> {
     Trait(PolyTraitRef<'hir>, TraitBoundModifier),
-    // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
-    LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
     Outlives(&'hir Lifetime),
 }
 
@@ -451,7 +449,6 @@ impl GenericBound<'_> {
     pub fn span(&self) -> Span {
         match self {
             GenericBound::Trait(t, ..) => t.span,
-            GenericBound::LangItemTrait(_, span, ..) => *span,
             GenericBound::Outlives(l) => l.ident.span,
         }
     }
@@ -1560,7 +1557,7 @@ impl Expr<'_> {
             ExprKind::Call(..) => ExprPrecedence::Call,
             ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
             ExprKind::Tup(_) => ExprPrecedence::Tup,
-            ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node.into()),
+            ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
             ExprKind::Unary(..) => ExprPrecedence::Unary,
             ExprKind::Lit(_) => ExprPrecedence::Lit,
             ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
@@ -1700,11 +1697,9 @@ impl Expr<'_> {
                 // them being used only for its side-effects.
                 base.can_have_side_effects()
             }
-            ExprKind::Struct(_, fields, init) => fields
-                .iter()
-                .map(|field| field.expr)
-                .chain(init.into_iter())
-                .any(|e| e.can_have_side_effects()),
+            ExprKind::Struct(_, fields, init) => {
+                fields.iter().map(|field| field.expr).chain(init).any(|e| e.can_have_side_effects())
+            }
 
             ExprKind::Array(args)
             | ExprKind::Tup(args)
@@ -2815,7 +2810,7 @@ impl TraitRef<'_> {
         match self.path.res {
             Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
             Res::Err => None,
-            _ => unreachable!(),
+            res => panic!("{res:?} did not resolve to a trait or trait alias"),
         }
     }
 }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 9cf1db166a5..67e058a3219 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1075,10 +1075,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
         GenericBound::Trait(ref typ, _modifier) => {
             visitor.visit_poly_trait_ref(typ);
         }
-        GenericBound::LangItemTrait(_, _span, hir_id, args) => {
-            visitor.visit_id(hir_id);
-            visitor.visit_generic_args(args);
-        }
         GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
     }
 }
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 0d65ddb5642..8948a03e4a6 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -67,6 +67,42 @@ impl Display for Target {
 }
 
 impl Target {
+    pub fn is_associated_item(self) -> bool {
+        match self {
+            Target::AssocConst | Target::AssocTy | Target::Method(_) => true,
+            Target::ExternCrate
+            | Target::Use
+            | Target::Static
+            | Target::Const
+            | Target::Fn
+            | Target::Closure
+            | Target::Mod
+            | Target::ForeignMod
+            | Target::GlobalAsm
+            | Target::TyAlias
+            | Target::OpaqueTy
+            | Target::Enum
+            | Target::Variant
+            | Target::Struct
+            | Target::Field
+            | Target::Union
+            | Target::Trait
+            | Target::TraitAlias
+            | Target::Impl
+            | Target::Expression
+            | Target::Statement
+            | Target::Arm
+            | Target::ForeignFn
+            | Target::ForeignStatic
+            | Target::ForeignTy
+            | Target::GenericParam(_)
+            | Target::MacroDef
+            | Target::Param
+            | Target::PatField
+            | Target::ExprField => false,
+        }
+    }
+
     pub fn from_item(item: &Item<'_>) -> Target {
         match item.kind {
             ItemKind::ExternCrate(..) => Target::ExternCrate,
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index dfec3c5e829..0748644cc0a 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -134,17 +134,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
                         only_self_bounds,
                     );
                 }
-                &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
-                    self.instantiate_lang_item_trait_ref(
-                        lang_item,
-                        span,
-                        hir_id,
-                        args,
-                        param_ty,
-                        bounds,
-                        only_self_bounds,
-                    );
-                }
                 hir::GenericBound::Outlives(lifetime) => {
                     let region = self.ast_region_to_region(lifetime, None);
                     bounds.push_region_bound(
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 47fbed45b91..be73c027fdc 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -661,7 +661,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
                 args.args[0].hir_id(),
                 multispan,
                 msg,
-                |lint| lint,
+                |_| {},
             );
         }
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
index 14e810d1336..9afb04b7470 100644
--- a/compiler/rustc_hir_analysis/src/astconv/lint.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -24,7 +24,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     ..
                 }),
             ..
-        }) = tcx.hir().get_by_def_id(parent_id)
+        }) = tcx.hir_node_by_def_id(parent_id)
             && self_ty.hir_id == impl_self_ty.hir_id
         {
             if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
@@ -122,7 +122,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             Applicability::MachineApplicable,
                         );
                         self.maybe_lint_blanket_trait_impl(self_ty, lint);
-                        lint
                     },
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 20d36a1b069..6f8e80172dd 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -477,7 +477,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             ty::Const::new_misc_error(tcx, ty).into()
                         }
                     }
-                    _ => unreachable!(),
+                    (kind, arg) => span_bug!(
+                        self.span,
+                        "mismatched path argument for kind {kind:?}: found arg {arg:?}"
+                    ),
                 }
             }
 
@@ -675,36 +678,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         )
     }
 
-    fn instantiate_poly_trait_ref_inner(
+    /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
+    /// a full trait reference. The resulting trait reference is returned. This may also generate
+    /// auxiliary bounds, which are added to `bounds`.
+    ///
+    /// Example:
+    ///
+    /// ```ignore (illustrative)
+    /// poly_trait_ref = Iterator<Item = u32>
+    /// self_ty = Foo
+    /// ```
+    ///
+    /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
+    ///
+    /// **A note on binders:** against our usual convention, there is an implied binder around
+    /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
+    /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
+    /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
+    /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
+    /// however.
+    #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
+    pub(crate) fn instantiate_poly_trait_ref(
         &self,
-        hir_id: hir::HirId,
+        trait_ref: &hir::TraitRef<'_>,
         span: Span,
-        binding_span: Option<Span>,
         constness: ty::BoundConstness,
         polarity: ty::ImplPolarity,
+        self_ty: Ty<'tcx>,
         bounds: &mut Bounds<'tcx>,
         speculative: bool,
-        trait_ref_span: Span,
-        trait_def_id: DefId,
-        trait_segment: &hir::PathSegment<'_>,
-        args: &GenericArgs<'_>,
-        infer_args: bool,
-        self_ty: Ty<'tcx>,
         only_self_bounds: OnlySelfBounds,
     ) -> GenericArgCountResult {
+        let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
+        let trait_segment = trait_ref.path.segments.last().unwrap();
+        let args = trait_segment.args();
+
+        self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
+        self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
+
         let (generic_args, arg_count) = self.create_args_for_ast_path(
-            trait_ref_span,
+            trait_ref.path.span,
             trait_def_id,
             &[],
             trait_segment,
             args,
-            infer_args,
+            trait_segment.infer_args,
             Some(self_ty),
             constness,
         );
 
         let tcx = self.tcx();
-        let bound_vars = tcx.late_bound_vars(hir_id);
+        let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
         debug!(?bound_vars);
 
         let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
@@ -732,13 +756,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
             // Specify type to assert that error was already reported in `Err` case.
             let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding(
-                hir_id,
+                trait_ref.hir_ref_id,
                 poly_trait_ref,
                 binding,
                 bounds,
                 speculative,
                 &mut dup_bindings,
-                binding_span.unwrap_or(binding.span),
+                binding.span,
                 constness,
                 only_self_bounds,
                 polarity,
@@ -749,102 +773,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         arg_count
     }
 
-    /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
-    /// a full trait reference. The resulting trait reference is returned. This may also generate
-    /// auxiliary bounds, which are added to `bounds`.
-    ///
-    /// Example:
-    ///
-    /// ```ignore (illustrative)
-    /// poly_trait_ref = Iterator<Item = u32>
-    /// self_ty = Foo
-    /// ```
-    ///
-    /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
-    ///
-    /// **A note on binders:** against our usual convention, there is an implied bounder around
-    /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
-    /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
-    /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
-    /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
-    /// however.
-    #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
-    pub(crate) fn instantiate_poly_trait_ref(
-        &self,
-        trait_ref: &hir::TraitRef<'_>,
-        span: Span,
-        constness: ty::BoundConstness,
-        polarity: ty::ImplPolarity,
-        self_ty: Ty<'tcx>,
-        bounds: &mut Bounds<'tcx>,
-        speculative: bool,
-        only_self_bounds: OnlySelfBounds,
-    ) -> GenericArgCountResult {
-        let hir_id = trait_ref.hir_ref_id;
-        let binding_span = None;
-        let trait_ref_span = trait_ref.path.span;
-        let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
-        let trait_segment = trait_ref.path.segments.last().unwrap();
-        let args = trait_segment.args();
-        let infer_args = trait_segment.infer_args;
-
-        self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
-        self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
-
-        self.instantiate_poly_trait_ref_inner(
-            hir_id,
-            span,
-            binding_span,
-            constness,
-            polarity,
-            bounds,
-            speculative,
-            trait_ref_span,
-            trait_def_id,
-            trait_segment,
-            args,
-            infer_args,
-            self_ty,
-            only_self_bounds,
-        )
-    }
-
-    pub(crate) fn instantiate_lang_item_trait_ref(
-        &self,
-        lang_item: hir::LangItem,
-        span: Span,
-        hir_id: hir::HirId,
-        args: &GenericArgs<'_>,
-        self_ty: Ty<'tcx>,
-        bounds: &mut Bounds<'tcx>,
-        only_self_bounds: OnlySelfBounds,
-    ) {
-        let binding_span = Some(span);
-        let constness = ty::BoundConstness::NotConst;
-        let speculative = false;
-        let trait_ref_span = span;
-        let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
-        let trait_segment = &hir::PathSegment::invalid();
-        let infer_args = false;
-
-        self.instantiate_poly_trait_ref_inner(
-            hir_id,
-            span,
-            binding_span,
-            constness,
-            ty::ImplPolarity::Positive,
-            bounds,
-            speculative,
-            trait_ref_span,
-            trait_def_id,
-            trait_segment,
-            args,
-            infer_args,
-            self_ty,
-            only_self_bounds,
-        );
-    }
-
     fn ast_path_to_mono_trait_ref(
         &self,
         span: Span,
@@ -1506,8 +1434,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
                         Applicability::MachineApplicable,
                     );
-
-                    lint
                 },
             );
         }
@@ -1946,7 +1872,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     "s",
                 ),
                 [only] => (only.to_string(), ""),
-                [] => unreachable!(),
+                [] => unreachable!("expected at least one generic to prohibit"),
             };
             let last_span = *arg_spans.last().unwrap();
             let span: MultiSpan = arg_spans.into();
@@ -2555,8 +2481,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len())
             {
                 // Resolve our own lifetime parameters.
-                let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() };
-                let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
+                let GenericParamDefKind::Lifetime { .. } = param.kind else {
+                    span_bug!(
+                        tcx.def_span(param.def_id),
+                        "only expected lifetime for opaque's own generics, got {:?}",
+                        param.kind
+                    );
+                };
+                let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else {
+                    bug!(
+                        "expected lifetime argument for param {param:?}, found {:?}",
+                        &lifetimes[i]
+                    )
+                };
                 self.ast_region_to_region(lifetime, None).into()
             } else {
                 tcx.mk_param_from_def(param)
@@ -2715,7 +2652,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let hir = tcx.hir();
 
         let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
-            hir.get(fn_hir_id)
+            tcx.hir_node(fn_hir_id)
         else {
             return None;
         };
diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
index ce5426b5142..dd5deb6f244 100644
--- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
@@ -73,7 +73,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 | ty::ClauseKind::ConstArgHasType(..)
                 | ty::ClauseKind::WellFormed(_)
                 | ty::ClauseKind::ConstEvaluatable(_) => {
-                    bug!()
+                    span_bug!(span, "did not expect {pred} clause in object bounds");
                 }
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 6e18abf632e..8413a1cc0db 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -51,7 +51,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
                 hir_id,
                 span,
                 "use of calling convention not supported on this target",
-                |lint| lint,
+                |_| {},
             );
         }
     }
@@ -190,7 +190,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             "static of uninhabited type",
             |lint| {
                 lint
-                .note("uninhabited statics cannot be initialized, and any access would be an immediate error")
+                .note("uninhabited statics cannot be initialized, and any access would be an immediate error");
             },
         );
     }
@@ -504,7 +504,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
             let origin = tcx.opaque_type_origin(id.owner_id.def_id);
             if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
             | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
-                && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
+                && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
                 && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
             {
                 // Skip opaques from RPIT in traits with no default body.
@@ -1093,7 +1093,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
                             "this {descr} contains `{field_ty}`, which {note}, \
                                 and makes it not a breaking change to become \
                                 non-zero-sized in the future."
-                        ))
+                        ));
                     },
                 )
             } else {
@@ -1173,7 +1173,7 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
             ty::VariantDiscr::Explicit(discr_def_id) => {
                 // In the case the discriminant is both a duplicate and overflowed, let the user know
                 if let hir::Node::AnonConst(expr) =
-                    tcx.hir().get_by_def_id(discr_def_id.expect_local())
+                    tcx.hir_node_by_def_id(discr_def_id.expect_local())
                     && let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind
                     && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
                     && *lit_value != dis.val
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 1412fd1a987..264868fdfc7 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2,9 +2,7 @@ use super::potentially_plural_count;
 use crate::errors::LifetimesOrBoundsMismatchOnTrait;
 use hir::def_id::{DefId, LocalDefId};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_errors::{
-    pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed, MultiSpan,
-};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit;
@@ -50,13 +48,7 @@ pub(super) fn compare_impl_method<'tcx>(
 
     let _: Result<_, ErrorGuaranteed> = try {
         check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
-        compare_method_predicate_entailment(
-            tcx,
-            impl_m,
-            trait_m,
-            impl_trait_ref,
-            CheckImpliedWfMode::Check,
-        )?;
+        compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
         refine::check_refining_return_position_impl_trait_in_trait(
             tcx,
             impl_m,
@@ -170,7 +162,6 @@ fn compare_method_predicate_entailment<'tcx>(
     impl_m: ty::AssocItem,
     trait_m: ty::AssocItem,
     impl_trait_ref: ty::TraitRef<'tcx>,
-    check_implied_wf: CheckImpliedWfMode,
 ) -> Result<(), ErrorGuaranteed> {
     let trait_to_impl_args = impl_trait_ref.args;
 
@@ -317,10 +308,10 @@ fn compare_method_predicate_entailment<'tcx>(
         return Err(emitted);
     }
 
-    if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
+    if !(impl_sig, trait_sig).references_error() {
         // Select obligations to make progress on inference before processing
         // the wf obligation below.
-        // FIXME(-Ztrait-solver=next): Not needed when the hack below is removed.
+        // FIXME(-Znext-solver): Not needed when the hack below is removed.
         let errors = ocx.select_where_possible();
         if !errors.is_empty() {
             let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
@@ -333,8 +324,9 @@ fn compare_method_predicate_entailment<'tcx>(
         // trigger the lint. Instead, let's only consider type outlives and
         // region outlives obligations.
         //
-        // FIXME(-Ztrait-solver=next): Try removing this hack again once
-        // the new solver is stable.
+        // FIXME(-Znext-solver): Try removing this hack again once the new
+        // solver is stable. We should just be able to register a WF pred for
+        // the fn sig.
         let mut wf_args: smallvec::SmallVec<[_; 4]> =
             unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
         // Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
@@ -357,7 +349,7 @@ fn compare_method_predicate_entailment<'tcx>(
                     // We need to register Projection oblgiations too, because we may end up with
                     // an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
                     // If we only register the region outlives obligation, this leads to an unconstrained var.
-                    // See `implied_bounds_entailment_alias_var` test.
+                    // See `implied_bounds_entailment_alias_var.rs` test.
                     ty::PredicateKind::Clause(
                         ty::ClauseKind::RegionOutlives(..)
                         | ty::ClauseKind::TypeOutlives(..)
@@ -378,26 +370,8 @@ fn compare_method_predicate_entailment<'tcx>(
     // version.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        match check_implied_wf {
-            CheckImpliedWfMode::Check => {
-                let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
-                return compare_method_predicate_entailment(
-                    tcx,
-                    impl_m,
-                    trait_m,
-                    impl_trait_ref,
-                    CheckImpliedWfMode::Skip,
-                )
-                .map(|()| {
-                    // If the skip-mode was successful, emit a lint.
-                    emit_implied_wf_lint(infcx.tcx, impl_m, impl_m_hir_id, vec![]);
-                });
-            }
-            CheckImpliedWfMode::Skip => {
-                let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
-                return Err(reported);
-            }
-        }
+        let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
+        return Err(reported);
     }
 
     // Finally, resolve all regions. This catches wily misuses of
@@ -408,119 +382,14 @@ fn compare_method_predicate_entailment<'tcx>(
     );
     let errors = infcx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
-        // FIXME(compiler-errors): This can be simplified when IMPLIED_BOUNDS_ENTAILMENT
-        // becomes a hard error (i.e. ideally we'd just call `resolve_regions_and_report_errors`
-        let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
-        match check_implied_wf {
-            CheckImpliedWfMode::Check => {
-                return compare_method_predicate_entailment(
-                    tcx,
-                    impl_m,
-                    trait_m,
-                    impl_trait_ref,
-                    CheckImpliedWfMode::Skip,
-                )
-                .map(|()| {
-                    let bad_args = extract_bad_args_for_implies_lint(
-                        tcx,
-                        &errors,
-                        (trait_m, trait_sig),
-                        // Unnormalized impl sig corresponds to the HIR types written
-                        (impl_m, unnormalized_impl_sig),
-                        impl_m_hir_id,
-                    );
-                    // If the skip-mode was successful, emit a lint.
-                    emit_implied_wf_lint(tcx, impl_m, impl_m_hir_id, bad_args);
-                });
-            }
-            CheckImpliedWfMode::Skip => {
-                if infcx.tainted_by_errors().is_none() {
-                    infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors);
-                }
-                return Err(tcx
-                    .sess
-                    .span_delayed_bug(rustc_span::DUMMY_SP, "error should have been emitted"));
-            }
-        }
+        return Err(infcx
+            .tainted_by_errors()
+            .unwrap_or_else(|| infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors)));
     }
 
     Ok(())
 }
 
-fn extract_bad_args_for_implies_lint<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    errors: &[infer::RegionResolutionError<'tcx>],
-    (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
-    (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
-    hir_id: hir::HirId,
-) -> Vec<(Span, Option<String>)> {
-    let mut blame_generics = vec![];
-    for error in errors {
-        // Look for the subregion origin that contains an input/output type
-        let origin = match error {
-            infer::RegionResolutionError::ConcreteFailure(o, ..) => o,
-            infer::RegionResolutionError::GenericBoundFailure(o, ..) => o,
-            infer::RegionResolutionError::SubSupConflict(_, _, o, ..) => o,
-            infer::RegionResolutionError::UpperBoundUniverseConflict(.., o, _) => o,
-        };
-        // Extract (possible) input/output types from origin
-        match origin {
-            infer::SubregionOrigin::Subtype(trace) => {
-                if let Some((a, b)) = trace.values.ty() {
-                    blame_generics.extend([a, b]);
-                }
-            }
-            infer::SubregionOrigin::RelateParamBound(_, ty, _) => blame_generics.push(*ty),
-            infer::SubregionOrigin::ReferenceOutlivesReferent(ty, _) => blame_generics.push(*ty),
-            _ => {}
-        }
-    }
-
-    let fn_decl = tcx.hir().fn_decl_by_hir_id(hir_id).unwrap();
-    let opt_ret_ty = match fn_decl.output {
-        hir::FnRetTy::DefaultReturn(_) => None,
-        hir::FnRetTy::Return(ty) => Some(ty),
-    };
-
-    // Map late-bound regions from trait to impl, so the names are right.
-    let mapping = std::iter::zip(
-        tcx.fn_sig(trait_m.def_id).skip_binder().bound_vars(),
-        tcx.fn_sig(impl_m.def_id).skip_binder().bound_vars(),
-    )
-    .filter_map(|(impl_bv, trait_bv)| {
-        if let ty::BoundVariableKind::Region(impl_bv) = impl_bv
-            && let ty::BoundVariableKind::Region(trait_bv) = trait_bv
-        {
-            Some((impl_bv, trait_bv))
-        } else {
-            None
-        }
-    })
-    .collect();
-
-    // For each arg, see if it was in the "blame" of any of the region errors.
-    // If so, then try to produce a suggestion to replace the argument type with
-    // one from the trait.
-    let mut bad_args = vec![];
-    for (idx, (ty, hir_ty)) in
-        std::iter::zip(impl_sig.inputs_and_output, fn_decl.inputs.iter().chain(opt_ret_ty))
-            .enumerate()
-    {
-        let expected_ty = trait_sig.inputs_and_output[idx]
-            .fold_with(&mut RemapLateBound { tcx, mapping: &mapping });
-        if blame_generics.iter().any(|blame| ty.contains(*blame)) {
-            let expected_ty_sugg = expected_ty.to_string();
-            bad_args.push((
-                hir_ty.span,
-                // Only suggest something if it actually changed.
-                (expected_ty_sugg != ty.to_string()).then_some(expected_ty_sugg),
-            ));
-        }
-    }
-
-    bad_args
-}
-
 struct RemapLateBound<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>,
@@ -544,53 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
     }
 }
 
-fn emit_implied_wf_lint<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    impl_m: ty::AssocItem,
-    hir_id: hir::HirId,
-    bad_args: Vec<(Span, Option<String>)>,
-) {
-    let span: MultiSpan = if bad_args.is_empty() {
-        tcx.def_span(impl_m.def_id).into()
-    } else {
-        bad_args.iter().map(|(span, _)| *span).collect::<Vec<_>>().into()
-    };
-    tcx.struct_span_lint_hir(
-        rustc_session::lint::builtin::IMPLIED_BOUNDS_ENTAILMENT,
-        hir_id,
-        span,
-        "impl method assumes more implied bounds than the corresponding trait method",
-        |lint| {
-            let bad_args: Vec<_> =
-                bad_args.into_iter().filter_map(|(span, sugg)| Some((span, sugg?))).collect();
-            if !bad_args.is_empty() {
-                lint.multipart_suggestion(
-                    format!(
-                        "replace {} type{} to make the impl signature compatible",
-                        pluralize!("this", bad_args.len()),
-                        pluralize!(bad_args.len())
-                    ),
-                    bad_args,
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            lint
-        },
-    );
-}
-
-#[derive(Debug, PartialEq, Eq)]
-enum CheckImpliedWfMode {
-    /// Checks implied well-formedness of the impl method. If it fails, we will
-    /// re-check with `Skip`, and emit a lint if it succeeds.
-    Check,
-    /// Skips checking implied well-formedness of the impl method, but will emit
-    /// a lint if the `compare_method_predicate_entailment` succeeded. This means that
-    /// the reason that we had failed earlier during `Check` was due to the impl
-    /// having stronger requirements than the trait.
-    Skip,
-}
-
 fn compare_asyncness<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_m: ty::AssocItem,
@@ -1086,8 +908,14 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
             _ => return Ok(region),
         }
 
-        let e = if let Some(region) = self.map.get(&region) {
-            if let ty::ReEarlyParam(e) = region.kind() { e } else { bug!() }
+        let e = if let Some(id_region) = self.map.get(&region) {
+            if let ty::ReEarlyParam(e) = id_region.kind() {
+                e
+            } else {
+                bug!(
+                    "expected to map region {region} to early-bound identity region, but got {id_region}"
+                );
+            }
         } else {
             let guar = match region.kind() {
                 ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
@@ -1710,92 +1538,87 @@ fn compare_synthetic_generics<'tcx>(
                 trait_m.name
             );
             err.span_label(trait_span, "declaration in trait here");
-            match (impl_synthetic, trait_synthetic) {
+            if impl_synthetic {
                 // The case where the impl method uses `impl Trait` but the trait method uses
                 // explicit generics
-                (true, false) => {
-                    err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
-                    let _: Option<_> = try {
-                        // try taking the name from the trait impl
-                        // FIXME: this is obviously suboptimal since the name can already be used
-                        // as another generic argument
-                        let new_name = tcx.opt_item_name(trait_def_id)?;
-                        let trait_m = trait_m.def_id.as_local()?;
-                        let trait_m = tcx.hir().expect_trait_item(trait_m);
-
-                        let impl_m = impl_m.def_id.as_local()?;
-                        let impl_m = tcx.hir().expect_impl_item(impl_m);
-
-                        // in case there are no generics, take the spot between the function name
-                        // and the opening paren of the argument list
-                        let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
-                        // in case there are generics, just replace them
-                        let generics_span =
-                            impl_m.generics.span.substitute_dummy(new_generics_span);
-                        // replace with the generics from the trait
-                        let new_generics =
-                            tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?;
-
-                        err.multipart_suggestion(
-                            "try changing the `impl Trait` argument to a generic parameter",
-                            vec![
-                                // replace `impl Trait` with `T`
-                                (impl_span, new_name.to_string()),
-                                // replace impl method generics with trait method generics
-                                // This isn't quite right, as users might have changed the names
-                                // of the generics, but it works for the common case
-                                (generics_span, new_generics),
-                            ],
-                            Applicability::MaybeIncorrect,
-                        );
-                    };
-                }
+                err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
+                let _: Option<_> = try {
+                    // try taking the name from the trait impl
+                    // FIXME: this is obviously suboptimal since the name can already be used
+                    // as another generic argument
+                    let new_name = tcx.opt_item_name(trait_def_id)?;
+                    let trait_m = trait_m.def_id.as_local()?;
+                    let trait_m = tcx.hir().expect_trait_item(trait_m);
+
+                    let impl_m = impl_m.def_id.as_local()?;
+                    let impl_m = tcx.hir().expect_impl_item(impl_m);
+
+                    // in case there are no generics, take the spot between the function name
+                    // and the opening paren of the argument list
+                    let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
+                    // in case there are generics, just replace them
+                    let generics_span = impl_m.generics.span.substitute_dummy(new_generics_span);
+                    // replace with the generics from the trait
+                    let new_generics =
+                        tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?;
+
+                    err.multipart_suggestion(
+                        "try changing the `impl Trait` argument to a generic parameter",
+                        vec![
+                            // replace `impl Trait` with `T`
+                            (impl_span, new_name.to_string()),
+                            // replace impl method generics with trait method generics
+                            // This isn't quite right, as users might have changed the names
+                            // of the generics, but it works for the common case
+                            (generics_span, new_generics),
+                        ],
+                        Applicability::MaybeIncorrect,
+                    );
+                };
+            } else {
                 // The case where the trait method uses `impl Trait`, but the impl method uses
                 // explicit generics.
-                (false, true) => {
-                    err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
-                    let _: Option<_> = try {
-                        let impl_m = impl_m.def_id.as_local()?;
-                        let impl_m = tcx.hir().expect_impl_item(impl_m);
-                        let (sig, _) = impl_m.expect_fn();
-                        let input_tys = sig.decl.inputs;
-
-                        struct Visitor(Option<Span>, hir::def_id::LocalDefId);
-                        impl<'v> intravisit::Visitor<'v> for Visitor {
-                            fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
-                                intravisit::walk_ty(self, ty);
-                                if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
-                                    && let Res::Def(DefKind::TyParam, def_id) = path.res
-                                    && def_id == self.1.to_def_id()
-                                {
-                                    self.0 = Some(ty.span);
-                                }
+                err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
+                let _: Option<_> = try {
+                    let impl_m = impl_m.def_id.as_local()?;
+                    let impl_m = tcx.hir().expect_impl_item(impl_m);
+                    let (sig, _) = impl_m.expect_fn();
+                    let input_tys = sig.decl.inputs;
+
+                    struct Visitor(Option<Span>, hir::def_id::LocalDefId);
+                    impl<'v> intravisit::Visitor<'v> for Visitor {
+                        fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
+                            intravisit::walk_ty(self, ty);
+                            if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
+                                && let Res::Def(DefKind::TyParam, def_id) = path.res
+                                && def_id == self.1.to_def_id()
+                            {
+                                self.0 = Some(ty.span);
                             }
                         }
+                    }
 
-                        let mut visitor = Visitor(None, impl_def_id);
-                        for ty in input_tys {
-                            intravisit::Visitor::visit_ty(&mut visitor, ty);
-                        }
-                        let span = visitor.0?;
-
-                        let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
-                        let bounds = bounds.first()?.span().to(bounds.last()?.span());
-                        let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?;
-
-                        err.multipart_suggestion(
-                            "try removing the generic parameter and using `impl Trait` instead",
-                            vec![
-                                // delete generic parameters
-                                (impl_m.generics.span, String::new()),
-                                // replace param usage with `impl Trait`
-                                (span, format!("impl {bounds}")),
-                            ],
-                            Applicability::MaybeIncorrect,
-                        );
-                    };
-                }
-                _ => unreachable!(),
+                    let mut visitor = Visitor(None, impl_def_id);
+                    for ty in input_tys {
+                        intravisit::Visitor::visit_ty(&mut visitor, ty);
+                    }
+                    let span = visitor.0?;
+
+                    let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
+                    let bounds = bounds.first()?.span().to(bounds.last()?.span());
+                    let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?;
+
+                    err.multipart_suggestion(
+                        "try removing the generic parameter and using `impl Trait` instead",
+                        vec![
+                            // delete generic parameters
+                            (impl_m.generics.span, String::new()),
+                            // replace param usage with `impl Trait`
+                            (span, format!("impl {bounds}")),
+                        ],
+                        Applicability::MaybeIncorrect,
+                    );
+                };
             }
             error_found = Some(err.emit_unless(delay));
         }
@@ -1859,7 +1682,9 @@ fn compare_generic_param_kinds<'tcx>(
             // this is exhaustive so that anyone adding new generic param kinds knows
             // to make sure this error is reported for them.
             (Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false,
-            (Lifetime { .. }, _) | (_, Lifetime { .. }) => unreachable!(),
+            (Lifetime { .. }, _) | (_, Lifetime { .. }) => {
+                bug!("lifetime params are expected to be filtered by `ty_const_params_of`")
+            }
         } {
             let param_impl_span = tcx.def_span(param_impl.def_id);
             let param_trait_span = tcx.def_span(param_trait.def_id);
@@ -1883,7 +1708,10 @@ fn compare_generic_param_kinds<'tcx>(
                     )
                 }
                 Type { .. } => format!("{prefix} type parameter"),
-                Lifetime { .. } => unreachable!(),
+                Lifetime { .. } => span_bug!(
+                    tcx.def_span(param.def_id),
+                    "lifetime params are expected to be filtered by `ty_const_params_of`"
+                ),
             };
 
             let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap();
@@ -2181,13 +2009,16 @@ pub(super) fn check_type_bounds<'tcx>(
     let impl_ty_span = if impl_ty.is_impl_trait_in_trait() {
         tcx.def_span(impl_ty_def_id)
     } else {
-        match tcx.hir().get_by_def_id(impl_ty_def_id) {
+        match tcx.hir_node_by_def_id(impl_ty_def_id) {
             hir::Node::TraitItem(hir::TraitItem {
                 kind: hir::TraitItemKind::Type(_, Some(ty)),
                 ..
             }) => ty.span,
             hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span,
-            _ => bug!(),
+            item => span_bug!(
+                tcx.def_span(impl_ty_def_id),
+                "cannot call `check_type_bounds` on item: {item:?}",
+            ),
         }
     };
     let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl_ty_def_id)?;
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index 86c38480d57..67796855ece 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -262,7 +262,10 @@ fn report_mismatched_rpitit_signature<'tcx>(
 
     if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
         let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {
-            bug!();
+            span_bug!(
+                tcx.def_span(trait_m_def_id),
+                "expected return type of async fn in trait to be a AFIT projection"
+            );
         };
         let Some(future_output_ty) = tcx
             .explicit_item_bounds(future_ty.def_id)
@@ -272,13 +275,13 @@ fn report_mismatched_rpitit_signature<'tcx>(
                 _ => None,
             })
         else {
-            bug!()
+            span_bug!(tcx.def_span(trait_m_def_id), "expected `Future` projection bound in AFIT");
         };
         return_ty = future_output_ty;
     }
 
     let (span, impl_return_span, pre, post) =
-        match tcx.hir().get_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output {
+        match tcx.hir_node_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output {
             hir::FnRetTy::DefaultReturn(span) => (tcx.def_span(impl_m_def_id), span, "-> ", " "),
             hir::FnRetTy::Return(ty) => (ty.span, ty.span, "", ""),
         };
diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs
index 947e50d3161..8f194ae88ab 100644
--- a/compiler/rustc_hir_analysis/src/check/entry.rs
+++ b/compiler/rustc_hir_analysis/src/check/entry.rs
@@ -43,7 +43,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
             return None;
         }
         let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
-        match tcx.hir().find(hir_id) {
+        match tcx.opt_hir_node(hir_id) {
             Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
                 generics.params.is_empty().not().then_some(generics.span)
             }
@@ -58,7 +58,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
             return None;
         }
         let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
-        match tcx.hir().find(hir_id) {
+        match tcx.opt_hir_node(hir_id) {
             Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
                 Some(generics.where_clause_span)
             }
@@ -80,7 +80,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
             return None;
         }
         let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
-        match tcx.hir().find(hir_id) {
+        match tcx.opt_hir_node(hir_id) {
             Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
                 Some(fn_sig.decl.output.span())
             }
@@ -199,7 +199,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
     let start_t = tcx.type_of(start_def_id).instantiate_identity();
     match start_t.kind() {
         ty::FnDef(..) => {
-            if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
+            if let Some(Node::Item(it)) = tcx.opt_hir_node(start_id) {
                 if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
                     let mut error = false;
                     if !generics.params.is_empty() {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 2428fe6ae79..d86ebc2c9c3 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -49,7 +49,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             16 => InlineAsmType::I16,
             32 => InlineAsmType::I32,
             64 => InlineAsmType::I64,
-            _ => unreachable!(),
+            width => bug!("unsupported pointer width: {width}"),
         };
 
         match *ty.kind() {
@@ -101,7 +101,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                             16 => InlineAsmType::VecI16(size),
                             32 => InlineAsmType::VecI32(size),
                             64 => InlineAsmType::VecI64(size),
-                            _ => unreachable!(),
+                            width => bug!("unsupported pointer width: {width}"),
                         })
                     }
                     ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
@@ -109,7 +109,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                     _ => None,
                 }
             }
-            ty::Infer(_) => unreachable!(),
+            ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
             _ => None,
         }
     }
@@ -136,8 +136,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => {
                 let fields = &adt.non_enum_variant().fields;
                 let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args);
-                let ty::Adt(ty, args) = ty.kind() else { unreachable!() };
-                assert!(ty.is_manually_drop());
+                // FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?
+                // If so, just get it from the args.
+                let ty::Adt(ty, args) = ty.kind() else {
+                    unreachable!("expected first field of `MaybeUninit` to be an ADT")
+                };
+                assert!(
+                    ty.is_manually_drop(),
+                    "expected first field of `MaybeUnit` to be `ManuallyDrop`"
+                );
                 let fields = &ty.non_enum_variant().fields;
                 let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
                 self.get_asm_ty(ty)
@@ -269,7 +276,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                         lint.help(format!(
                             "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
                         ));
-                        lint
                     },
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index d08a8305105..df17879a967 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -130,7 +130,7 @@ fn get_owner_return_paths(
 ) -> Option<(LocalDefId, ReturnsVisitor<'_>)> {
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
     let parent_id = tcx.hir().get_parent_item(hir_id).def_id;
-    tcx.hir().find_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
+    tcx.opt_hir_node_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
         let body = tcx.hir().body(body_id);
         let mut visitor = ReturnsVisitor::default();
         visitor.visit_body(body);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3e805ab00b9..64026cdfff4 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -204,11 +204,14 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
                 res = Err(err.emit());
             }
             // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
-            match (tcx.impl_polarity(def_id), impl_.polarity) {
-                (ty::ImplPolarity::Positive, _) => {
+            match tcx.impl_polarity(def_id) {
+                ty::ImplPolarity::Positive => {
                     res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
                 }
-                (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
+                ty::ImplPolarity::Negative => {
+                    let ast::ImplPolarity::Negative(span) = impl_.polarity else {
+                        bug!("impl_polarity query disagrees with impl's polarity in AST");
+                    };
                     // FIXME(#27579): what amount of WF checking do we need for neg impls?
                     if let hir::Defaultness::Default { .. } = impl_.defaultness {
                         let mut spans = vec![span];
@@ -222,10 +225,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
                         .emit());
                     }
                 }
-                (ty::ImplPolarity::Reservation, _) => {
+                ty::ImplPolarity::Reservation => {
                     // FIXME: what amount of WF checking do we need for reservation impls?
                 }
-                _ => unreachable!(),
             }
             res
         }
@@ -793,7 +795,7 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
 /// When this is done, suggest using `Self` instead.
 fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
     let (trait_name, trait_def_id) =
-        match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
+        match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
             hir::Node::Item(item) => match item.kind {
                 hir::ItemKind::Trait(..) => (item.ident, item.owner_id),
                 _ => return,
@@ -992,15 +994,6 @@ fn check_associated_item(
     })
 }
 
-fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> {
-    match kind {
-        ItemKind::Struct(..) => Some(AdtKind::Struct),
-        ItemKind::Union(..) => Some(AdtKind::Union),
-        ItemKind::Enum(..) => Some(AdtKind::Enum),
-        _ => None,
-    }
-}
-
 /// In a type definition, we check that to ensure that the types of the fields are well-formed.
 fn check_type_defn<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -1019,7 +1012,7 @@ fn check_type_defn<'tcx>(
             for field in &variant.fields {
                 let field_id = field.did.expect_local();
                 let hir::FieldDef { ty: hir_ty, .. } =
-                    tcx.hir().get_by_def_id(field_id).expect_field();
+                    tcx.hir_node_by_def_id(field_id).expect_field();
                 let ty = wfcx.normalize(
                     hir_ty.span,
                     None,
@@ -1057,7 +1050,7 @@ fn check_type_defn<'tcx>(
                 let last = idx == variant.fields.len() - 1;
                 let field_id = field.did.expect_local();
                 let hir::FieldDef { ty: hir_ty, .. } =
-                    tcx.hir().get_by_def_id(field_id).expect_field();
+                    tcx.hir_node_by_def_id(field_id).expect_field();
                 let ty = wfcx.normalize(
                     hir_ty.span,
                     None,
@@ -1068,9 +1061,14 @@ fn check_type_defn<'tcx>(
                         hir_ty.span,
                         wfcx.body_def_id,
                         traits::FieldSized {
-                            adt_kind: match item_adt_kind(&item.kind) {
-                                Some(i) => i,
-                                None => bug!(),
+                            adt_kind: match &item.kind {
+                                ItemKind::Struct(..) => AdtKind::Struct,
+                                ItemKind::Union(..) => AdtKind::Union,
+                                ItemKind::Enum(..) => AdtKind::Enum,
+                                kind => span_bug!(
+                                    item.span,
+                                    "should be wfchecking an ADT, got {kind:?}"
+                                ),
                             },
                             span: hir_ty.span,
                             last,
@@ -1302,7 +1300,9 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
         | GenericParamDefKind::Const { has_default, .. } => {
             has_default && def.index >= generics.parent_count as u32
         }
-        GenericParamDefKind::Lifetime => unreachable!(),
+        GenericParamDefKind::Lifetime => {
+            span_bug!(tcx.def_span(def.def_id), "lifetime params can have no default")
+        }
     };
 
     // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
@@ -1750,15 +1750,15 @@ fn check_variances_for_type_defn<'tcx>(
             }
         }
         ItemKind::TyAlias(..) => {
-            if tcx.type_alias_is_lazy(item.owner_id) {
-                if tcx.type_of(item.owner_id).skip_binder().references_error() {
-                    return;
-                }
-            } else {
-                bug!();
+            assert!(
+                tcx.type_alias_is_lazy(item.owner_id),
+                "should not be computing variance of non-weak type alias"
+            );
+            if tcx.type_of(item.owner_id).skip_binder().references_error() {
+                return;
             }
         }
-        _ => bug!(),
+        kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"),
     }
 
     let ty_predicates = tcx.predicates_of(item.owner_id);
@@ -1882,7 +1882,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
             // Match the existing behavior.
             if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) {
                 let pred = self.normalize(span, None, pred);
-                let hir_node = tcx.hir().find_by_def_id(self.body_def_id);
+                let hir_node = tcx.opt_hir_node_by_def_id(self.body_def_id);
 
                 // only use the span of the predicate clause (#90869)
 
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index 9ad73eeffc6..36cb8f7a202 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -45,7 +45,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
             item.hir_id(),
             path.span,
             msg,
-            |lint| lint,
+            |_| {},
         );
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 45100457629..88128d22a3d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -522,7 +522,7 @@ fn lint_auto_trait_impl<'tcx>(
                 format!(
                     "try using the same sequence of generic parameters as the {self_descr} definition",
                 ),
-            )
+            );
         },
     );
 }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index ae35d6ebd75..d176665e4c0 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -221,7 +221,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>(
 
             // Check if parent is const or static
             let parent_id = tcx.hir().parent_id(hir_ty.hir_id);
-            let parent_node = tcx.hir().get(parent_id);
+            let parent_node = tcx.hir_node(parent_id);
 
             is_const_or_static = matches!(
                 parent_node,
@@ -354,7 +354,7 @@ impl<'tcx> ItemCtxt<'tcx> {
     }
 
     pub fn node(&self) -> hir::Node<'tcx> {
-        self.tcx.hir().get(self.hir_id())
+        self.tcx.hir_node(self.hir_id())
     }
 }
 
@@ -835,9 +835,8 @@ fn convert_variant(
 fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
     use rustc_hir::*;
 
-    let hir_id = tcx.local_def_id_to_hir_id(def_id);
-    let Node::Item(item) = tcx.hir().get(hir_id) else {
-        bug!();
+    let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else {
+        bug!("expected ADT to be an item");
     };
 
     let repr = tcx.repr_options_of_def(def_id.to_def_id());
@@ -888,7 +887,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
 
             (adt_kind, variants)
         }
-        _ => bug!(),
+        _ => bug!("{:?} is not an ADT", item.owner_id.def_id),
     };
     tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
 }
@@ -1105,7 +1104,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
 
     let icx = ItemCtxt::new(tcx, def_id);
 
-    let output = match tcx.hir().get(hir_id) {
+    let output = match tcx.hir_node(hir_id) {
         TraitItem(hir::TraitItem {
             kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
             generics,
@@ -1551,7 +1550,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
 }
 
 fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> {
-    match tcx.hir().get_by_def_id(def_id) {
+    match tcx.hir_node_by_def_id(def_id) {
         Node::Expr(&rustc_hir::Expr {
             kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }),
             ..
@@ -1561,7 +1560,7 @@ fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineK
 }
 
 fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
-    match tcx.hir().get_by_def_id(def_id) {
+    match tcx.hir_node_by_def_id(def_id) {
         Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
             matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
         }
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 114c5147e11..3ee2822edd8 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -16,7 +16,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
 
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
 
-    let node = tcx.hir().get(hir_id);
+    let node = tcx.hir_node(hir_id);
     let parent_def_id = match node {
         Node::ImplItem(_)
         | Node::TraitItem(_)
@@ -279,7 +279,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                             param.hir_id,
                             param.span,
                             TYPE_DEFAULT_NOT_ALLOWED,
-                            |lint| lint,
+                            |_| {},
                         );
                     }
                     Defaults::Deny => {
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 4d0fd2b691a..39ca1bba065 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -34,17 +34,14 @@ fn associated_type_bounds<'tcx>(
     let trait_def_id = tcx.local_parent(assoc_item_def_id);
     let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
 
-    let bounds_from_parent = trait_predicates
-        .predicates
-        .iter()
-        .copied()
-        .filter(|(pred, _)| match pred.kind().skip_binder() {
+    let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
+        match pred.kind().skip_binder() {
             ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty,
             ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty,
             ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty,
             _ => false,
-        })
-        .map(|(clause, span)| (clause, span));
+        }
+    });
 
     let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
     debug!(
@@ -86,7 +83,7 @@ pub(super) fn explicit_item_bounds(
         // RPITIT's bounds are the same as opaque type bounds, but with
         // a projection self type.
         Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
-            let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item();
+            let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
             let opaque_ty = item.expect_opaque_ty();
             return ty::EarlyBinder::bind(opaque_type_bounds(
                 tcx,
@@ -100,13 +97,14 @@ pub(super) fn explicit_item_bounds(
                 item.span,
             ));
         }
-        // These should have been fed!
-        Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(),
+        Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
+            tcx.def_span(def_id),
+            "item bounds for RPITIT in impl to be fed on def-id creation"
+        ),
         None => {}
     }
 
-    let hir_id = tcx.local_def_id_to_hir_id(def_id);
-    let bounds = match tcx.hir().get(hir_id) {
+    let bounds = match tcx.hir_node_by_def_id(def_id) {
         hir::Node::TraitItem(hir::TraitItem {
             kind: hir::TraitItemKind::Type(bounds, _),
             span,
@@ -132,7 +130,7 @@ pub(super) fn explicit_item_bounds(
             let (hir::OpaqueTyOrigin::FnReturn(fn_def_id)
             | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin
             else {
-                bug!()
+                span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}");
             };
             let args = GenericArgs::identity_for_item(tcx, def_id);
             let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index ca9443225e2..41520718aa8 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -135,7 +135,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     }
 
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
-    let node = tcx.hir().get(hir_id);
+    let node = tcx.hir_node(hir_id);
 
     let mut is_trait = None;
     let mut is_default_impl_trait = None;
@@ -296,7 +296,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                         hir::GenericBound::Outlives(lt) => {
                             (icx.astconv().ast_region_to_region(lt, None), lt.ident.span)
                         }
-                        _ => bug!(),
+                        bound => {
+                            span_bug!(
+                                bound.span(),
+                                "lifetime param bounds must be outlives, but found {bound:?}"
+                            )
+                        }
                     };
                     let pred = ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2))
                         .to_predicate(tcx);
@@ -337,7 +342,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     // and the duplicated parameter, to ensure that they do not get out of sync.
     if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
         let opaque_ty_id = tcx.hir().parent_id(hir_id);
-        let opaque_ty_node = tcx.hir().get(opaque_ty_id);
+        let opaque_ty_node = tcx.hir_node(opaque_ty_id);
         let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else {
             bug!("unexpected {opaque_ty_node:?}")
         };
@@ -413,7 +418,7 @@ fn const_evaluatable_predicates_of(
     }
 
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
-    let node = tcx.hir().get(hir_id);
+    let node = tcx.hir_node(hir_id);
 
     let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
     if let hir::Node::Item(item) = node
@@ -633,7 +638,7 @@ pub(super) fn implied_predicates_with_filter(
 
     let trait_hir_id = tcx.local_def_id_to_hir_id(trait_def_id);
 
-    let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
+    let Node::Item(item) = tcx.hir_node(trait_hir_id) else {
         bug!("trait_node_id {} is not an item", trait_hir_id);
     };
 
@@ -713,7 +718,7 @@ pub(super) fn type_param_predicates(
     let mut extend = None;
 
     let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
-    let ast_generics = match tcx.hir().get(item_hir_id) {
+    let ast_generics = match tcx.hir_node(item_hir_id) {
         Node::TraitItem(item) => item.generics,
 
         Node::ImplItem(item) => item.generics,
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 e939b7abd90..9f0742dade8 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -350,7 +350,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     // Nested poly trait refs have the binders concatenated
                     let mut full_binders =
                         self.map.late_bound_vars.entry(*hir_id).or_default().clone();
-                    full_binders.extend(supertrait_bound_vars.into_iter());
+                    full_binders.extend(supertrait_bound_vars);
                     break (full_binders, BinderScopeType::Concatenating);
                 }
             }
@@ -748,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     }
                     if let hir::Node::Item(hir::Item {
                         kind: hir::ItemKind::OpaqueTy { .. }, ..
-                    }) = self.tcx.hir().get(parent_id)
+                    }) = self.tcx.hir_node(parent_id)
                     {
                         let mut err = self.tcx.sess.struct_span_err(
                             lifetime.ident.span,
@@ -925,7 +925,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                                     "you can use the `'static` lifetime directly, in place of `{}`",
                                     lifetime.ident,
                                 );
-                                lint.help(help)
+                                lint.help(help);
                             },
                         );
                     }
@@ -938,32 +938,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
         }
     }
 
-    fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) {
-        match bound {
-            hir::GenericBound::LangItemTrait(_, _, hir_id, _) => {
-                // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
-                // through the regular poly trait ref code, so we don't get another
-                // chance to introduce a binder. For now, I'm keeping the existing logic
-                // of "if there isn't a Binder scope above us, add one", but I
-                // imagine there's a better way to go about this.
-                let (binders, scope_type) = self.poly_trait_ref_binder_info();
-
-                self.record_late_bound_vars(*hir_id, binders);
-                let scope = Scope::Binder {
-                    hir_id: *hir_id,
-                    bound_vars: FxIndexMap::default(),
-                    s: self.scope,
-                    scope_type,
-                    where_bound_origin: None,
-                };
-                self.with(scope, |this| {
-                    intravisit::walk_param_bound(this, bound);
-                });
-            }
-            _ => intravisit::walk_param_bound(self, bound),
-        }
-    }
-
     fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
         self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow);
     }
@@ -1004,7 +978,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
 fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectLifetimeDefault {
     debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
-    let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(param_def_id) else {
+    let hir::Node::GenericParam(param) = tcx.hir_node_by_def_id(param_def_id) else {
         bug!("expected GenericParam for object_lifetime_default");
     };
     match param.source {
@@ -1300,12 +1274,16 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             what,
                         })
                     }
-                    _ => unreachable!(),
+                    kind => span_bug!(
+                        use_span,
+                        "did not expect to resolve lifetime to {}",
+                        kind.descr(param_def_id)
+                    ),
                 };
                 def = ResolvedArg::Error(guar);
             } else if let Some(body_id) = outermost_body {
                 let fn_id = self.tcx.hir().body_owner(body_id);
-                match self.tcx.hir().get(fn_id) {
+                match self.tcx.hir_node(fn_id) {
                     Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn(..), .. })
                     | Node::TraitItem(hir::TraitItem {
                         owner_id,
@@ -1441,7 +1419,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             what,
                         })
                     }
-                    _ => unreachable!(),
+                    kind => span_bug!(
+                        use_span,
+                        "did not expect to resolve non-lifetime param to {}",
+                        kind.descr(param_def_id.to_def_id())
+                    ),
                 };
                 self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
             } else {
@@ -2122,8 +2104,8 @@ pub fn deny_non_region_late_bound(
     let mut first = true;
 
     for (var, arg) in bound_vars {
-        let Node::GenericParam(param) = tcx.hir().get_by_def_id(*var) else {
-            bug!();
+        let Node::GenericParam(param) = tcx.hir_node_by_def_id(*var) else {
+            span_bug!(tcx.def_span(*var), "expected bound-var def-id to resolve to param");
         };
 
         let what = match param.kind {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index c4fc4dda069..174217d3b70 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -20,10 +20,16 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
     use rustc_middle::ty::Ty;
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
 
-    let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() };
+    let node = tcx.hir_node(hir_id);
+    let Node::AnonConst(_) = node else {
+        span_bug!(
+            tcx.def_span(def_id),
+            "expected anon const in `anon_const_type_of`, got {node:?}"
+        );
+    };
 
     let parent_node_id = tcx.hir().parent_id(hir_id);
-    let parent_node = tcx.hir().get(parent_node_id);
+    let parent_node = tcx.hir_node(parent_node_id);
 
     let (generics, arg_idx) = match parent_node {
         // Easy case: arrays repeat expressions.
@@ -61,7 +67,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
         }
 
         Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
-            if let Node::TraitRef(trait_ref) = tcx.hir().get(tcx.hir().parent_id(binding_id)) =>
+            if let Node::TraitRef(trait_ref) = tcx.hir_node(tcx.hir().parent_id(binding_id)) =>
         {
             let Some(trait_def_id) = trait_ref.trait_def_id() else {
                 return Ty::new_error_with_message(
@@ -354,7 +360,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
 
     let icx = ItemCtxt::new(tcx, def_id);
 
-    let output = match tcx.hir().get(hir_id) {
+    let output = match tcx.hir_node(hir_id) {
         Node::TraitItem(item) => match item.kind {
             TraitItemKind::Fn(..) => {
                 let args = ty::GenericArgs::identity_for_item(tcx, def_id);
@@ -517,8 +523,7 @@ pub(super) fn type_of_opaque(
     if let Some(def_id) = def_id.as_local() {
         use rustc_hir::*;
 
-        let hir_id = tcx.local_def_id_to_hir_id(def_id);
-        Ok(ty::EarlyBinder::bind(match tcx.hir().get(hir_id) {
+        Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
             Node::Item(item) => match item.kind {
                 ItemKind::OpaqueTy(OpaqueTy {
                     origin: hir::OpaqueTyOrigin::TyAlias { .. },
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index f11a953536d..bf0d9d4856a 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -50,8 +50,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
     if scope == hir::CRATE_HIR_ID {
         tcx.hir().walk_toplevel_module(&mut locator);
     } else {
-        trace!("scope={:#?}", tcx.hir().get(scope));
-        match tcx.hir().get(scope) {
+        trace!("scope={:#?}", tcx.hir_node(scope));
+        match tcx.hir_node(scope) {
             // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
             // This allows our visitor to process the defining item itself, causing
             // it to pick up any 'sibling' defining uses.
@@ -95,7 +95,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
         let reported = tcx.sess.emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_name(parent_def_id.to_def_id()),
-            what: match tcx.hir().get(scope) {
+            what: match tcx.hir_node(scope) {
                 _ if scope == hir::CRATE_HIR_ID => "module",
                 Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
                 Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
@@ -282,7 +282,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
         debug!(?scope);
         let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
 
-        match tcx.hir().get(scope) {
+        match tcx.hir_node(scope) {
             Node::Item(it) => intravisit::walk_item(&mut locator, it),
             Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it),
             Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it),
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index 4ed1377e7fc..78745fe47ab 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -122,7 +122,7 @@ fn diagnostic_hir_wf_check<'tcx>(
     // We will walk 'into' this type to try to find
     // a more precise span for our predicate.
     let tys = match loc {
-        WellFormedLoc::Ty(_) => match hir.get(hir_id) {
+        WellFormedLoc::Ty(_) => match tcx.hir_node(hir_id) {
             hir::Node::ImplItem(item) => match item.kind {
                 hir::ImplItemKind::Type(ty) => vec![ty],
                 hir::ImplItemKind::Const(ty, _) => vec![ty],
diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs
index c065f6e7e88..9541e510702 100644
--- a/compiler/rustc_hir_analysis/src/outlives/mod.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs
@@ -41,7 +41,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
         }
     }
 
-    match tcx.hir().get(id) {
+    match tcx.hir_node(id) {
         Node::Item(item) => match item.kind {
             hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
                 let crate_map = tcx.inferred_outlives_crate(());
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 76bd370a641..fab841e3679 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -137,10 +137,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             // is from the 'of_trait' field of the enclosing impl
 
             let parent = self.tcx.hir().get_parent(self.path_segment.hir_id);
-            let parent_item = self
-                .tcx
-                .hir()
-                .get_by_def_id(self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id);
+            let parent_item = self.tcx.hir_node_by_def_id(
+                self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id,
+            );
 
             // Get the HIR id of the trait ref
             let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else {
@@ -774,7 +773,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
         );
 
         if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
-            && let Some(parent_node) = self.tcx.hir().find(parent_node)
+            && let Some(parent_node) = self.tcx.opt_hir_node(parent_node)
             && let hir::Node::Expr(expr) = parent_node
         {
             match &expr.kind {
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 8701626058d..21a50b94a37 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2003,18 +2003,14 @@ impl<'a> State<'a> {
         });
         self.word("|");
 
-        if let hir::FnRetTy::DefaultReturn(..) = decl.output {
-            return;
-        }
-
-        self.space_if_not_bol();
-        self.word_space("->");
         match decl.output {
             hir::FnRetTy::Return(ty) => {
+                self.space_if_not_bol();
+                self.word_space("->");
                 self.print_type(ty);
                 self.maybe_print_comment(ty.span.lo());
             }
-            hir::FnRetTy::DefaultReturn(..) => unreachable!(),
+            hir::FnRetTy::DefaultReturn(..) => {}
         }
     }
 
@@ -2088,11 +2084,6 @@ impl<'a> State<'a> {
                     }
                     self.print_poly_trait_ref(tref);
                 }
-                GenericBound::LangItemTrait(lang_item, span, ..) => {
-                    self.word("#[lang = \"");
-                    self.print_ident(Ident::new(lang_item.name(), *span));
-                    self.word("\"]");
-                }
                 GenericBound::Outlives(lt) => {
                     self.print_lifetime(lt);
                 }
@@ -2179,7 +2170,7 @@ impl<'a> State<'a> {
                             GenericBound::Outlives(lt) => {
                                 self.print_lifetime(lt);
                             }
-                            _ => panic!(),
+                            _ => panic!("unexpected bound on lifetime param: {bound:?}"),
                         }
 
                         if i != 0 {
@@ -2216,16 +2207,14 @@ impl<'a> State<'a> {
     }
 
     fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) {
-        if let hir::FnRetTy::DefaultReturn(..) = decl.output {
-            return;
-        }
-
-        self.space_if_not_bol();
-        self.ibox(INDENT_UNIT);
-        self.word_space("->");
         match decl.output {
-            hir::FnRetTy::DefaultReturn(..) => unreachable!(),
-            hir::FnRetTy::Return(ty) => self.print_type(ty),
+            hir::FnRetTy::Return(ty) => {
+                self.space_if_not_bol();
+                self.ibox(INDENT_UNIT);
+                self.word_space("->");
+                self.print_type(ty);
+            }
+            hir::FnRetTy::DefaultReturn(..) => return,
         }
         self.end();
 
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index e7cbbc71335..181de372840 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -238,8 +238,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         // Next, make sure that we have no type expectation.
-        let Some(ret) = hir
-            .find_by_def_id(self.body_id)
+        let Some(ret) = self
+            .tcx
+            .opt_hir_node_by_def_id(self.body_id)
             .and_then(|owner| owner.fn_decl())
             .map(|decl| decl.output.span())
         else {
@@ -317,7 +318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         hir_id: hir::HirId,
         sp: Span,
     ) -> Option<(Span, String)> {
-        let node = self.tcx.hir().get(hir_id);
+        let node = self.tcx.hir_node(hir_id);
         if let hir::Node::Block(block) = node {
             // check that the body's parent is an fn
             let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id));
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 512946cc504..baca2be06e6 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -295,7 +295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let hir = self.tcx.hir();
         let parent_hir_id = hir.parent_id(hir_id);
-        let parent_node = hir.get(parent_hir_id);
+        let parent_node = self.tcx.hir_node(parent_hir_id);
         if let (
             hir::Node::Expr(hir::Expr {
                 kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, body, .. }),
@@ -313,7 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let hir::Node::Expr(hir::Expr {
                     kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
                     ..
-                }) = hir.get(async_closure)
+                }) = self.tcx.hir_node(async_closure)
                 {
                     fn_decl_span
                 } else {
@@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         callee_expr: &'tcx hir::Expr<'tcx>,
     ) -> bool {
         let hir_id = self.tcx.hir().parent_id(call_expr.hir_id);
-        let parent_node = self.tcx.hir().get(hir_id);
+        let parent_node = self.tcx.hir_node(hir_id);
         if let (
             hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }),
             hir::ExprKind::Tup(exp),
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index d89af297560..0de0365364c 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -149,7 +149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub enum CastError {
     ErrorGuaranteed(ErrorGuaranteed),
 
@@ -271,7 +271,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                         match e {
                             CastError::NeedViaPtr => "a raw pointer",
                             CastError::NeedViaThinPtr => "a thin pointer",
-                            _ => bug!(),
+                            e => unreachable!("control flow means we should never encounter a {e:?}"),
                         }
                     ));
                 }
@@ -288,13 +288,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     self.cast_ty,
                     fcx,
                 )
-                .help(format!(
-                    "cast through {} first",
-                    match e {
-                        CastError::NeedViaInt => "an integer",
-                        _ => bug!(),
-                    }
-                ))
+                .help("cast through an integer first")
                 .emit();
             }
             CastError::IllegalCast => {
@@ -534,7 +528,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 let unknown_cast_to = match e {
                     CastError::UnknownCastPtrKind => true,
                     CastError::UnknownExprPtrKind => false,
-                    _ => bug!(),
+                    e => unreachable!("control flow means we should never encounter a {e:?}"),
                 };
                 let (span, sub) = if unknown_cast_to {
                     (self.cast_span, errors::CastUnknownPointerSub::To(self.cast_span))
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index f0bb18df48c..7e43d67587b 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -141,7 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         debug!(?sig, ?opt_kind);
 
         let closure_kind_ty = match opt_kind {
-            Some(kind) => kind.to_ty(self.tcx),
+            Some(kind) => Ty::from_closure_kind(self.tcx, kind),
 
             // Create a type variable (for now) to represent the closure kind.
             // It will be unified during the upvar inference phase (`upvar.rs`)
@@ -483,8 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         body: &hir::Body<'_>,
         expected_sig: ExpectedSig<'tcx>,
     ) -> ClosureSignatures<'tcx> {
-        let hir = self.tcx.hir();
-        let expr_map_node = hir.get_by_def_id(expr_def_id);
+        let expr_map_node = self.tcx.hir_node_by_def_id(expr_def_id);
         let expected_args: Vec<_> = expected_sig
             .sig
             .skip_binder()
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 0d3bb0f7e0c..61236c07135 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1019,7 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Returns false if the coercion creates any obligations that result in
     /// errors.
     pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
-        // FIXME(-Ztrait-solver=next): We need to structurally resolve both types here.
+        // FIXME(-Znext-solver): We need to structurally resolve both types here.
         let source = self.resolve_vars_with_obligations(expr_ty);
         debug!("coercion::can_with_predicates({:?} -> {:?})", source, target);
 
@@ -1182,14 +1182,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     Adjust::Pointer(PointerCoercion::ClosureFnPointer(a_sig.unsafety()))
                 }
                 ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer),
-                _ => unreachable!(),
+                _ => span_bug!(cause.span, "should not try to coerce a {prev_ty} to a fn pointer"),
             };
             let next_adjustment = match new_ty.kind() {
                 ty::Closure(..) => {
                     Adjust::Pointer(PointerCoercion::ClosureFnPointer(b_sig.unsafety()))
                 }
                 ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer),
-                _ => unreachable!(),
+                _ => span_bug!(new.span, "should not try to coerce a {new_ty} to a fn pointer"),
             };
             for expr in exprs.iter().map(|e| e.as_coercion_site()) {
                 self.apply_adjustments(
@@ -1694,14 +1694,14 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         let ret_msg = "return a value for the case when the loop has zero elements to iterate on";
         let ret_ty_msg =
             "otherwise consider changing the return type to account for that possibility";
-        if let Some(node) = hir.find(item.into())
+        if let Some(node) = tcx.opt_hir_node(item.into())
             && let Some(body_id) = node.body_id()
             && let Some(sig) = node.fn_sig()
             && let hir::ExprKind::Block(block, _) = hir.body(body_id).value.kind
             && !ty.is_never()
         {
             let indentation = if let None = block.expr
-                && let [.., last] = &block.stmts[..]
+                && let [.., last] = &block.stmts
             {
                 tcx.sess.source_map().indentation_before(last.span).unwrap_or_else(String::new)
             } else if let Some(expr) = block.expr {
@@ -1710,7 +1710,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 String::new()
             };
             if let None = block.expr
-                && let [.., last] = &block.stmts[..]
+                && let [.., last] = &block.stmts
             {
                 err.span_suggestion_verbose(
                     last.span.shrink_to_hi(),
@@ -1750,7 +1750,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 }
             }
             if let None = block.expr
-                && let [.., last] = &block.stmts[..]
+                && let [.., last] = &block.stmts
             {
                 sugg.push((last.span.shrink_to_hi(), format!("\n{indentation}None")));
             } else if let Some(expr) = block.expr {
@@ -1776,7 +1776,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
 
         let parent_id = fcx.tcx.hir().parent_id(id);
-        let parent = fcx.tcx.hir().get(parent_id);
+        let parent = fcx.tcx.hir_node(parent_id);
         if let Some(expr) = expression
             && let hir::Node::Expr(hir::Expr {
                 kind: hir::ExprKind::Closure(&hir::Closure { body, .. }),
@@ -1835,7 +1835,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         }
 
         let parent_id = fcx.tcx.hir().get_parent_item(id);
-        let parent_item = fcx.tcx.hir().get_by_def_id(parent_id.def_id);
+        let parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
 
         if let (Some(expr), Some(_), Some((fn_id, fn_decl, _, _))) =
             (expression, blk_id, fcx.get_node_fn_decl(parent_item))
@@ -1918,7 +1918,7 @@ where
 
 impl AsCoercionSite for ! {
     fn as_coercion_site(&self) -> &hir::Expr<'_> {
-        unreachable!()
+        *self
     }
 }
 
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 8f633834885..8b666c63425 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -289,7 +289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let hir::def::Res::Local(local_hir_id) = p.res else {
             return false;
         };
-        let hir::Node::Pat(pat) = hir.get(local_hir_id) else {
+        let hir::Node::Pat(pat) = self.tcx.hir_node(local_hir_id) else {
             return false;
         };
         let (init_ty_hir_id, init) = match hir.get_parent(pat.hir_id) {
@@ -331,13 +331,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty_op: |ty| {
                 if let ty::Infer(infer) = ty.kind() {
                     match infer {
-                        ty::InferTy::TyVar(_) => self.next_ty_var(TypeVariableOrigin {
+                        ty::TyVar(_) => self.next_ty_var(TypeVariableOrigin {
                             kind: TypeVariableOriginKind::MiscVariable,
                             span: DUMMY_SP,
                         }),
-                        ty::InferTy::IntVar(_) => self.next_int_var(),
-                        ty::InferTy::FloatVar(_) => self.next_float_var(),
-                        _ => bug!(),
+                        ty::IntVar(_) => self.next_int_var(),
+                        ty::FloatVar(_) => self.next_float_var(),
+                        ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
+                            bug!("unexpected fresh ty outside of the trait solver")
+                        }
                     }
                 } else {
                     ty
@@ -557,7 +559,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
                 | hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
                 | hir::Node::Expr(&ref p),
-            ) = self.tcx.hir().find(parent_id)
+            ) = self.tcx.opt_hir_node(parent_id)
             else {
                 break;
             };
@@ -570,7 +572,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let mut direct = false;
             loop {
                 // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
-                let parent = match self.tcx.hir().find(parent_id) {
+                let parent = match self.tcx.opt_hir_node(parent_id) {
                     Some(hir::Node::Expr(&ref parent)) => {
                         parent_id = self.tcx.hir().parent_id(parent.hir_id);
                         parent
@@ -672,7 +674,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         error: Option<TypeError<'tcx>>,
     ) {
         let parent = self.tcx.hir().parent_id(expr.hir_id);
-        match (self.tcx.hir().find(parent), error) {
+        match (self.tcx.opt_hir_node(parent), error) {
             (Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })), _)
                 if init.hir_id == expr.hir_id =>
             {
@@ -717,7 +719,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         None,
                         hir::Path { res: hir::def::Res::Local(hir_id), .. },
                     )) => {
-                        if let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(*hir_id) {
+                        if let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id) {
                             primary_span = pat.span;
                             secondary_span = pat.span;
                             match self.tcx.hir().find_parent(pat.hir_id) {
@@ -790,7 +792,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         };
         let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. })) =
-            self.tcx.hir().find(parent)
+            self.tcx.opt_hir_node(parent)
         else {
             return;
         };
@@ -862,7 +864,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             mutability,
                         ),
                     ),
-                    match &args[..] {
+                    match &args {
                         [] => (base.span.shrink_to_hi().with_hi(deref.span.hi()), ")".to_string()),
                         [first, ..] => (base.span.between(first.span), ", ".to_string()),
                     },
@@ -1014,8 +1016,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
         )) = expr.kind
         {
-            let bind = self.tcx.hir().find(*bind_hir_id);
-            let parent = self.tcx.hir().find(self.tcx.hir().parent_id(*bind_hir_id));
+            let bind = self.tcx.opt_hir_node(*bind_hir_id);
+            let parent = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*bind_hir_id));
             if let Some(hir::Node::Pat(hir::Pat {
                 kind: hir::PatKind::Binding(_, _hir_id, _, _),
                 ..
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 74aec897f95..ff03cf16a27 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -573,13 +573,13 @@ impl rustc_errors::AddToDiagnostic for CastUnknownPointerSub {
     {
         match self {
             CastUnknownPointerSub::To(span) => {
-                let msg = f(diag, crate::fluent_generated::hir_typeck_label_to.into());
+                let msg = f(diag, crate::fluent_generated::hir_typeck_label_to);
                 diag.span_label(span, msg);
-                let msg = f(diag, crate::fluent_generated::hir_typeck_note.into());
+                let msg = f(diag, crate::fluent_generated::hir_typeck_note);
                 diag.note(msg);
             }
             CastUnknownPointerSub::From(span) => {
-                let msg = f(diag, crate::fluent_generated::hir_typeck_label_from.into());
+                let msg = f(diag, crate::fluent_generated::hir_typeck_label_from);
                 diag.span_label(span, msg);
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 7c157c0eae0..80265cf31e6 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -883,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             kind: hir::ImplItemKind::Fn(..),
             span: encl_fn_span,
             ..
-        })) = self.tcx.hir().find_by_def_id(encl_item_id.def_id)
+        })) = self.tcx.opt_hir_node_by_def_id(encl_item_id.def_id)
         {
             // We are inside a function body, so reporting "return statement
             // outside of function body" needs an explanation.
@@ -997,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         then: impl FnOnce(&hir::Expr<'_>),
     ) {
         let mut parent = self.tcx.hir().parent_id(original_expr_id);
-        while let Some(node) = self.tcx.hir().find(parent) {
+        while let Some(node) = self.tcx.opt_hir_node(parent) {
             match node {
                 hir::Node::Expr(hir::Expr {
                     kind:
@@ -2087,7 +2087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let names = names.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
                     format!("{} and `{last}` ", names.join(", "))
                 }
-                [] => unreachable!(),
+                [] => bug!("expected at least one private field to report"),
             };
             err.note(format!(
                 "{}private field{s} {names}that {were} not provided",
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index df840aaa578..3bee42eb89c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             orig_span,
                             custom_note
                                 .unwrap_or("any code following this expression is unreachable"),
-                        )
+                        );
                     },
                 )
             }
@@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// version (resolve_vars_if_possible), this version will
     /// also select obligations if it seems useful, in an effort
     /// to get more type information.
-    // FIXME(-Ztrait-solver=next): A lot of the calls to this method should
+    // FIXME(-Znext-solver): A lot of the calls to this method should
     // probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead.
     #[instrument(skip(self), level = "debug", ret)]
     pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
@@ -994,7 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
         // `while` before reaching it, as block tail returns are not available in them.
         self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
-            let parent = self.tcx.hir().get(blk_id);
+            let parent = self.tcx.hir_node(blk_id);
             self.get_node_fn_decl(parent)
                 .map(|(fn_id, fn_decl, _, is_main)| (fn_id, fn_decl, is_main))
         })
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index 9b5459529ff..76360239c45 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -94,7 +94,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let hir = self.tcx.hir();
-        let (expr, qpath) = match hir.get(hir_id) {
+        let (expr, qpath) = match self.tcx.hir_node(hir_id) {
             hir::Node::Expr(expr) => {
                 if self.closure_span_overlaps_error(error, expr.span) {
                     return false;
@@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .find_ancestor_in_same_ctxt(error.obligation.cause.span)
                 .unwrap_or(arg.span);
 
-            if let hir::Node::Expr(arg_expr) = self.tcx.hir().get(arg.hir_id) {
+            if let hir::Node::Expr(arg_expr) = self.tcx.hir_node(arg.hir_id) {
                 // This is more specific than pointing at the entire argument.
                 self.blame_specific_expr_if_possible(error, arg_expr)
             }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index bb9b849f03b..3f97b24aa59 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -993,7 +993,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }) {
                         match e {
                             Error::Missing(expected_idx) => missing_idxs.push(expected_idx),
-                            _ => unreachable!(),
+                            _ => unreachable!(
+                                "control flow ensures that we should always get an `Error::Missing`"
+                            ),
                         }
                     }
 
@@ -1734,7 +1736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
-        let node = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(id).def_id);
+        let node = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(id).def_id);
         match node {
             Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
             | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
@@ -1750,7 +1752,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
     fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
-        let parent = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id);
+        let parent = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id);
         self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident))
     }
 
@@ -2018,7 +2020,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let new_def_id = self.probe(|_| {
                         let trait_ref = ty::TraitRef::new(
                             self.tcx,
-                            call_kind.to_def_id(self.tcx),
+                            self.tcx.fn_trait_kind_to_def_id(call_kind)?,
                             [
                                 callee_ty,
                                 self.next_ty_var(TypeVariableOrigin {
@@ -2084,7 +2086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let node = self
                     .tcx
                     .opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id))
-                    .and_then(|hir_id| self.tcx.hir().find(hir_id));
+                    .and_then(|hir_id| self.tcx.opt_hir_node(hir_id));
                 match node {
                     Some(hir::Node::Item(item)) => call_finder.visit_item(item),
                     Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item),
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 2c9942caab2..668e547571f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -677,7 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // can suggest Box::pin.
                 let parent = self.tcx.hir().parent_id(expr.hir_id);
                 let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) =
-                    self.tcx.hir().find(parent)
+                    self.tcx.opt_hir_node(parent)
                 else {
                     return false;
                 };
@@ -824,10 +824,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
                     && let hir::Node::Item(hir::Item {
                         kind: hir::ItemKind::OpaqueTy(op_ty), ..
-                    }) = self.tcx.hir().get(item_id.hir_id())
-                    && let [
-                        hir::GenericBound::LangItemTrait(hir::LangItem::Future, _, _, generic_args),
-                    ] = op_ty.bounds
+                    }) = self.tcx.hir_node(item_id.hir_id())
+                    && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
+                    && let Some(hir::PathSegment { args: Some(generic_args), .. }) =
+                        trait_ref.trait_ref.path.segments.last()
                     && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
                     && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } =
                         ty_binding.kind
@@ -902,7 +902,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let ty::Param(expected_ty_as_param) = expected.kind() else { return };
 
-        let fn_node = self.tcx.hir().find(fn_id);
+        let fn_node = self.tcx.opt_hir_node(fn_id);
 
         let Some(hir::Node::Item(hir::Item {
             kind:
@@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
             let ty = self.normalize(expr.span, ty);
             if self.can_coerce(found, ty) {
-                if let Some(node) = self.tcx.hir().find(fn_id)
+                if let Some(node) = self.tcx.opt_hir_node(fn_id)
                     && let Some(owner_node) = node.as_owner()
                     && let Some(span) = expr.span.find_ancestor_inside(owner_node.span())
                 {
@@ -1545,12 +1545,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn is_loop(&self, id: hir::HirId) -> bool {
-        let node = self.tcx.hir().get(id);
+        let node = self.tcx.hir_node(id);
         matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. }))
     }
 
     fn is_local_statement(&self, id: hir::HirId) -> bool {
-        let node = self.tcx.hir().get(id);
+        let node = self.tcx.hir_node(id);
         matches!(node, Node::Stmt(Stmt { kind: StmtKind::Local(..), .. }))
     }
 
@@ -1677,11 +1677,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 None,
                 hir::Path { segments: [_], res: crate::Res::Local(binding), .. },
             )) => {
-                let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.hir().find(*binding)
+                let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.opt_hir_node(*binding)
                 else {
                     return expr;
                 };
-                let Some(parent) = self.tcx.hir().find(self.tcx.hir().parent_id(*hir_id)) else {
+                let Some(parent) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id)) else {
                     return expr;
                 };
 
@@ -1697,7 +1697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ..
                     }) => {
                         let Some(hir::Node::Local(hir::Local { init: Some(init), .. })) =
-                            self.tcx.hir().find(self.tcx.hir().parent_id(*pat_hir_id))
+                            self.tcx.opt_hir_node(self.tcx.hir().parent_id(*pat_hir_id))
                         else {
                             return expr;
                         };
@@ -1730,8 +1730,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     && let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } =
                         call_expr_path
                     && let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) =
-                        self.tcx.hir().find(*binding)
-                    && let Some(closure) = self.tcx.hir().find(self.tcx.hir().parent_id(*hir_id))
+                        self.tcx.opt_hir_node(*binding)
+                    && let Some(closure) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id))
                     && let hir::Node::Local(hir::Local { init: Some(init), .. }) = closure
                     && let Expr {
                         kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }),
@@ -1985,7 +1985,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 if let Some(hir::Node::Block(&hir::Block {
                     span: block_span, expr: Some(e), ..
-                })) = self.tcx.hir().find(parent)
+                })) = self.tcx.opt_hir_node(parent)
                 {
                     if e.hir_id == id {
                         if let Some(span) = expr.span.find_ancestor_inside(block_span) {
@@ -2072,8 +2072,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     Some(CtorKind::Fn) => ("(".to_owned(), ")"),
                     None => (format!(" {{ {field_name}: "), " }"),
 
-                    // unit variants don't have fields
-                    Some(CtorKind::Const) => unreachable!(),
+                    Some(CtorKind::Const) => unreachable!("unit variants don't have fields"),
                 };
 
                 // Suggest constructor as deep into the block tree as possible.
@@ -2211,7 +2210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let local_parent = self.tcx.hir().parent_id(local_id);
         let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) =
-            self.tcx.hir().find(local_parent)
+            self.tcx.opt_hir_node(local_parent)
         else {
             return None;
         };
@@ -2221,13 +2220,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             hir_id: expr_hir_id,
             kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }),
             ..
-        })) = self.tcx.hir().find(param_parent)
+        })) = self.tcx.opt_hir_node(param_parent)
         else {
             return None;
         };
 
         let expr_parent = self.tcx.hir().parent_id(*expr_hir_id);
-        let hir = self.tcx.hir().find(expr_parent);
+        let hir = self.tcx.opt_hir_node(expr_parent);
         let closure_params_len = closure_fn_decl.inputs.len();
         let (
             Some(Node::Expr(hir::Expr {
@@ -2667,7 +2666,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let Some(Node::Expr(hir::Expr {
                 kind: hir::ExprKind::If(_, _, Some(else_expr)),
                 ..
-            })) = self.tcx.hir().find(parent_id)
+            })) = self.tcx.opt_hir_node(parent_id)
             {
                 return else_expr.hir_id == expr.hir_id;
             }
@@ -3057,7 +3056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         };
         let parent = self.tcx.hir().parent_id(expr.hir_id);
-        if let Some(hir::Node::ExprField(_)) = self.tcx.hir().find(parent) {
+        if let Some(hir::Node::ExprField(_)) = self.tcx.opt_hir_node(parent) {
             // Ignore `Foo { field: a..Default::default() }`
             return;
         }
@@ -3136,7 +3135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let hir::def::Res::Local(hir_id) = path.res else {
             return;
         };
-        let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else {
+        let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else {
             return;
         };
         let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 6ad7b301014..f1f893623f6 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -127,7 +127,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     }
 
     if let Some(def_id) = def_id.as_local() {
-        primary_body_of(tcx.hir().get_by_def_id(def_id)).is_some()
+        primary_body_of(tcx.hir_node_by_def_id(def_id)).is_some()
     } else {
         false
     }
@@ -166,7 +166,7 @@ fn typeck_with_fallback<'tcx>(
     }
 
     let id = tcx.local_def_id_to_hir_id(def_id);
-    let node = tcx.hir().get(id);
+    let node = tcx.hir_node(id);
     let span = tcx.hir().span(id);
 
     // Figure out what primary body this item has.
@@ -201,7 +201,7 @@ fn typeck_with_fallback<'tcx>(
                 span,
             }))
         } else if let Node::AnonConst(_) = node {
-            match tcx.hir().get(tcx.hir().parent_id(id)) {
+            match tcx.hir_node(tcx.hir().parent_id(id)) {
                 Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
                     if anon_const.hir_id == id =>
                 {
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index e7af7da205c..b2ead3cd40b 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -415,7 +415,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                             )
                             .into()
                     }
-                    _ => unreachable!(),
+                    (kind, arg) => {
+                        bug!("mismatched method arg kind {kind:?} in turbofish: {arg:?}")
+                    }
                 }
             }
 
diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs
index 3f1dca5b1de..43d258de6ca 100644
--- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs
+++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs
@@ -122,8 +122,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             format!("disambiguate the method call with `({self_adjusted})`",),
                         );
                     }
-
-                    lint
                 },
             );
         } else {
@@ -187,8 +185,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             ),
                         );
                     }
-
-                    lint
                 },
             );
         }
@@ -307,8 +303,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
                     Applicability::MachineApplicable,
                 );
-
-                lint
             },
         );
     }
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 4243bce377f..fe2d43a3c92 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -445,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         scope_expr_id,
                         span,
                         "type annotations needed",
-                        |lint| lint,
+                        |_| {},
                     );
                 }
             } else {
@@ -1427,8 +1427,6 @@ impl<'tcx> Pick<'tcx> {
                         ));
                     }
                 }
-
-                lint
             },
         );
     }
@@ -1548,9 +1546,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     );
 
                     let candidate_obligations = impl_obligations
-                        .chain(norm_obligations.into_iter())
+                        .chain(norm_obligations)
                         .chain(ref_obligations.iter().cloned())
-                        .chain(normalization_obligations.into_iter());
+                        .chain(normalization_obligations);
 
                     // Evaluate those obligations to see if they might possibly hold.
                     for o in candidate_obligations {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index b38a6ebd501..8fb703fa7f5 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                         if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind
                             && let hir::def::Res::Local(hir_id) = path.res
-                            && let Some(hir::Node::Pat(b)) = self.tcx.hir().find(hir_id)
+                            && let Some(hir::Node::Pat(b)) = self.tcx.opt_hir_node(hir_id)
                             && let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id)
                             && let Some(node) = self.tcx.hir().find_parent(p.hir_id)
                             && let Some(decl) = node.fn_decl()
@@ -262,7 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         rcvr_ty: Ty<'tcx>,
         rcvr_expr: &hir::Expr<'tcx>,
     ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
-        let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
+        let mut file = None;
+        let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file);
         let mut err = struct_span_err!(
             self.tcx.sess,
             rcvr_expr.span,
@@ -280,6 +281,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 "a writer is needed before this format string",
             );
         };
+        if let Some(file) = file {
+            err.note(format!("the full type name has been written to '{}'", file.display()));
+        }
 
         err
     }
@@ -299,11 +303,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mode = no_match_data.mode;
         let tcx = self.tcx;
         let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
-        let ((mut ty_str, ty_file), short_ty_str) =
+        let mut ty_file = None;
+        let (mut ty_str, short_ty_str) =
             if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() {
-                ((predicates.to_string(), None), with_forced_trimmed_paths!(predicates.to_string()))
+                (predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
             } else {
-                (tcx.short_ty_string(rcvr_ty), with_forced_trimmed_paths!(rcvr_ty.to_string()))
+                (
+                    tcx.short_ty_string(rcvr_ty, &mut ty_file),
+                    with_forced_trimmed_paths!(rcvr_ty.to_string()),
+                )
             };
         let is_method = mode == Mode::MethodCall;
         let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;
@@ -605,16 +613,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if let (ty::Param(_), ty::PredicateKind::Clause(ty::ClauseKind::Trait(p))) =
                         (self_ty.kind(), parent_pred.kind().skip_binder())
                     {
-                        let hir = self.tcx.hir();
                         let node = match p.trait_ref.self_ty().kind() {
                             ty::Param(_) => {
                                 // Account for `fn` items like in `issue-35677.rs` to
                                 // suggest restricting its type params.
-                                Some(hir.get_by_def_id(self.body_id))
-                            }
-                            ty::Adt(def, _) => {
-                                def.did().as_local().map(|def_id| hir.get_by_def_id(def_id))
+                                Some(self.tcx.hir_node_by_def_id(self.body_id))
                             }
+                            ty::Adt(def, _) => def
+                                .did()
+                                .as_local()
+                                .map(|def_id| self.tcx.hir_node_by_def_id(def_id)),
                             _ => None,
                         };
                         if let Some(hir::Node::Item(hir::Item { kind, .. })) = node
@@ -1952,7 +1960,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         visitor.visit_body(body);
 
         let parent = self.tcx.hir().parent_id(seg1.hir_id);
-        if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent)
+        if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
             && let Some(expr) = visitor.result
             && let Some(self_ty) = self.node_ty_opt(expr.hir_id)
         {
@@ -2869,11 +2877,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 let id = item
                                     .def_id
                                     .as_local()
-                                    .map(|def_id| self.tcx.local_def_id_to_hir_id(def_id));
+                                    .map(|def_id| self.tcx.hir_node_by_def_id(def_id));
                                 if let Some(hir::Node::TraitItem(hir::TraitItem {
                                     kind: hir::TraitItemKind::Fn(fn_sig, method),
                                     ..
-                                })) = id.map(|id| self.tcx.hir().get(id))
+                                })) = id
                                 {
                                     let self_first_arg = match method {
                                         hir::TraitFn::Required([ident, ..]) => {
@@ -2963,7 +2971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // Get the `hir::Param` to verify whether it already has any bounds.
                     // We do this to avoid suggesting code that ends up as `T: FooBar`,
                     // instead we suggest `T: Foo + Bar` in that case.
-                    match hir.get(id) {
+                    match self.tcx.hir_node(id) {
                         Node::GenericParam(param) => {
                             enum Introducer {
                                 Plus,
@@ -3183,7 +3191,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let parent = self.tcx.hir().parent_id(expr.hir_id);
-        if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent)
+        if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
             && let hir::ExprKind::MethodCall(
                 hir::PathSegment { ident: method_name, .. },
                 self_expr,
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index b63bb1e00cb..56a420fab4f 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -720,7 +720,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             && let PatKind::Binding(_, _, binding, ..) = inner.kind
         {
             let binding_parent_id = tcx.hir().parent_id(pat.hir_id);
-            let binding_parent = tcx.hir().get(binding_parent_id);
+            let binding_parent = tcx.hir_node(binding_parent_id);
             debug!(?inner, ?pat, ?binding_parent);
 
             let mutability = match mutbl {
@@ -941,7 +941,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Some(hir::Node::Item(hir::Item {
                     kind: hir::ItemKind::Const(_, _, body_id),
                     ..
-                })) => match self.tcx.hir().get(body_id.hir_id) {
+                })) => match self.tcx.hir_node(body_id.hir_id) {
                     hir::Node::Expr(expr) => {
                         if hir::is_range_literal(expr) {
                             let span = self.tcx.hir().span(body_id.hir_id);
@@ -1820,7 +1820,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         fn joined_uncovered_patterns(witnesses: &[&Ident]) -> String {
             const LIMIT: usize = 3;
             match witnesses {
-                [] => bug!(),
+                [] => {
+                    unreachable!(
+                        "expected an uncovered pattern, otherwise why are we emitting an error?"
+                    )
+                }
                 [witness] => format!("`{witness}`"),
                 [head @ .., tail] if head.len() < LIMIT => {
                     let head: Vec<_> = head.iter().map(<_>::to_string).collect();
@@ -1845,8 +1849,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         lint.note(format!(
             "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found",
         ));
-
-        lint
     });
     }
 
diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
index 04d84102336..b9b3ed53dae 100644
--- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
+++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
@@ -69,12 +69,13 @@ pub fn resolve_rvalue_scopes<'a, 'tcx>(
     def_id: DefId,
 ) -> RvalueScopes {
     let tcx = &fcx.tcx;
-    let hir_map = tcx.hir();
     let mut rvalue_scopes = RvalueScopes::new();
     debug!("start resolving rvalue scopes, def_id={def_id:?}");
     debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates);
     for (&hir_id, candidate) in &scope_tree.rvalue_candidates {
-        let Some(Node::Expr(expr)) = hir_map.find(hir_id) else { bug!("hir node does not exist") };
+        let Some(Node::Expr(expr)) = tcx.opt_hir_node(hir_id) else {
+            bug!("hir node does not exist")
+        };
         record_rvalue_scope(&mut rvalue_scopes, expr, candidate);
     }
     rvalue_scopes
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index c0a5818b9e5..69d6fb8e2ea 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -261,7 +261,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Unify the (as yet unbound) type variable in the closure
             // args with the kind we inferred.
             let closure_kind_ty = closure_args.as_closure().kind_ty();
-            self.demand_eqtype(span, closure_kind.to_ty(self.tcx), closure_kind_ty);
+            self.demand_eqtype(
+                span,
+                Ty::from_closure_kind(self.tcx, closure_kind),
+                closure_kind_ty,
+            );
 
             // If we have an origin, store it.
             if let Some(mut origin) = origin {
@@ -315,11 +319,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let final_tupled_upvars_type = Ty::new_tup(self.tcx, &final_upvar_tys);
         self.demand_suptype(span, args.tupled_upvars_ty(), final_tupled_upvars_type);
 
-        let fake_reads = delegate
-            .fake_reads
-            .into_iter()
-            .map(|(place, cause, hir_id)| (place, cause, hir_id))
-            .collect();
+        let fake_reads = delegate.fake_reads;
+
         self.typeck_results.borrow_mut().closure_fake_reads.insert(closure_def_id, fake_reads);
 
         if self.tcx.sess.opts.unstable_opts.profile_closures {
@@ -853,7 +854,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             // Looks like a macro fragment. Try to find the real block.
                             if let Some(hir::Node::Expr(&hir::Expr {
                                 kind: hir::ExprKind::Block(block, ..), ..
-                            })) = self.tcx.hir().find(body_id.hir_id) {
+                            })) = self.tcx.opt_hir_node(body_id.hir_id) {
                                 // If the body is a block (with `{..}`), we use the span of that block.
                                 // E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`.
                                 // Since we know it's a block, we know we can insert the `let _ = ..` without
@@ -911,8 +912,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             Applicability::HasPlaceholders
                         );
                     }
-
-                    lint
                 },
             );
         }
@@ -1673,7 +1672,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>(
 fn drop_location_span(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> Span {
     let owner_id = tcx.hir().get_enclosing_scope(hir_id).unwrap();
 
-    let owner_node = tcx.hir().get(owner_id);
+    let owner_node = tcx.hir_node(owner_id);
     let owner_span = match owner_node {
         hir::Node::Item(item) => match item.kind {
             hir::ItemKind::Fn(_, _, owner_id) => tcx.hir().span(owner_id.hir_id),
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 1609c036fbd..5e562d9453f 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -504,8 +504,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
             if !errors_buffer.is_empty() {
                 errors_buffer.sort_by_key(|diag| diag.span.primary_span());
-                for mut diag in errors_buffer {
-                    self.tcx().sess.diagnostic().emit_diagnostic(&mut diag);
+                for diag in errors_buffer {
+                    self.tcx().sess.diagnostic().emit_diagnostic(diag);
                 }
             }
         }
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 0f2194139df..8a7b97139ea 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -232,7 +232,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
     /// Return all DepNode labels that should be asserted for this item.
     /// index=0 is the "name" used for error messages
     fn auto_labels(&mut self, item_id: LocalDefId, attr: &Attribute) -> (&'static str, Labels) {
-        let node = self.tcx.hir().get_by_def_id(item_id);
+        let node = self.tcx.hir_node_by_def_id(item_id);
         let (name, labels) = match node {
             HirNode::Item(item) => {
                 match item.kind {
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index 6a220243266..a0768fc7115 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -363,9 +363,7 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
                 return false;
             };
 
-            let hir_id = self.tcx.local_def_id_to_hir_id(anon_reg.def_id);
-
-            let node = self.tcx.hir().get(hir_id);
+            let node = self.tcx.hir_node_by_def_id(anon_reg.def_id);
             let is_impl = matches!(&node, hir::Node::ImplItem(_));
             let generics = match node {
                 hir::Node::Item(&hir::Item {
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 473a3965885..5b00ef42211 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -35,36 +35,13 @@ impl<'tcx> InferCtxt<'tcx> {
     /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#canonicalizing-the-query
     pub fn canonicalize_query<V>(
         &self,
-        value: V,
-        query_state: &mut OriginalQueryValues<'tcx>,
-    ) -> Canonical<'tcx, V>
-    where
-        V: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        Canonicalizer::canonicalize(value, self, self.tcx, &CanonicalizeAllFreeRegions, query_state)
-    }
-
-    /// Like [Self::canonicalize_query], but preserves distinct universes. For
-    /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and
-    /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1`
-    /// in `U2`.
-    ///
-    /// This is used for Chalk integration.
-    pub fn canonicalize_query_preserving_universes<V>(
-        &self,
-        value: V,
+        value: ty::ParamEnvAnd<'tcx, V>,
         query_state: &mut OriginalQueryValues<'tcx>,
-    ) -> Canonical<'tcx, V>
+    ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
     where
         V: TypeFoldable<TyCtxt<'tcx>>,
     {
-        Canonicalizer::canonicalize(
-            value,
-            self,
-            self.tcx,
-            &CanonicalizeAllFreeRegionsPreservingUniverses,
-            query_state,
-        )
+        self.canonicalize_query_with_mode(value, query_state, &CanonicalizeAllFreeRegions)
     }
 
     /// Canonicalizes a query *response* `V`. When we canonicalize a
@@ -99,7 +76,7 @@ impl<'tcx> InferCtxt<'tcx> {
         let mut query_state = OriginalQueryValues::default();
         Canonicalizer::canonicalize(
             value,
-            self,
+            Some(self),
             self.tcx,
             &CanonicalizeQueryResponse,
             &mut query_state,
@@ -113,7 +90,7 @@ impl<'tcx> InferCtxt<'tcx> {
         let mut query_state = OriginalQueryValues::default();
         Canonicalizer::canonicalize(
             value,
-            self,
+            Some(self),
             self.tcx,
             &CanonicalizeUserTypeAnnotation,
             &mut query_state,
@@ -126,19 +103,53 @@ impl<'tcx> InferCtxt<'tcx> {
     /// handling of `'static` regions (e.g. trait evaluation).
     pub fn canonicalize_query_keep_static<V>(
         &self,
-        value: V,
+        value: ty::ParamEnvAnd<'tcx, V>,
         query_state: &mut OriginalQueryValues<'tcx>,
-    ) -> Canonical<'tcx, V>
+    ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
     where
         V: TypeFoldable<TyCtxt<'tcx>>,
     {
-        Canonicalizer::canonicalize(
+        self.canonicalize_query_with_mode(
             value,
-            self,
-            self.tcx,
+            query_state,
             &CanonicalizeFreeRegionsOtherThanStatic,
+        )
+    }
+
+    fn canonicalize_query_with_mode<V>(
+        &self,
+        value: ty::ParamEnvAnd<'tcx, V>,
+        query_state: &mut OriginalQueryValues<'tcx>,
+        canonicalize_region_mode: &dyn CanonicalizeMode,
+    ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
+    where
+        V: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        let (param_env, value) = value.into_parts();
+        let base = self.tcx.canonical_param_env_cache.get_or_insert(
+            self.tcx,
+            param_env,
+            query_state,
+            |tcx, param_env, query_state| {
+                Canonicalizer::canonicalize(
+                    param_env,
+                    None,
+                    tcx,
+                    &CanonicalizeFreeRegionsOtherThanStatic,
+                    query_state,
+                )
+            },
+        );
+
+        Canonicalizer::canonicalize_with_base(
+            base,
+            value,
+            Some(self),
+            self.tcx,
+            canonicalize_region_mode,
             query_state,
         )
+        .unchecked_map(|(param_env, value)| param_env.and(value))
     }
 }
 
@@ -168,8 +179,22 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
     fn canonicalize_free_region<'tcx>(
         &self,
         canonicalizer: &mut Canonicalizer<'_, 'tcx>,
-        r: ty::Region<'tcx>,
+        mut r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
+        let infcx = canonicalizer.infcx.unwrap();
+
+        if let ty::ReVar(vid) = *r {
+            r = infcx
+                .inner
+                .borrow_mut()
+                .unwrap_region_constraints()
+                .opportunistic_resolve_var(canonicalizer.tcx, vid);
+            debug!(
+                "canonical: region var found with vid {vid:?}, \
+                     opportunistically resolved to {r:?}",
+            );
+        };
+
         match *r {
             ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r,
 
@@ -179,7 +204,8 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
             ),
 
             ty::ReVar(vid) => {
-                let universe = canonicalizer.region_var_universe(vid);
+                let universe =
+                    infcx.inner.borrow_mut().unwrap_region_constraints().var_universe(vid);
                 canonicalizer.canonical_var_for_region(
                     CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) },
                     r,
@@ -264,30 +290,6 @@ impl CanonicalizeMode for CanonicalizeAllFreeRegions {
     }
 }
 
-struct CanonicalizeAllFreeRegionsPreservingUniverses;
-
-impl CanonicalizeMode for CanonicalizeAllFreeRegionsPreservingUniverses {
-    fn canonicalize_free_region<'tcx>(
-        &self,
-        canonicalizer: &mut Canonicalizer<'_, 'tcx>,
-        r: ty::Region<'tcx>,
-    ) -> ty::Region<'tcx> {
-        let universe = canonicalizer.infcx.universe_of_region(r);
-        canonicalizer.canonical_var_for_region(
-            CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) },
-            r,
-        )
-    }
-
-    fn any(&self) -> bool {
-        true
-    }
-
-    fn preserve_universes(&self) -> bool {
-        true
-    }
-}
-
 struct CanonicalizeFreeRegionsOtherThanStatic;
 
 impl CanonicalizeMode for CanonicalizeFreeRegionsOtherThanStatic {
@@ -309,7 +311,8 @@ impl CanonicalizeMode for CanonicalizeFreeRegionsOtherThanStatic {
 }
 
 struct Canonicalizer<'cx, 'tcx> {
-    infcx: &'cx InferCtxt<'tcx>,
+    /// Set to `None` to disable the resolution of inference variables.
+    infcx: Option<&'cx InferCtxt<'tcx>>,
     tcx: TyCtxt<'tcx>,
     variables: SmallVec<[CanonicalVarInfo<'tcx>; 8]>,
     query_state: &'cx mut OriginalQueryValues<'tcx>,
@@ -347,25 +350,12 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                 }
             }
 
-            ty::ReVar(vid) => {
-                let resolved = self
-                    .infcx
-                    .inner
-                    .borrow_mut()
-                    .unwrap_region_constraints()
-                    .opportunistic_resolve_var(self.tcx, vid);
-                debug!(
-                    "canonical: region var found with vid {vid:?}, \
-                     opportunistically resolved to {resolved:?}",
-                );
-                self.canonicalize_mode.canonicalize_free_region(self, resolved)
-            }
-
             ty::ReStatic
             | ty::ReEarlyParam(..)
             | ty::ReError(_)
             | ty::ReLateParam(_)
             | ty::RePlaceholder(..)
+            | ty::ReVar(_)
             | ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
         }
     }
@@ -376,14 +366,14 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                 // We need to canonicalize the *root* of our ty var.
                 // This is so that our canonical response correctly reflects
                 // any equated inference vars correctly!
-                let root_vid = self.infcx.root_var(vid);
+                let root_vid = self.infcx.unwrap().root_var(vid);
                 if root_vid != vid {
-                    t = Ty::new_var(self.infcx.tcx, root_vid);
+                    t = Ty::new_var(self.tcx, root_vid);
                     vid = root_vid;
                 }
 
                 debug!("canonical: type var found with vid {:?}", vid);
-                match self.infcx.probe_ty_var(vid) {
+                match self.infcx.unwrap().probe_ty_var(vid) {
                     // `t` could be a float / int variable; canonicalize that instead.
                     Ok(t) => {
                         debug!("(resolved to {:?})", t);
@@ -408,7 +398,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
             }
 
             ty::Infer(ty::IntVar(vid)) => {
-                let nt = self.infcx.opportunistic_resolve_int_var(vid);
+                let nt = self.infcx.unwrap().opportunistic_resolve_int_var(vid);
                 if nt != t {
                     return self.fold_ty(nt);
                 } else {
@@ -419,7 +409,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                 }
             }
             ty::Infer(ty::FloatVar(vid)) => {
-                let nt = self.infcx.opportunistic_resolve_float_var(vid);
+                let nt = self.infcx.unwrap().opportunistic_resolve_float_var(vid);
                 if nt != t {
                     return self.fold_ty(nt);
                 } else {
@@ -490,14 +480,14 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                 // We need to canonicalize the *root* of our const var.
                 // This is so that our canonical response correctly reflects
                 // any equated inference vars correctly!
-                let root_vid = self.infcx.root_const_var(vid);
+                let root_vid = self.infcx.unwrap().root_const_var(vid);
                 if root_vid != vid {
-                    ct = ty::Const::new_var(self.infcx.tcx, root_vid, ct.ty());
+                    ct = ty::Const::new_var(self.tcx, root_vid, ct.ty());
                     vid = root_vid;
                 }
 
                 debug!("canonical: const var found with vid {:?}", vid);
-                match self.infcx.probe_const_var(vid) {
+                match self.infcx.unwrap().probe_const_var(vid) {
                     Ok(c) => {
                         debug!("(resolved to {:?})", c);
                         return self.fold_const(c);
@@ -518,8 +508,8 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                 }
             }
             ty::ConstKind::Infer(InferConst::EffectVar(vid)) => {
-                match self.infcx.probe_effect_var(vid) {
-                    Some(value) => return self.fold_const(value.as_const(self.infcx.tcx)),
+                match self.infcx.unwrap().probe_effect_var(vid) {
+                    Some(value) => return self.fold_const(value.as_const(self.tcx)),
                     None => {
                         return self.canonicalize_const_var(
                             CanonicalVarInfo { kind: CanonicalVarKind::Effect },
@@ -562,7 +552,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     /// `canonicalize_query` and `canonicalize_response`.
     fn canonicalize<V>(
         value: V,
-        infcx: &InferCtxt<'tcx>,
+        infcx: Option<&InferCtxt<'tcx>>,
         tcx: TyCtxt<'tcx>,
         canonicalize_region_mode: &dyn CanonicalizeMode,
         query_state: &mut OriginalQueryValues<'tcx>,
@@ -570,6 +560,33 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     where
         V: TypeFoldable<TyCtxt<'tcx>>,
     {
+        let base = Canonical {
+            max_universe: ty::UniverseIndex::ROOT,
+            variables: List::empty(),
+            value: (),
+        };
+        Canonicalizer::canonicalize_with_base(
+            base,
+            value,
+            infcx,
+            tcx,
+            canonicalize_region_mode,
+            query_state,
+        )
+        .unchecked_map(|((), val)| val)
+    }
+
+    fn canonicalize_with_base<U, V>(
+        base: Canonical<'tcx, U>,
+        value: V,
+        infcx: Option<&InferCtxt<'tcx>>,
+        tcx: TyCtxt<'tcx>,
+        canonicalize_region_mode: &dyn CanonicalizeMode,
+        query_state: &mut OriginalQueryValues<'tcx>,
+    ) -> Canonical<'tcx, (U, V)>
+    where
+        V: TypeFoldable<TyCtxt<'tcx>>,
+    {
         let needs_canonical_flags = if canonicalize_region_mode.any() {
             TypeFlags::HAS_INFER | TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_FREE_REGIONS
         } else {
@@ -578,12 +595,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
 
         // Fast path: nothing that needs to be canonicalized.
         if !value.has_type_flags(needs_canonical_flags) {
-            let canon_value = Canonical {
-                max_universe: ty::UniverseIndex::ROOT,
-                variables: List::empty(),
-                value,
-            };
-            return canon_value;
+            return base.unchecked_map(|b| (b, value));
         }
 
         let mut canonicalizer = Canonicalizer {
@@ -591,11 +603,20 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             tcx,
             canonicalize_mode: canonicalize_region_mode,
             needs_canonical_flags,
-            variables: SmallVec::new(),
+            variables: SmallVec::from_slice(base.variables),
             query_state,
             indices: FxHashMap::default(),
             binder_index: ty::INNERMOST,
         };
+        if canonicalizer.query_state.var_values.spilled() {
+            canonicalizer.indices = canonicalizer
+                .query_state
+                .var_values
+                .iter()
+                .enumerate()
+                .map(|(i, &kind)| (kind, BoundVar::new(i)))
+                .collect();
+        }
         let out_value = value.fold_with(&mut canonicalizer);
 
         // Once we have canonicalized `out_value`, it should not
@@ -612,7 +633,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             .max()
             .unwrap_or(ty::UniverseIndex::ROOT);
 
-        Canonical { max_universe, variables: canonical_variables, value: out_value }
+        Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) }
     }
 
     /// Creates a canonical variable replacing `kind` from the input,
@@ -761,11 +782,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
         )
     }
 
-    /// Returns the universe in which `vid` is defined.
-    fn region_var_universe(&self, vid: ty::RegionVid) -> ty::UniverseIndex {
-        self.infcx.inner.borrow_mut().unwrap_region_constraints().var_universe(vid)
-    }
-
     /// Creates a canonical variable (with the given `info`)
     /// representing the region `r`; return a region referencing it.
     fn canonical_var_for_region(
@@ -783,14 +799,9 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     /// *that*. Otherwise, create a new canonical variable for
     /// `ty_var`.
     fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> {
-        let infcx = self.infcx;
-        let bound_to = infcx.shallow_resolve(ty_var);
-        if bound_to != ty_var {
-            self.fold_ty(bound_to)
-        } else {
-            let var = self.canonical_var(info, ty_var.into());
-            Ty::new_bound(self.tcx, self.binder_index, var.into())
-        }
+        debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
+        let var = self.canonical_var(info, ty_var.into());
+        Ty::new_bound(self.tcx, self.binder_index, var.into())
     }
 
     /// Given a type variable `const_var` of the given kind, first check
@@ -802,13 +813,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
         info: CanonicalVarInfo<'tcx>,
         const_var: ty::Const<'tcx>,
     ) -> ty::Const<'tcx> {
-        let infcx = self.infcx;
-        let bound_to = infcx.shallow_resolve(const_var);
-        if bound_to != const_var {
-            self.fold_const(bound_to)
-        } else {
-            let var = self.canonical_var(info, const_var.into());
-            ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty()))
-        }
+        debug_assert!(
+            !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve(const_var))
+        );
+        let var = self.canonical_var(info, const_var.into());
+        ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty()))
     }
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 3c4c4644fe6..386fdb09ba5 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -101,7 +101,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// variable, then you'll get a new inference variable; if it is a
     /// universally quantified variable, you get a placeholder.
     ///
-    /// FIXME(-Ztrait-solver=next): This is public because it's used by the
+    /// FIXME(-Znext-solver): This is public because it's used by the
     /// new trait solver which has a different canonicalization routine.
     /// We should somehow deduplicate all of this.
     pub fn instantiate_canonical_var(
diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs
index f368b30fbd1..e0b97bb160c 100644
--- a/compiler/rustc_infer/src/infer/canonical/substitute.rs
+++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs
@@ -11,7 +11,7 @@ use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable};
 use rustc_middle::ty::GenericArgKind;
 use rustc_middle::ty::{self, TyCtxt};
 
-/// FIXME(-Ztrait-solver=next): This or public because it is shared with the
+/// FIXME(-Znext-solver): This or public because it is shared with the
 /// new trait solver implementation. We should deduplicate canonicalization.
 pub trait CanonicalExt<'tcx, V> {
     /// Instantiate the wrapped value, replacing each canonical value
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 745c3d195ad..c118c405c20 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -891,7 +891,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 }
                 // don't suggest wrapping either blocks in `if .. {} else {}`
                 let is_empty_arm = |id| {
-                    let hir::Node::Block(blk) = self.tcx.hir().get(id) else {
+                    let hir::Node::Block(blk) = self.tcx.hir_node(id) else {
                         return false;
                     };
                     if blk.expr.is_some() || !blk.stmts.is_empty() {
@@ -1743,7 +1743,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             }
         }
 
-        if let Some((expected, found, exp_p, found_p)) = expected_found {
+        if let Some((expected, found, path)) = expected_found {
             let (expected_label, found_label, exp_found) = match exp_found {
                 Mismatch::Variable(ef) => (
                     ef.expected.prefix_string(self.tcx),
@@ -1869,40 +1869,31 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 }
                 TypeError::Sorts(values) => {
                     let extra = expected == found;
-                    let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| {
-                        let mut s = match (extra, ty.kind()) {
-                            (true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
-                                let sm = self.tcx.sess.source_map();
-                                let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
-                                format!(
-                                    " (opaque type at <{}:{}:{}>)",
-                                    sm.filename_for_diagnostics(&pos.file.name),
-                                    pos.line,
-                                    pos.col.to_usize() + 1,
-                                )
-                            }
-                            (true, ty::Alias(ty::Projection, proj))
-                                if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
-                            {
-                                let sm = self.tcx.sess.source_map();
-                                let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
-                                format!(
-                                    " (trait associated opaque type at <{}:{}:{}>)",
-                                    sm.filename_for_diagnostics(&pos.file.name),
-                                    pos.line,
-                                    pos.col.to_usize() + 1,
-                                )
-                            }
-                            (true, _) => format!(" ({})", ty.sort_string(self.tcx)),
-                            (false, _) => "".to_string(),
-                        };
-                        if let Some(path) = path {
-                            s.push_str(&format!(
-                                "\nthe full type name has been written to '{}'",
-                                path.display(),
-                            ));
+                    let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
+                        (true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
+                            let sm = self.tcx.sess.source_map();
+                            let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
+                            format!(
+                                " (opaque type at <{}:{}:{}>)",
+                                sm.filename_for_diagnostics(&pos.file.name),
+                                pos.line,
+                                pos.col.to_usize() + 1,
+                            )
                         }
-                        s
+                        (true, ty::Alias(ty::Projection, proj))
+                            if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
+                        {
+                            let sm = self.tcx.sess.source_map();
+                            let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
+                            format!(
+                                " (trait associated opaque type at <{}:{}:{}>)",
+                                sm.filename_for_diagnostics(&pos.file.name),
+                                pos.line,
+                                pos.col.to_usize() + 1,
+                            )
+                        }
+                        (true, _) => format!(" ({})", ty.sort_string(self.tcx)),
+                        (false, _) => "".to_string(),
                     };
                     if !(values.expected.is_simple_text(self.tcx)
                         && values.found.is_simple_text(self.tcx))
@@ -1933,9 +1924,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                                     expected,
                                     &found_label,
                                     found,
-                                    &sort_string(values.expected, exp_p),
-                                    &sort_string(values.found, found_p),
+                                    &sort_string(values.expected),
+                                    &sort_string(values.found),
                                 );
+                                if let Some(path) = path {
+                                    diag.note(format!(
+                                        "the full type name has been written to '{}'",
+                                        path.display(),
+                                    ));
+                                }
                             }
                         }
                     }
@@ -2007,7 +2004,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             diag.span_note(span, "this closure does not fulfill the lifetime requirements");
             self.suggest_for_all_lifetime_closure(
                 span,
-                self.tcx.hir().get_by_def_id(def_id),
+                self.tcx.hir_node_by_def_id(def_id),
                 &exp_found,
                 diag,
             );
@@ -2101,7 +2098,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. })
         | BlockTailExpression(.., source)) = code
             && let hir::MatchSource::TryDesugar(_) = source
-            && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
+            && let Some((expected_ty, found_ty, _)) = self.values_str(trace.values)
         {
             suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
                 found: found_ty.content(),
@@ -2121,7 +2118,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         let TypeError::FixedArraySize(sz) = terr else {
             return None;
         };
-        let tykind = match hir.find_by_def_id(trace.cause.body_id) {
+        let tykind = match self.tcx.opt_hir_node_by_def_id(trace.cause.body_id) {
             Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => {
                 let body = hir.body(*body_id);
                 struct LetVisitor<'v> {
@@ -2219,8 +2216,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn values_str(
         &self,
         values: ValuePairs<'tcx>,
-    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
-    {
+    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
         match values {
             infer::Regions(exp_found) => self.expected_found_str(exp_found),
             infer::Terms(exp_found) => self.expected_found_str_term(exp_found),
@@ -2233,7 +2229,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     found: exp_found.found.print_trait_sugared(),
                 };
                 match self.expected_found_str(pretty_exp_found) {
-                    Some((expected, found, _, _)) if expected == found => {
+                    Some((expected, found, _)) if expected == found => {
                         self.expected_found_str(exp_found)
                     }
                     ret => ret,
@@ -2245,7 +2241,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     return None;
                 }
                 let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
-                Some((exp, fnd, None, None))
+                Some((exp, fnd, None))
             }
         }
     }
@@ -2253,8 +2249,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn expected_found_str_term(
         &self,
         exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
-    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
-    {
+    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
         let exp_found = self.resolve_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
@@ -2269,25 +2264,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 let len = self.tcx.sess().diagnostic_width() + 40;
                 let exp_s = exp.content();
                 let fnd_s = fnd.content();
-                let mut exp_p = None;
-                let mut fnd_p = None;
+                let mut path = None;
                 if exp_s.len() > len {
-                    let (exp_s, exp_path) = self.tcx.short_ty_string(expected);
+                    let exp_s = self.tcx.short_ty_string(expected, &mut path);
                     exp = DiagnosticStyledString::highlighted(exp_s);
-                    exp_p = exp_path;
                 }
                 if fnd_s.len() > len {
-                    let (fnd_s, fnd_path) = self.tcx.short_ty_string(found);
+                    let fnd_s = self.tcx.short_ty_string(found, &mut path);
                     fnd = DiagnosticStyledString::highlighted(fnd_s);
-                    fnd_p = fnd_path;
                 }
-                (exp, fnd, exp_p, fnd_p)
+                (exp, fnd, path)
             }
             _ => (
                 DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
                 DiagnosticStyledString::highlighted(exp_found.found.to_string()),
                 None,
-                None,
             ),
         })
     }
@@ -2296,8 +2287,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         exp_found: ty::error::ExpectedFound<T>,
-    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
-    {
+    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
         let exp_found = self.resolve_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
@@ -2307,7 +2297,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
             DiagnosticStyledString::highlighted(exp_found.found.to_string()),
             None,
-            None,
         ))
     }
 
@@ -2452,7 +2441,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
             if !suggs.is_empty() {
                 err.multipart_suggestion_verbose(
-                    format!("{msg}"),
+                    msg,
                     suggs,
                     Applicability::MaybeIncorrect, // Issue #41966
                 );
@@ -2591,8 +2580,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
         if let infer::Subtype(ref sup_trace) = sup_origin
             && let infer::Subtype(ref sub_trace) = sub_origin
-            && let Some((sup_expected, sup_found, _, _)) = self.values_str(sup_trace.values)
-            && let Some((sub_expected, sub_found, _, _)) = self.values_str(sub_trace.values)
+            && let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values)
+            && let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values)
             && sub_expected == sup_expected
             && sub_found == sup_found
         {
@@ -2997,7 +2986,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// Given a [`hir::HirId`] for a block, get the span of its last expression
     /// or statement, peeling off any inner blocks.
     pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span {
-        match self.tcx.hir().get(hir_id) {
+        match self.tcx.hir_node(hir_id) {
             hir::Node::Block(blk) => self.find_block_span(blk),
             // The parser was in a weird state if either of these happen, but
             // it's better not to panic.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 8fe6c1b0d86..1caa9aa8cd6 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -232,7 +232,9 @@ fn ty_to_string<'tcx>(
 /// something users are familiar with. Directly printing the `fn_sig` of closures also
 /// doesn't work as they actually use the "rust-call" API.
 fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
-    let ty::Closure(_, args) = ty.kind() else { unreachable!() };
+    let ty::Closure(_, args) = ty.kind() else {
+        bug!("cannot convert non-closure to fn str in `closure_as_fn_str`")
+    };
     let fn_sig = args.as_closure().sig();
     let args = fn_sig
         .inputs()
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
index ab928232d74..4f74365d06c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -26,8 +26,7 @@ pub fn find_anon_type<'tcx>(
     br: &ty::BoundRegionKind,
 ) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> {
     let anon_reg = tcx.is_suitable_region(region)?;
-    let hir_id = tcx.local_def_id_to_hir_id(anon_reg.def_id);
-    let fn_sig = tcx.hir().get(hir_id).fn_sig()?;
+    let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?;
 
     fn_sig
         .decl
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 81154415c1e..01b43f7197d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -460,7 +460,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                 tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
                     if let Node::Item(Item {
                         kind: ItemKind::Impl(hir::Impl { self_ty, .. }), ..
-                    }) = tcx.hir().find_by_def_id(impl_did)?
+                    }) = tcx.opt_hir_node_by_def_id(impl_did)?
                         && trait_objects.iter().all(|did| {
                             // FIXME: we should check `self_ty` against the receiver
                             // type in the `UnifyReceiver` context, but for now, use
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index 155c0356025..bfff00b948e 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
@@ -50,11 +50,10 @@ pub fn find_param_with_region<'tcx>(
 
     let hir = &tcx.hir();
     let def_id = id.as_local()?;
-    let hir_id = tcx.local_def_id_to_hir_id(def_id);
 
     // FIXME: use def_kind
     // Don't perform this on closures
-    match hir.get(hir_id) {
+    match tcx.hir_node_by_def_id(def_id) {
         hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
             return None;
         }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index fed76cd65cf..1e365848e07 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -22,7 +22,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
                 span: trace.cause.span,
                 requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
-                expected_found: self.values_str(trace.values).map(|(e, f, _, _)| (e, f)),
+                expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
             }
             .add_to_diagnostic(err),
             infer::Reborrow(span) => {
@@ -375,7 +375,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     err.span_note(span, "the lifetime requirement is introduced here");
                     err
                 } else {
-                    unreachable!()
+                    unreachable!(
+                        "control flow ensures we have a `BindingObligation` or `ExprBindingObligation` here..."
+                    )
                 }
             }
             infer::Subtype(box trace) => {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index b93fe02aaea..afb3c5c1e56 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -655,7 +655,7 @@ fn foo(&self) -> Self::T { String::new() }
         // When `body_owner` is an `impl` or `trait` item, look in its associated types for
         // `expected` and point at it.
         let parent_id = tcx.hir().get_parent_item(hir_id);
-        let item = tcx.hir().find_by_def_id(parent_id.def_id);
+        let item = tcx.opt_hir_node_by_def_id(parent_id.def_id);
 
         debug!("expected_projection parent item {:?}", item);
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index aa5fe6d3f56..bbe07b8ed72 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -42,7 +42,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         ]
         .into_iter()
         .find_map(|(id, ty)| {
-            let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None };
+            let hir::Node::Block(blk) = self.tcx.hir_node(id?) else { return None };
             self.could_remove_semicolon(blk, ty)
         });
         match remove_semicolon {
@@ -62,7 +62,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 let mut ret = None;
                 for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] {
                     if let Some(id) = id
-                        && let hir::Node::Block(blk) = self.tcx.hir().get(id)
+                        && let hir::Node::Block(blk) = self.tcx.hir_node(id)
                         && let Some(diag) = self.consider_returning_binding_diag(blk, ty)
                     {
                         ret = Some(diag);
@@ -668,26 +668,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     (
                         hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
                         hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
-                    ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| {
-                        match (left, right) {
-                            (
-                                hir::GenericBound::Trait(tl, ml),
-                                hir::GenericBound::Trait(tr, mr),
-                            ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
+                    ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
+                        left, right,
+                    ) {
+                        (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr))
+                            if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
                                 && ml == mr =>
-                            {
-                                true
-                            }
-                            (
-                                hir::GenericBound::LangItemTrait(langl, _, _, argsl),
-                                hir::GenericBound::LangItemTrait(langr, _, _, argsr),
-                            ) if langl == langr => {
-                                // FIXME: consider the bounds!
-                                debug!("{:?} {:?}", argsl, argsr);
-                                true
-                            }
-                            _ => false,
+                        {
+                            true
                         }
+                        _ => false,
                     }) =>
                     {
                         StatementAsExpression::NeedsBoxing
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 18231af2bed..3de269da22d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -5,7 +5,7 @@ pub use self::BoundRegionConversionTime::*;
 pub use self::RegionVariableOrigin::*;
 pub use self::SubregionOrigin::*;
 pub use self::ValuePairs::*;
-pub use combine::ObligationEmittingRelation;
+pub use relate::combine::ObligationEmittingRelation;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
@@ -43,7 +43,6 @@ use rustc_span::{Span, DUMMY_SP};
 use std::cell::{Cell, RefCell};
 use std::fmt;
 
-use self::combine::CombineFields;
 use self::error_reporting::TypeErrCtxt;
 use self::free_regions::RegionRelations;
 use self::lexical_region_resolve::LexicalRegionResolutions;
@@ -51,29 +50,23 @@ use self::region_constraints::{GenericKind, VarInfos, VerifyBound};
 use self::region_constraints::{
     RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot,
 };
+pub use self::relate::combine::CombineFields;
+pub use self::relate::nll as nll_relate;
 use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 
 pub mod at;
 pub mod canonical;
-mod combine;
-mod equate;
 pub mod error_reporting;
 pub mod free_regions;
 mod freshen;
 mod fudge;
-mod generalize;
-mod glb;
-mod higher_ranked;
-pub mod lattice;
 mod lexical_region_resolve;
-mod lub;
-pub mod nll_relate;
 pub mod opaque_types;
 pub mod outlives;
 mod projection;
 pub mod region_constraints;
+mod relate;
 pub mod resolve;
-mod sub;
 pub mod type_variable;
 mod undo_log;
 
@@ -381,17 +374,13 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
         self.probe_ty_var(vid).ok()
     }
 
-    fn root_lt_var(&self, vid: ty::RegionVid) -> ty::RegionVid {
-        self.root_region_var(vid)
-    }
-
-    fn probe_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
+    fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
         let re = self
             .inner
             .borrow_mut()
             .unwrap_region_constraints()
             .opportunistic_resolve_var(self.tcx, vid);
-        if re.is_var() { None } else { Some(re) }
+        if *re == ty::ReVar(vid) { None } else { Some(re) }
     }
 
     fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
@@ -1367,10 +1356,6 @@ impl<'tcx> InferCtxt<'tcx> {
         self.inner.borrow_mut().type_variables().root_var(var)
     }
 
-    pub fn root_region_var(&self, var: ty::RegionVid) -> ty::RegionVid {
-        self.inner.borrow_mut().unwrap_region_constraints().root_var(var)
-    }
-
     pub fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
         self.inner.borrow_mut().const_unification_table().find(var).vid
     }
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 82ab1955053..a492c6bf9bb 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -683,8 +683,8 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi
     let res = hir_id == scope;
     trace!(
         "may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
-        tcx.hir().find(hir_id),
-        tcx.hir().get(opaque_hir_id),
+        tcx.opt_hir_node(hir_id),
+        tcx.hir_node(opaque_hir_id),
         res
     );
     res
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index 45df22d44e8..47038cfd468 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -203,7 +203,9 @@ pub(super) fn compute_alias_components_recursive<'tcx>(
     out: &mut SmallVec<[Component<'tcx>; 4]>,
     visited: &mut SsoHashSet<GenericArg<'tcx>>,
 ) {
-    let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() };
+    let ty::Alias(kind, alias_ty) = alias_ty.kind() else {
+        unreachable!("can only call `compute_alias_components_recursive` on an alias type")
+    };
     let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] };
     for (index, child) in alias_ty.args.iter().enumerate() {
         if opt_variances.get(index) == Some(&ty::Bivariant) {
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index ce619ae8a0d..bb578a482e4 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -130,12 +130,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         // see the extensive comment in projection_must_outlive
         let recursive_bound = {
             let mut components = smallvec![];
-            compute_alias_components_recursive(
-                self.tcx,
-                alias_ty_as_ty.into(),
-                &mut components,
-                visited,
-            );
+            compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components, visited);
             self.bound_from_components(&components, visited)
         };
 
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 5c043b1d3dd..cbd8040c9f1 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -623,11 +623,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
         }
     }
 
-    pub fn root_var(&mut self, vid: ty::RegionVid) -> ty::RegionVid {
-        let mut ut = self.unification_table_mut(); // FIXME(rust-lang/ena#42): unnecessary mut
-        ut.find(vid).vid
-    }
-
     fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
         match t {
             Glb => &mut self.glbs,
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index bab21bc237a..dfaca3458d6 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -3,7 +3,7 @@
 //! combining two instances of various things and yielding a new instance.
 //! These combiner methods always yield a `Result<T>`. To relate two
 //! types, you can use `infcx.at(cause, param_env)` which then allows
-//! you to use the relevant methods of [At](super::at::At).
+//! you to use the relevant methods of [At](crate::infer::at::At).
 //!
 //! Combiners mostly do their specific behavior and then hand off the
 //! bulk of the work to [InferCtxt::super_combine_tys] and
@@ -23,11 +23,11 @@
 //! this should be correctly updated.
 
 use super::equate::Equate;
+use super::generalize::{self, CombineDelegate, Generalization};
 use super::glb::Glb;
 use super::lub::Lub;
 use super::sub::Sub;
-use super::{DefineOpaqueTypes, InferCtxt, TypeTrace};
-use crate::infer::generalize::{self, CombineDelegate, Generalization};
+use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
 use crate::traits::{Obligation, PredicateObligations};
 use rustc_middle::infer::canonical::OriginalQueryValues;
 use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue};
@@ -103,15 +103,19 @@ impl<'tcx> InferCtxt<'tcx> {
             }
 
             // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
-            (
-                ty::Alias(..),
-                ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
-            )
-            | (
-                ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
-                ty::Alias(..),
-            ) if self.next_trait_solver() => {
-                bug!()
+            (ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..))
+                if self.next_trait_solver() =>
+            {
+                bug!(
+                    "We do not expect to encounter `TyVar` this late in combine \
+                    -- they should have been handled earlier"
+                )
+            }
+            (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)))
+            | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _)
+                if self.next_trait_solver() =>
+            {
+                bug!("We do not expect to encounter `Fresh` variables in the new solver")
             }
 
             (_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
@@ -172,7 +176,7 @@ impl<'tcx> InferCtxt<'tcx> {
             // two const param's types are able to be equal has to go through a canonical query with the actual logic
             // in `rustc_trait_selection`.
             let canonical = self.canonicalize_query(
-                (relation.param_env(), a.ty(), b.ty()),
+                relation.param_env().and((a.ty(), b.ty())),
                 &mut OriginalQueryValues::default(),
             );
             self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
@@ -548,7 +552,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
     }
 
     pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
-        self.obligations.extend(obligations.into_iter());
+        self.obligations.extend(obligations);
     }
 
     pub fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>) {
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/relate/equate.rs
index 5d929394eb0..9943c638a91 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/relate/equate.rs
@@ -1,8 +1,6 @@
-use crate::infer::DefineOpaqueTypes;
-use crate::traits::PredicateObligations;
-
 use super::combine::{CombineFields, ObligationEmittingRelation};
-use super::Subtype;
+use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
+use crate::traits::PredicateObligations;
 
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::GenericArgsRef;
@@ -133,7 +131,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
         b: ty::Region<'tcx>,
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
-        let origin = Subtype(Box::new(self.fields.trace.clone()));
+        let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         self.fields
             .infcx
             .inner
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 383f3bdbe23..66f7b08ee12 100644
--- a/compiler/rustc_infer/src/infer/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -16,7 +16,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin};
 /// Attempts to generalize `term` for the type variable `for_vid`.
 /// This checks for cycles -- that is, whether the type `term`
 /// references `for_vid`.
-pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
+pub fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
     infcx: &InferCtxt<'tcx>,
     delegate: &mut D,
     term: T,
@@ -54,7 +54,7 @@ pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>>
 
 /// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
 /// in the generalizer code.
-pub(super) trait GeneralizerDelegate<'tcx> {
+pub trait GeneralizerDelegate<'tcx> {
     fn param_env(&self) -> ty::ParamEnv<'tcx>;
 
     fn forbid_inference_vars() -> bool;
@@ -64,7 +64,7 @@ pub(super) trait GeneralizerDelegate<'tcx> {
     fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
 }
 
-pub(super) struct CombineDelegate<'cx, 'tcx> {
+pub struct CombineDelegate<'cx, 'tcx> {
     pub infcx: &'cx InferCtxt<'tcx>,
     pub param_env: ty::ParamEnv<'tcx>,
     pub span: Span,
@@ -515,7 +515,7 @@ where
 /// not only the generalized type, but also a bool flag
 /// indicating whether further WF checks are needed.
 #[derive(Debug)]
-pub(super) struct Generalization<T> {
+pub struct Generalization<T> {
     /// When generalizing `<?0 as Trait>::Assoc` or
     /// `<T as Bar<<?0 as Foo>::Assoc>>::Assoc`
     /// for `?0` generalization returns an inference
@@ -524,7 +524,7 @@ pub(super) struct Generalization<T> {
     /// This has to be handled wotj care as it can
     /// otherwise very easily result in infinite
     /// recursion.
-    pub(super) value_may_be_infer: T,
+    pub value_may_be_infer: T,
 
     /// If true, then the generalized type may not be well-formed,
     /// even if the source type is well-formed, so we should add an
@@ -551,5 +551,5 @@ pub(super) struct Generalization<T> {
     /// will force the calling code to check that `WF(Foo<?C, ?D>)`
     /// holds, which in turn implies that `?C::Item == ?D`. So once
     /// `?C` is constrained, that should suffice to restrict `?D`.
-    pub(super) needs_wf: bool,
+    pub needs_wf: bool,
 }
diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs
index 2f659d9a665..6a3413879c4 100644
--- a/compiler/rustc_infer/src/infer/glb.rs
+++ b/compiler/rustc_infer/src/infer/relate/glb.rs
@@ -1,13 +1,12 @@
 //! Greatest lower bound. See [`lattice`].
 
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+
 use super::combine::{CombineFields, ObligationEmittingRelation};
 use super::lattice::{self, LatticeDir};
-use super::Subtype;
-use super::{DefineOpaqueTypes, InferCtxt};
-
+use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 use crate::traits::{ObligationCause, PredicateObligations};
-use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
 /// "Greatest lower bound" (common subtype)
 pub struct Glb<'combine, 'infcx, 'tcx> {
@@ -68,7 +67,7 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
 
-        let origin = Subtype(Box::new(self.fields.trace.clone()));
+        let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         // GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
         Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
             self.tcx(),
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index 510b1797d3c..440df8c8936 100644
--- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -2,8 +2,8 @@
 //! the end of the file for details.
 
 use super::combine::CombineFields;
-use super::{HigherRankedType, InferCtxt};
 use crate::infer::CombinedSnapshot;
+use crate::infer::{HigherRankedType, InferCtxt};
 use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable};
diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index 9ef35429fe3..744e2dfa380 100644
--- a/compiler/rustc_infer/src/infer/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -18,10 +18,10 @@
 //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
 
 use super::combine::ObligationEmittingRelation;
-use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use super::{DefineOpaqueTypes, InferCtxt};
-
+use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use crate::infer::{DefineOpaqueTypes, InferCtxt};
 use crate::traits::ObligationCause;
+
 use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::TyVar;
 use rustc_middle::ty::{self, Ty};
diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs
index e41ec7e6c01..41cd98ed0cf 100644
--- a/compiler/rustc_infer/src/infer/lub.rs
+++ b/compiler/rustc_infer/src/infer/relate/lub.rs
@@ -2,10 +2,9 @@
 
 use super::combine::{CombineFields, ObligationEmittingRelation};
 use super::lattice::{self, LatticeDir};
-use super::Subtype;
-use super::{DefineOpaqueTypes, InferCtxt};
-
+use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 use crate::traits::{ObligationCause, PredicateObligations};
+
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
@@ -68,7 +67,7 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
 
-        let origin = Subtype(Box::new(self.fields.trace.clone()));
+        let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         // LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8
         Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
             self.tcx(),
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
new file mode 100644
index 00000000000..f688c2b74a6
--- /dev/null
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -0,0 +1,12 @@
+//! This module contains the definitions of most `TypeRelation`s in the type system
+//! (except for some relations used for diagnostics and heuristics in the compiler).
+
+pub(super) mod combine;
+mod equate;
+pub(super) mod generalize;
+mod glb;
+mod higher_ranked;
+mod lattice;
+mod lub;
+pub mod nll;
+mod sub;
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/relate/nll.rs
index d707c30206d..afc2a8b2f62 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/nll.rs
@@ -30,8 +30,8 @@ use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
 use rustc_span::{Span, Symbol};
 use std::fmt::Debug;
 
-use crate::infer::combine::ObligationEmittingRelation;
-use crate::infer::generalize::{self, Generalization};
+use super::combine::ObligationEmittingRelation;
+use super::generalize::{self, Generalization};
 use crate::infer::InferCtxt;
 use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::traits::{Obligation, PredicateObligations};
@@ -247,7 +247,9 @@ where
         let (a, b) = match (a.kind(), b.kind()) {
             (&ty::Alias(ty::Opaque, ..), _) => (a, generalize(b, false)?),
             (_, &ty::Alias(ty::Opaque, ..)) => (generalize(a, true)?, b),
-            _ => unreachable!(),
+            _ => unreachable!(
+                "expected at least one opaque type in `relate_opaques`, got {a} and {b}."
+            ),
         };
         let cause = ObligationCause::dummy_with_span(self.delegate.span());
         let obligations = self
@@ -707,7 +709,9 @@ where
             ),
             // FIXME(deferred_projection_equality): Implement this when we trigger it.
             // Probably just need to do nothing here.
-            ty::Variance::Bivariant => unreachable!(),
+            ty::Variance::Bivariant => {
+                unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)")
+            }
         })]);
     }
 }
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/relate/sub.rs
index 0c3bb633b53..5a623e48c93 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/relate/sub.rs
@@ -1,7 +1,7 @@
 use super::combine::CombineFields;
-use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
-
+use crate::infer::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
 use crate::traits::{Obligation, PredicateObligations};
+
 use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::TyVar;
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index a26e676c521..b9be178916c 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -135,7 +135,7 @@ pub enum FulfillmentErrorCode<'tcx> {
     CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
     CodeConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>),
     CodeAmbiguity {
-        /// Overflow reported from the new solver `-Ztrait-solver=next`, which will
+        /// Overflow reported from the new solver `-Znext-solver`, which will
         /// be reported as an regular error as opposed to a fatal error.
         overflow: bool,
     },
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index ce58b2ab061..d96b1ba88f5 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -6,10 +6,9 @@ use rustc_session::config::{
     build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
     DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs,
     FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay,
-    LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, OomStrategy, Options,
-    OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius,
-    ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, TraitSolver,
-    WasiExecModel,
+    LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, NextSolverConfig,
+    OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius,
+    ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
 };
 use rustc_session::lint::Level;
 use rustc_session::search_paths::SearchPath;
@@ -748,6 +747,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
     tracked!(debug_info_for_profiling, true);
     tracked!(debug_macros, true);
+    tracked!(default_hidden_visibility, Some(true));
     tracked!(dep_info_omit_d_target, true);
     tracked!(dual_proc_macros, true);
     tracked!(dwarf_version, Some(5));
@@ -780,6 +780,10 @@ fn test_unstable_options_tracking_hash() {
     tracked!(mir_opt_level, Some(4));
     tracked!(move_size_limit, Some(4096));
     tracked!(mutable_noalias, false);
+    tracked!(
+        next_solver,
+        Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() })
+    );
     tracked!(no_generate_arange_section, true);
     tracked!(no_jump_tables, true);
     tracked!(no_link, true);
@@ -821,7 +825,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(thir_unsafeck, true);
     tracked!(tiny_const_eval_limit, true);
     tracked!(tls_model, Some(TlsModel::GeneralDynamic));
-    tracked!(trait_solver, TraitSolver::NextCoherence);
     tracked!(translate_remapped_path_to_local_path, false);
     tracked!(trap_unreachable, Some(false));
     tracked!(treat_err_as_bug, NonZeroUsize::new(1));
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 32eb67ba3a1..045ff38c056 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2800,7 +2800,7 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
                             NAMED_ASM_LABELS,
                             Some(target_spans),
                             fluent::lint_builtin_asm_labels,
-                            |lint| lint,
+                            |_| {},
                             BuiltinLintDiagnostics::NamedAsmLabel(
                                 "only local labels of the form `<number>:` should be used in inline asm"
                                     .to_string(),
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 024e542d4af..c7a9d5e80ac 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -520,9 +520,6 @@ pub trait LintContext {
     /// Emit a lint at the appropriate level, with an optional associated span and an existing
     /// diagnostic.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed
-    /// explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn lookup_with_diagnostics(
@@ -530,9 +527,7 @@ pub trait LintContext {
         lint: &'static Lint,
         span: Option<impl Into<MultiSpan>>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
         diagnostic: BuiltinLintDiagnostics,
     ) {
         // We first generate a blank diagnostic.
@@ -706,9 +701,13 @@ pub trait LintContext {
                 },
                 BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
                     let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().copied().collect();
+                    let is_from_cargo = std::env::var_os("CARGO").is_some();
+                    let mut is_feature_cfg = name == sym::feature;
 
+                    if is_feature_cfg && is_from_cargo {
+                        db.help("consider defining some features in `Cargo.toml`");
                     // Suggest the most probable if we found one
-                    if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
+                    } else if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
                         if let Some(ExpectedValues::Some(best_match_values)) =
                             sess.parse_sess.check_config.expecteds.get(&best_match) {
                             let mut possibilities = best_match_values.iter()
@@ -741,8 +740,8 @@ pub trait LintContext {
                         } else {
                             db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect);
                         }
-                    } else if name == sym::feature && std::env::var_os("CARGO").is_some() {
-                        db.help("consider defining some features in `Cargo.toml`");
+
+                        is_feature_cfg |= best_match == sym::feature;
                     } else if !possibilities.is_empty() {
                         let mut possibilities = possibilities.iter()
                             .map(Symbol::as_str)
@@ -756,6 +755,23 @@ pub trait LintContext {
                         // once.
                         db.help_once(format!("expected names are: `{possibilities}`"));
                     }
+
+                    let inst = if let Some((value, _value_span)) = value {
+                        let pre = if is_from_cargo { "\\" } else { "" };
+                        format!("cfg({name}, values({pre}\"{value}{pre}\"))")
+                    } else {
+                        format!("cfg({name})")
+                    };
+
+                    if is_from_cargo {
+                        if !is_feature_cfg {
+                            db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
+                        }
+                        db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
+                    } else {
+                        db.help(format!("to expect this configuration use `--check-cfg={inst}`"));
+                        db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration");
+                    }
                 },
                 BuiltinLintDiagnostics::UnexpectedCfgValue((name, name_span), value) => {
                     let Some(ExpectedValues::Some(values)) = &sess.parse_sess.check_config.expecteds.get(&name) else {
@@ -767,6 +783,7 @@ pub trait LintContext {
                         .copied()
                         .flatten()
                         .collect();
+                    let is_from_cargo = std::env::var_os("CARGO").is_some();
 
                     // 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
@@ -787,6 +804,8 @@ pub trait LintContext {
                                 db.span_suggestion(value_span, "there is a expected value with a similar name", format!("\"{best_match}\""), Applicability::MaybeIncorrect);
 
                             }
+                        } else if name == sym::feature && is_from_cargo {
+                            db.help(format!("consider defining `{name}` as feature in `Cargo.toml`"));
                         } else if let &[first_possibility] = &possibilities[..] {
                             db.span_suggestion(name_span.shrink_to_hi(), "specify a config value", format!(" = \"{first_possibility}\""), Applicability::MaybeIncorrect);
                         }
@@ -796,6 +815,27 @@ pub trait LintContext {
                             db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect);
                         }
                     }
+
+                    let inst = if let Some((value, _value_span)) = value {
+                        let pre = if is_from_cargo { "\\" } else { "" };
+                        format!("cfg({name}, values({pre}\"{value}{pre}\"))")
+                    } else {
+                        format!("cfg({name})")
+                    };
+
+                    if is_from_cargo {
+                        if name == sym::feature {
+                            if let Some((value, _value_span)) = value {
+                                db.help(format!("consider adding `{value}` as a feature in `Cargo.toml`"));
+                            }
+                        } else {
+                            db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
+                        }
+                        db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
+                    } else {
+                        db.help(format!("to expect this configuration use `--check-cfg={inst}`"));
+                        db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration");
+                    }
                 },
                 BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(new_span, suggestion) => {
                     db.multipart_suggestion(
@@ -941,8 +981,6 @@ pub trait LintContext {
     // set the span in their `decorate` function (preferably using set_span).
     /// Emit a lint at the appropriate level, with an optional associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn lookup<S: Into<MultiSpan>>(
@@ -950,9 +988,7 @@ pub trait LintContext {
         lint: &'static Lint,
         span: Option<S>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     );
 
     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
@@ -963,13 +999,13 @@ pub trait LintContext {
         span: S,
         decorator: impl for<'a> DecorateLint<'a, ()>,
     ) {
-        self.lookup(lint, Some(span), decorator.msg(), |diag| decorator.decorate_lint(diag));
+        self.lookup(lint, Some(span), decorator.msg(), |diag| {
+            decorator.decorate_lint(diag);
+        });
     }
 
     /// Emit a lint at the appropriate level, with an associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn struct_span_lint<S: Into<MultiSpan>>(
@@ -977,9 +1013,7 @@ pub trait LintContext {
         lint: &'static Lint,
         span: S,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         self.lookup(lint, Some(span), msg, decorate);
     }
@@ -988,23 +1022,19 @@ pub trait LintContext {
     /// generated by `#[derive(LintDiagnostic)]`).
     fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) {
         self.lookup(lint, None as Option<Span>, decorator.msg(), |diag| {
-            decorator.decorate_lint(diag)
+            decorator.decorate_lint(diag);
         });
     }
 
     /// Emit a lint at the appropriate level, with no associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn lint(
         &self,
         lint: &'static Lint,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         self.lookup(lint, None as Option<Span>, msg, decorate);
     }
@@ -1068,9 +1098,7 @@ impl<'tcx> LintContext for LateContext<'tcx> {
         lint: &'static Lint,
         span: Option<S>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let hir_id = self.last_node_with_lint_attrs;
 
@@ -1097,9 +1125,7 @@ impl LintContext for EarlyContext<'_> {
         lint: &'static Lint,
         span: Option<S>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate)
     }
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 4c7f9eeff8c..b9add9e9f06 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -45,13 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
     fn inlined_check_id(&mut self, id: ast::NodeId) {
         for early_lint in self.context.buffered.take(id) {
             let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint;
-            self.context.lookup_with_diagnostics(
-                lint_id.lint,
-                Some(span),
-                msg,
-                |lint| lint,
-                diagnostic,
-            );
+            self.context.lookup_with_diagnostics(lint_id.lint, Some(span), msg, |_| {}, diagnostic);
         }
     }
 
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 823ede1222c..53d99c7f7f3 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -34,7 +34,7 @@ declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
 impl LateLintPass<'_> for DefaultHashTypes {
     fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
         let Res::Def(rustc_hir::def::DefKind::Struct, def_id) = path.res else { return };
-        if matches!(cx.tcx.hir().get(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
+        if matches!(cx.tcx.hir_node(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
             // don't lint imports, only actual usages
             return;
         }
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index c1d4ed37627..8c8ff3fc650 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -1077,7 +1077,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                             GateIssue::Language,
                             lint_from_cli,
                         );
-                        lint
                     },
                 );
                 return false;
@@ -1094,8 +1093,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     /// Used to emit a lint-related diagnostic based on the current state of
     /// this lint context.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     #[track_caller]
@@ -1104,9 +1101,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         lint: &'static Lint,
         span: Option<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let (level, src) = self.lint_level(lint);
         struct_lint_level(self.sess, lint, level, src, span, msg, decorate)
@@ -1121,7 +1116,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     ) {
         let (level, src) = self.lint_level(lint);
         struct_lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| {
-            decorate.decorate_lint(lint)
+            decorate.decorate_lint(lint);
         });
     }
 
@@ -1129,7 +1124,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> DecorateLint<'a, ()>) {
         let (level, src) = self.lint_level(lint);
         struct_lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| {
-            decorate.decorate_lint(lint)
+            decorate.decorate_lint(lint);
         });
     }
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 83414ee702f..a4ab5527e3f 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -509,6 +509,11 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, see PR #104616 \
          <https://github.com/rust-lang/rust/pull/104616> for more information",
     );
+    store.register_removed(
+        "implied_bounds_entailment",
+        "converted into hard error, see PR #117984 \
+        <https://github.com/rust-lang/rust/pull/117984> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index d0b895f7354..ca6408bdf3d 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -134,12 +134,8 @@ pub struct BuiltinMissingDebugImpl<'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("debug", self.tcx.def_path_str(self.def_id));
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -243,17 +239,13 @@ pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
 }
 
 impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.span_label(self.label, fluent::lint_label);
         rustc_session::parse::add_feature_diagnostics(
             diag,
             self.parse_sess,
             sym::async_fn_track_caller,
         );
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -433,10 +425,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> {
 }
 
 impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("ty", self.ty);
         diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
         if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
@@ -447,7 +436,6 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
             );
         }
         self.sub.add_to_diagnostic(diag);
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1159,10 +1147,7 @@ pub struct NonFmtPanicUnused {
 
 // Used because of two suggestions based on one Option<Span>
 impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("count", self.count);
         diag.note(fluent::lint_note);
         if let Some(span) = self.suggestion {
@@ -1179,7 +1164,6 @@ impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
                 Applicability::MachineApplicable,
             );
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1358,12 +1342,9 @@ pub struct DropTraitConstraintsDiag<'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("predicate", self.predicate);
-        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
+        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1378,11 +1359,8 @@ pub struct DropGlue<'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
-        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
+        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1655,10 +1633,7 @@ pub struct ImproperCTypes<'a> {
 
 // Used because of the complexity of Option<DiagnosticMessage>, DiagnosticMessage, and Option<Span>
 impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("ty", self.ty);
         diag.set_arg("desc", self.desc);
         diag.span_label(self.label, fluent::lint_label);
@@ -1669,7 +1644,6 @@ impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
         if let Some(note) = self.span_note {
             diag.span_note(note, fluent::lint_note);
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1802,10 +1776,7 @@ pub enum UnusedDefSuggestion {
 
 // Needed because of def_path_str
 impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("pre", self.pre);
         diag.set_arg("post", self.post);
         diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
@@ -1816,7 +1787,6 @@ impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
         if let Some(sugg) = self.suggestion {
             diag.subdiagnostic(sugg);
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1889,15 +1859,11 @@ pub struct AsyncFnInTraitDiag {
 }
 
 impl<'a> DecorateLint<'a, ()> for AsyncFnInTraitDiag {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.note(fluent::lint_note);
         if let Some(sugg) = self.sugg {
             diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect);
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index f0e415492ae..9fcd70ba0b5 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -126,7 +126,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
         lint.note(fluent::lint_more_info_note);
         if !is_arg_inside_call(arg_span, span) {
             // No clue where this argument is coming from.
-            return lint;
+            return;
         }
         if arg_macro.is_some_and(|id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
             // A case of `panic!(format!(..))`.
@@ -207,7 +207,6 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 }
             }
         }
-        lint
     });
 }
 
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 82483ac7dc0..96290288f07 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -37,59 +37,73 @@ declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]);
 
 impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else {
-            return;
-        };
-
-        let init = cx.expr_or_init(e);
-
-        let Some(ty_has_interior_mutability) = is_cast_from_const_to_mut(cx, init) else {
-            return;
-        };
-        let orig_cast = if init.span != e.span { Some(init.span) } else { None };
-        let ty_has_interior_mutability = ty_has_interior_mutability.then_some(());
-
-        cx.emit_spanned_lint(
-            INVALID_REFERENCE_CASTING,
-            expr.span,
-            if is_assignment {
-                InvalidReferenceCastingDiag::AssignToRef { orig_cast, ty_has_interior_mutability }
-            } else {
-                InvalidReferenceCastingDiag::BorrowAsMut { orig_cast, ty_has_interior_mutability }
-            },
-        );
+        if let Some((e, pat)) = borrow_or_assign(cx, expr) {
+            if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign) {
+                let init = cx.expr_or_init(e);
+
+                let Some(ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr(cx, init) else {
+                    return;
+                };
+                let orig_cast = if init.span != e.span { Some(init.span) } else { None };
+                let ty_has_interior_mutability = ty_has_interior_mutability.then_some(());
+
+                cx.emit_spanned_lint(
+                    INVALID_REFERENCE_CASTING,
+                    expr.span,
+                    if pat == PatternKind::Assign {
+                        InvalidReferenceCastingDiag::AssignToRef {
+                            orig_cast,
+                            ty_has_interior_mutability,
+                        }
+                    } else {
+                        InvalidReferenceCastingDiag::BorrowAsMut {
+                            orig_cast,
+                            ty_has_interior_mutability,
+                        }
+                    },
+                );
+            }
+        }
     }
 }
 
-fn is_operation_we_care_about<'tcx>(
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+enum PatternKind {
+    Borrow { mutbl: Mutability },
+    Assign,
+}
+
+fn borrow_or_assign<'tcx>(
     cx: &LateContext<'tcx>,
     e: &'tcx Expr<'tcx>,
-) -> Option<(bool, &'tcx Expr<'tcx>)> {
-    fn deref_assign_or_addr_of<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(bool, &'tcx Expr<'tcx>)> {
-        // &mut <expr>
-        let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
-            expr
+) -> Option<(&'tcx Expr<'tcx>, PatternKind)> {
+    fn deref_assign_or_addr_of<'tcx>(
+        expr: &'tcx Expr<'tcx>,
+    ) -> Option<(&'tcx Expr<'tcx>, PatternKind)> {
+        // &(mut) <expr>
+        let (inner, pat) = if let ExprKind::AddrOf(_, mutbl, expr) = expr.kind {
+            (expr, PatternKind::Borrow { mutbl })
         // <expr> = ...
         } else if let ExprKind::Assign(expr, _, _) = expr.kind {
-            expr
+            (expr, PatternKind::Assign)
         // <expr> += ...
         } else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
-            expr
+            (expr, PatternKind::Assign)
         } else {
             return None;
         };
 
-        if let ExprKind::Unary(UnOp::Deref, e) = &inner.kind {
-            Some((!matches!(expr.kind, ExprKind::AddrOf(..)), e))
-        } else {
-            None
-        }
+        // *<inner>
+        let ExprKind::Unary(UnOp::Deref, e) = &inner.kind else {
+            return None;
+        };
+        Some((e, pat))
     }
 
     fn ptr_write<'tcx>(
         cx: &LateContext<'tcx>,
         e: &'tcx Expr<'tcx>,
-    ) -> Option<(bool, &'tcx Expr<'tcx>)> {
+    ) -> Option<(&'tcx Expr<'tcx>, PatternKind)> {
         if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind
             && let ExprKind::Path(ref qpath) = path.kind
             && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
@@ -98,7 +112,7 @@ fn is_operation_we_care_about<'tcx>(
                 Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned)
             )
         {
-            Some((true, arg_ptr))
+            Some((arg_ptr, PatternKind::Assign))
         } else {
             None
         }
@@ -107,13 +121,10 @@ fn is_operation_we_care_about<'tcx>(
     deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e))
 }
 
-fn is_cast_from_const_to_mut<'tcx>(
+fn is_cast_from_ref_to_mut_ptr<'tcx>(
     cx: &LateContext<'tcx>,
     orig_expr: &'tcx Expr<'tcx>,
 ) -> Option<bool> {
-    let mut need_check_freeze = false;
-    let mut e = orig_expr;
-
     let end_ty = cx.typeck_results().node_type(orig_expr.hir_id);
 
     // Bail out early if the end type is **not** a mutable pointer.
@@ -121,6 +132,28 @@ fn is_cast_from_const_to_mut<'tcx>(
         return None;
     }
 
+    let (e, need_check_freeze) = peel_casts(cx, orig_expr);
+
+    let start_ty = cx.typeck_results().node_type(e.hir_id);
+    if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
+        // If an UnsafeCell method is involved, we need to additionally check the
+        // inner type for the presence of the Freeze trait (ie does NOT contain
+        // an UnsafeCell), since in that case we would incorrectly lint on valid casts.
+        //
+        // Except on the presence of non concrete skeleton types (ie generics)
+        // since there is no way to make it safe for arbitrary types.
+        let inner_ty_has_interior_mutability =
+            !inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton();
+        (!need_check_freeze || !inner_ty_has_interior_mutability)
+            .then_some(inner_ty_has_interior_mutability)
+    } else {
+        None
+    }
+}
+
+fn peel_casts<'tcx>(cx: &LateContext<'tcx>, mut e: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, bool) {
+    let mut gone_trough_unsafe_cell_raw_get = false;
+
     loop {
         e = e.peel_blocks();
         // <expr> as ...
@@ -145,27 +178,18 @@ fn is_cast_from_const_to_mut<'tcx>(
             )
         {
             if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
-                need_check_freeze = true;
+                gone_trough_unsafe_cell_raw_get = true;
             }
             arg
         } else {
-            break;
+            let init = cx.expr_or_init(e);
+            if init.hir_id != e.hir_id {
+                init
+            } else {
+                break;
+            }
         };
     }
 
-    let start_ty = cx.typeck_results().node_type(e.hir_id);
-    if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
-        // If an UnsafeCell method is involved we need to additionally check the
-        // inner type for the presence of the Freeze trait (ie does NOT contain
-        // an UnsafeCell), since in that case we would incorrectly lint on valid casts.
-        //
-        // We also consider non concrete skeleton types (ie generics)
-        // to be an issue since there is no way to make it safe for abitrary types.
-        let inner_ty_has_interior_mutability =
-            !inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton();
-        (!need_check_freeze || !inner_ty_has_interior_mutability)
-            .then_some(inner_ty_has_interior_mutability)
-    } else {
-        None
-    }
+    (e, gone_trough_unsafe_cell_raw_get)
 }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 810d691d16a..6dade43a183 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -202,7 +202,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
 ) -> bool {
     // Look past casts to support cases like `0..256 as u8`
     let (expr, lit_span) = if let Node::Expr(par_expr) =
-        cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id))
+        cx.tcx.hir_node(cx.tcx.hir().parent_id(expr.hir_id))
         && let ExprKind::Cast(_, _) = par_expr.kind
     {
         (par_expr, expr.span)
@@ -213,7 +213,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
     // We only want to handle exclusive (`..`) ranges,
     // which are represented as `ExprKind::Struct`.
     let par_id = cx.tcx.hir().parent_id(expr.hir_id);
-    let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false };
+    let Node::ExprField(field) = cx.tcx.hir_node(par_id) else { return false };
     let Node::Expr(struct_expr) = cx.tcx.hir().get_parent(field.hir_id) else { return false };
     if !is_range_literal(struct_expr) {
         return false;
@@ -498,7 +498,7 @@ fn lint_uint_literal<'tcx>(
     };
     if lit_val < min || lit_val > max {
         let parent_id = cx.tcx.hir().parent_id(e.hir_id);
-        if let Node::Expr(par_e) = cx.tcx.hir().get(parent_id) {
+        if let Node::Expr(par_e) = cx.tcx.hir_node(parent_id) {
             match par_e.kind {
                 hir::ExprKind::Cast(..) => {
                     if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index e6e445c54b1..f9b66239bf9 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -47,7 +47,6 @@ declare_lint_pass! {
         HIDDEN_GLOB_REEXPORTS,
         ILL_FORMED_ATTRIBUTE_INPUT,
         ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
-        IMPLIED_BOUNDS_ENTAILMENT,
         INCOMPLETE_INCLUDE,
         INDIRECT_STRUCTURAL_MATCH,
         INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
@@ -4236,47 +4235,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `implied_bounds_entailment` lint detects cases where the arguments of an impl method
-    /// have stronger implied bounds than those from the trait method it's implementing.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// #![deny(implied_bounds_entailment)]
-    ///
-    /// trait Trait {
-    ///     fn get<'s>(s: &'s str, _: &'static &'static ()) -> &'static str;
-    /// }
-    ///
-    /// impl Trait for () {
-    ///     fn get<'s>(s: &'s str, _: &'static &'s ()) -> &'static str {
-    ///         s
-    ///     }
-    /// }
-    ///
-    /// let val = <() as Trait>::get(&String::from("blah blah blah"), &&());
-    /// println!("{}", val);
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Neither the trait method, which provides no implied bounds about `'s`, nor the impl,
-    /// requires the main function to prove that 's: 'static, but the impl method is allowed
-    /// to assume that `'s: 'static` within its own body.
-    ///
-    /// This can be used to implement an unsound API if used incorrectly.
-    pub IMPLIED_BOUNDS_ENTAILMENT,
-    Deny,
-    "impl method assumes more implied bounds than its corresponding trait method",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #105572 <https://github.com/rust-lang/rust/issues/105572>",
-    };
-}
-
-declare_lint! {
     /// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field
     /// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or
     /// more built-in traits.
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index 31ad9cdb216..cd61544f69d 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -175,9 +175,9 @@ impl<'a> LintDiagnosticDerive<'a> {
                 fn decorate_lint<'__b>(
                     self,
                     #diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>
-                ) -> &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> {
+                ) {
                     use rustc_errors::IntoDiagnosticArg;
-                    #implementation
+                    #implementation;
                 }
 
                 fn msg(&self) -> rustc_errors::DiagnosticMessage {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 143e439bd57..ad3fea65e82 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1144,7 +1144,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
             let origin = tcx.opaque_type_origin(def_id);
             if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
             | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
-                && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
+                && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
                 && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
             {
                 false
@@ -1161,7 +1161,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
             }
         }
         DefKind::TyParam => {
-            let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(def_id) else { bug!() };
+            let hir::Node::GenericParam(param) = tcx.hir_node_by_def_id(def_id) else { bug!() };
             let hir::GenericParamKind::Type { default, .. } = param.kind else { bug!() };
             default.is_some()
         }
@@ -1372,7 +1372,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             // anonymous constants will not work on them and panic. It's not clear whether it
             // can cause any observable issues or not.
             let anon_const_without_hir = def_kind == DefKind::AnonConst
-                && tcx.hir().find(tcx.local_def_id_to_hir_id(local_id)).is_none();
+                && tcx.opt_hir_node(tcx.local_def_id_to_hir_id(local_id)).is_none();
             if should_encode_generics(def_kind) && !anon_const_without_hir {
                 let g = tcx.generics_of(def_id);
                 record!(self.tables.generics_of[def_id] <- g);
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 4af886a9718..598c26de23f 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -57,6 +57,10 @@ fn is_body_owner(node: Node<'_>, hir_id: HirId) -> bool {
     }
 }
 
+// FIXME: the structure was necessary in the past but now it
+// only serves as "namespace" for HIR-related methods, and can be
+// removed if all the methods are reasonably renamed and moved to tcx
+// (https://github.com/rust-lang/rust/pull/118256#issuecomment-1826442834).
 #[derive(Copy, Clone)]
 pub struct Map<'hir> {
     pub(super) tcx: TyCtxt<'hir>,
@@ -128,6 +132,40 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
     }
 }
 
+impl<'tcx> TyCtxt<'tcx> {
+    /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
+    pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> {
+        if id.local_id == ItemLocalId::from_u32(0) {
+            let owner = self.hir_owner(id.owner)?;
+            Some(owner.node.into())
+        } else {
+            let owner = self.hir_owner_nodes(id.owner).as_owner()?;
+            let node = owner.nodes[id.local_id].as_ref()?;
+            Some(node.node)
+        }
+    }
+
+    /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
+    #[inline]
+    pub fn opt_hir_node_by_def_id(self, id: LocalDefId) -> Option<Node<'tcx>> {
+        self.opt_hir_node(self.opt_local_def_id_to_hir_id(id)?)
+    }
+
+    /// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
+    #[track_caller]
+    pub fn hir_node(self, id: HirId) -> Node<'tcx> {
+        self.opt_hir_node(id).unwrap_or_else(|| bug!("couldn't find HIR node for hir id {id:?}"))
+    }
+
+    /// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
+    #[inline]
+    #[track_caller]
+    pub fn hir_node_by_def_id(self, id: LocalDefId) -> Node<'tcx> {
+        self.opt_hir_node_by_def_id(id)
+            .unwrap_or_else(|| bug!("couldn't find HIR node for def id {id:?}"))
+    }
+}
+
 impl<'hir> Map<'hir> {
     #[inline]
     pub fn krate(self) -> &'hir Crate<'hir> {
@@ -191,46 +229,15 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn get_parent(self, hir_id: HirId) -> Node<'hir> {
-        self.get(self.parent_id(hir_id))
+        self.tcx.hir_node(self.parent_id(hir_id))
     }
 
     pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
-        self.find(self.opt_parent_id(hir_id)?)
-    }
-
-    /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
-    pub fn find(self, id: HirId) -> Option<Node<'hir>> {
-        if id.local_id == ItemLocalId::from_u32(0) {
-            let owner = self.tcx.hir_owner(id.owner)?;
-            Some(owner.node.into())
-        } else {
-            let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
-            let node = owner.nodes[id.local_id].as_ref()?;
-            Some(node.node)
-        }
-    }
-
-    /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
-    #[inline]
-    pub fn find_by_def_id(self, id: LocalDefId) -> Option<Node<'hir>> {
-        self.find(self.tcx.opt_local_def_id_to_hir_id(id)?)
-    }
-
-    /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
-    #[track_caller]
-    pub fn get(self, id: HirId) -> Node<'hir> {
-        self.find(id).unwrap_or_else(|| bug!("couldn't find hir id {} in the HIR map", id))
-    }
-
-    /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
-    #[inline]
-    #[track_caller]
-    pub fn get_by_def_id(self, id: LocalDefId) -> Node<'hir> {
-        self.find_by_def_id(id).unwrap_or_else(|| bug!("couldn't find {:?} in the HIR map", id))
+        self.tcx.opt_hir_node(self.opt_parent_id(hir_id)?)
     }
 
     pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
-        id.as_local().and_then(|id| self.find(self.tcx.opt_local_def_id_to_hir_id(id)?))
+        id.as_local().and_then(|id| self.tcx.opt_hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?))
     }
 
     pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
@@ -264,7 +271,7 @@ impl<'hir> Map<'hir> {
 
     #[track_caller]
     pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
-        if let Some(node) = self.find(hir_id) {
+        if let Some(node) = self.tcx.opt_hir_node(hir_id) {
             node.fn_decl()
         } else {
             bug!("no node for hir_id `{}`", hir_id)
@@ -273,7 +280,7 @@ impl<'hir> Map<'hir> {
 
     #[track_caller]
     pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
-        if let Some(node) = self.find(hir_id) {
+        if let Some(node) = self.tcx.opt_hir_node(hir_id) {
             node.fn_sig()
         } else {
             bug!("no node for hir_id `{}`", hir_id)
@@ -296,19 +303,22 @@ impl<'hir> Map<'hir> {
     /// item (possibly associated), a closure, or a `hir::AnonConst`.
     pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
         let parent = self.parent_id(hir_id);
-        assert!(self.find(parent).is_some_and(|n| is_body_owner(n, hir_id)), "{hir_id:?}");
+        assert!(
+            self.tcx.opt_hir_node(parent).is_some_and(|n| is_body_owner(n, hir_id)),
+            "{hir_id:?}"
+        );
         parent
     }
 
     pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId {
         let parent = self.parent_id(hir_id);
-        associated_body(self.get(parent)).unwrap().0
+        associated_body(self.tcx.hir_node(parent)).unwrap().0
     }
 
     /// Given a `LocalDefId`, returns the `BodyId` associated with it,
     /// if the node is a body owner, otherwise returns `None`.
     pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<BodyId> {
-        let node = self.find_by_def_id(id)?;
+        let node = self.tcx.opt_hir_node_by_def_id(id)?;
         let (_, body_id) = associated_body(node)?;
         Some(body_id)
     }
@@ -548,7 +558,7 @@ impl<'hir> Map<'hir> {
     /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
     #[inline]
     pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
-        self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?)))
+        self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.tcx.opt_hir_node(id)?)))
     }
 
     /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
@@ -600,7 +610,7 @@ impl<'hir> Map<'hir> {
     pub fn get_return_block(self, id: HirId) -> Option<HirId> {
         let mut iter = self.parent_iter(id).peekable();
         let mut ignore_tail = false;
-        if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.find(id) {
+        if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.tcx.opt_hir_node(id) {
             // When dealing with `return` statements, we don't care about climbing only tail
             // expressions.
             ignore_tail = true;
@@ -708,7 +718,7 @@ impl<'hir> Map<'hir> {
         let mut scope = id;
         loop {
             scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID);
-            if scope == CRATE_HIR_ID || !matches!(self.get(scope), Node::Block(_)) {
+            if scope == CRATE_HIR_ID || !matches!(self.tcx.hir_node(scope), Node::Block(_)) {
                 return scope;
             }
         }
@@ -764,7 +774,7 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> {
-        match self.find(id) {
+        match self.tcx.opt_hir_node(id) {
             Some(Node::Variant(variant)) => variant,
             _ => bug!("expected variant, found {}", self.node_to_string(id)),
         }
@@ -783,7 +793,7 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
-        match self.find(id) {
+        match self.tcx.opt_hir_node(id) {
             Some(Node::Expr(expr)) => expr,
             _ => bug!("expected expr, found {}", self.node_to_string(id)),
         }
@@ -791,7 +801,7 @@ impl<'hir> Map<'hir> {
 
     #[inline]
     fn opt_ident(self, id: HirId) -> Option<Ident> {
-        match self.find(id)? {
+        match self.tcx.opt_hir_node(id)? {
             Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
             // A `Ctor` doesn't have an identifier itself, but its parent
             // struct/variant does. Compare with `hir::Map::opt_span`.
@@ -860,7 +870,7 @@ impl<'hir> Map<'hir> {
             }
         }
 
-        let span = match self.find(hir_id)? {
+        let span = match self.tcx.opt_hir_node(hir_id)? {
             // Function-like.
             Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
             | Node::TraitItem(TraitItem {
@@ -950,7 +960,7 @@ impl<'hir> Map<'hir> {
     /// Like `hir.span()`, but includes the body of items
     /// (instead of just the item header)
     pub fn span_with_body(self, hir_id: HirId) -> Span {
-        match self.get(hir_id) {
+        match self.tcx.hir_node(hir_id) {
             Node::Param(param) => param.span,
             Node::Item(item) => item.span,
             Node::ForeignItem(foreign_item) => foreign_item.span,
@@ -1045,7 +1055,7 @@ impl<'hir> Map<'hir> {
 
 impl<'hir> intravisit::Map<'hir> for Map<'hir> {
     fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
-        (*self).find(hir_id)
+        self.tcx.opt_hir_node(hir_id)
     }
 
     fn body(&self, id: BodyId) -> &'hir Body<'hir> {
@@ -1159,7 +1169,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
     let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default();
     let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
 
-    match map.find(id) {
+    match map.tcx.opt_hir_node(id) {
         Some(Node::Item(item)) => {
             let item_str = match item.kind {
                 ItemKind::ExternCrate(..) => "extern crate",
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index a16317a0c67..af99c7d55c3 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -195,7 +195,7 @@ pub fn provide(providers: &mut Providers) {
         | Node::ForeignItem(&ForeignItem {
             kind: ForeignItemKind::Fn(_, idents, _),
             ..
-        }) = hir.get(hir_id)
+        }) = tcx.hir_node(hir_id)
         {
             idents
         } else {
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index ef5a1caadb7..e544c2a26e8 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -21,17 +21,20 @@
 //!
 //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
 
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::Lock;
 use rustc_macros::HashStable;
 use rustc_type_ir::Canonical as IrCanonical;
 use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo;
 pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind};
 use smallvec::SmallVec;
+use std::collections::hash_map::Entry;
 use std::ops::Index;
 
 use crate::infer::MemberConstraint;
 use crate::mir::ConstraintCategory;
 use crate::ty::GenericArg;
-use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt};
+use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
 
 pub type Canonical<'tcx, V> = IrCanonical<TyCtxt<'tcx>, V>;
 
@@ -291,3 +294,62 @@ impl<'tcx> Index<BoundVar> for CanonicalVarValues<'tcx> {
         &self.var_values[value.as_usize()]
     }
 }
+
+#[derive(Default)]
+pub struct CanonicalParamEnvCache<'tcx> {
+    map: Lock<
+        FxHashMap<
+            ty::ParamEnv<'tcx>,
+            (Canonical<'tcx, ty::ParamEnv<'tcx>>, &'tcx [GenericArg<'tcx>]),
+        >,
+    >,
+}
+
+impl<'tcx> CanonicalParamEnvCache<'tcx> {
+    /// Gets the cached canonical form of `key` or executes
+    /// `canonicalize_op` and caches the result if not present.
+    ///
+    /// `canonicalize_op` is intentionally not allowed to be a closure to
+    /// statically prevent it from capturing `InferCtxt` and resolving
+    /// inference variables, which invalidates the cache.
+    pub fn get_or_insert(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        key: ty::ParamEnv<'tcx>,
+        state: &mut OriginalQueryValues<'tcx>,
+        canonicalize_op: fn(
+            TyCtxt<'tcx>,
+            ty::ParamEnv<'tcx>,
+            &mut OriginalQueryValues<'tcx>,
+        ) -> Canonical<'tcx, ty::ParamEnv<'tcx>>,
+    ) -> Canonical<'tcx, ty::ParamEnv<'tcx>> {
+        if !key.has_type_flags(
+            TypeFlags::HAS_INFER | TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_FREE_REGIONS,
+        ) {
+            return Canonical {
+                max_universe: ty::UniverseIndex::ROOT,
+                variables: List::empty(),
+                value: key,
+            };
+        }
+
+        assert_eq!(state.var_values.len(), 0);
+        assert_eq!(state.universe_map.len(), 1);
+        debug_assert_eq!(&*state.universe_map, &[ty::UniverseIndex::ROOT]);
+
+        match self.map.borrow().entry(key) {
+            Entry::Occupied(e) => {
+                let (canonical, var_values) = e.get();
+                state.var_values.extend_from_slice(var_values);
+                *canonical
+            }
+            Entry::Vacant(e) => {
+                let canonical = canonicalize_op(tcx, key, state);
+                let OriginalQueryValues { var_values, universe_map } = state;
+                assert_eq!(universe_map.len(), 1);
+                e.insert((canonical, tcx.arena.alloc_slice(var_values)));
+                canonical
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index eada116f896..4c4f38d1ad8 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -253,29 +253,10 @@ pub fn explain_lint_level_source(
 /// - [`TyCtxt::struct_lint_node`]
 /// - `LintContext::lookup`
 ///
-/// ## `decorate` signature
+/// ## `decorate`
 ///
-/// The return value of `decorate` is ignored by this function. So what is the
-/// point of returning `&'b mut DiagnosticBuilder<'a, ()>`?
-///
-/// There are 2 reasons for this signature.
-///
-/// First of all, it prevents accidental use of `.emit()` -- it's clear that the
-/// builder will be later used and shouldn't be emitted right away (this is
-/// especially important because the old API expected you to call `.emit()` in
-/// the closure).
-///
-/// Second of all, it makes the most common case of adding just a single label
-/// /suggestion much nicer, since [`DiagnosticBuilder`] methods return
-/// `&mut DiagnosticBuilder`, you can just chain methods, without needed
-/// awkward `{ ...; }`:
-/// ```ignore pseudo-code
-/// struct_lint_level(
-///     ...,
-///     |lint| lint.span_label(sp, "lbl")
-///     //          ^^^^^^^^^^^^^^^^^^^^^ returns `&mut DiagnosticBuilder` by default
-/// )
-/// ```
+/// It is not intended to call `emit`/`cancel` on the `DiagnosticBuilder` passed
+/// in the `decorate` callback.
 #[track_caller]
 pub fn struct_lint_level(
     sess: &Session,
@@ -284,9 +265,7 @@ pub fn struct_lint_level(
     src: LintLevelSource,
     span: Option<MultiSpan>,
     msg: impl Into<DiagnosticMessage>,
-    decorate: impl for<'a, 'b> FnOnce(
-        &'b mut DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut DiagnosticBuilder<'a, ()>,
+    decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
 ) {
     // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
     // the "real" work.
@@ -298,12 +277,7 @@ pub fn struct_lint_level(
         src: LintLevelSource,
         span: Option<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: Box<
-            dyn '_
-                + for<'a, 'b> FnOnce(
-                    &'b mut DiagnosticBuilder<'a, ()>,
-                ) -> &'b mut DiagnosticBuilder<'a, ()>,
-        >,
+        decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>)>,
     ) {
         // Check for future incompatibility lints and issue a stronger warning.
         let future_incompatible = lint.future_incompatible;
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index 9a633e04ce7..2899e629d79 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -36,6 +36,17 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
+    /// Given a [`ty::ClosureKind`], get the [`DefId`] of its corresponding `Fn`-family
+    /// trait, if it is defined.
+    pub fn fn_trait_kind_to_def_id(self, kind: ty::ClosureKind) -> Option<DefId> {
+        let items = self.lang_items();
+        match kind {
+            ty::ClosureKind::Fn => items.fn_trait(),
+            ty::ClosureKind::FnMut => items.fn_mut_trait(),
+            ty::ClosureKind::FnOnce => items.fn_once_trait(),
+        }
+    }
+
     /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits.
     pub fn is_fn_trait(self, id: DefId) -> bool {
         self.fn_trait_kind_from_def_id(id).is_some()
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 30f13afff9a..3f6dc2b9f12 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -180,7 +180,7 @@ impl Scope {
         };
         let span = tcx.hir().span(hir_id);
         if let ScopeData::Remainder(first_statement_index) = self.data {
-            if let Node::Block(blk) = tcx.hir().get(hir_id) {
+            if let Node::Block(blk) = tcx.hir_node(hir_id) {
                 // Want span for scope starting after the
                 // indexed statement and ending at end of
                 // `blk`; reuse span of `blk` and shift `lo`
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 27d82f5fefc..0cba6d5b52a 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -219,11 +219,10 @@ fn late_report_deprecation(
     }
     let method_span = method_span.unwrap_or(span);
     tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| {
-        if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
+        if let hir::Node::Expr(_) = tcx.hir_node(hir_id) {
             let kind = tcx.def_descr(def_id);
             deprecation_suggestion(diag, kind, suggestion, method_span);
         }
-        diag
     });
 }
 
@@ -587,7 +586,7 @@ impl<'tcx> TyCtxt<'tcx> {
         unmarked: impl FnOnce(Span, DefId),
     ) -> bool {
         let soft_handler = |lint, span, msg: String| {
-            self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |lint| lint)
+            self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {})
         };
         let eval_result =
             self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 34068a9da37..092b59deeff 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -113,7 +113,7 @@ impl<'tcx> TyCtxt<'tcx> {
                                 self.local_def_id_to_hir_id(local_def_id),
                                 self.def_span(ct.def),
                                 "cannot use constants which depend on generic parameters in types",
-                                |err| err,
+                                |_| {},
                             )
                         }
                     }
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index ea6b44d62b0..93a9bbf64c9 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -15,7 +15,6 @@ TrivialTypeTraversalImpls! {
     UserTypeAnnotationIndex,
     BorrowKind,
     CastKind,
-    hir::Movability,
     BasicBlock,
     SwitchTargets,
     CoroutineKind,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 03f3ceb8d17..a69bff6ed8c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2177,7 +2177,9 @@ rustc_queries! {
     /// Used in `super_combine_consts` to ICE if the type of the two consts are definitely not going to end up being
     /// equal to eachother. This might return `Ok` even if the types are not equal, but will never return `Err` if
     /// the types might be equal.
-    query check_tys_might_be_eq(arg: Canonical<'tcx, (ty::ParamEnv<'tcx>, Ty<'tcx>, Ty<'tcx>)>) -> Result<(), NoSolution> {
+    query check_tys_might_be_eq(
+        arg: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>
+    ) -> Result<(), NoSolution> {
         desc { "check whether two const param are definitely not equal to eachother"}
     }
 
diff --git a/compiler/rustc_middle/src/traits/solve/cache.rs b/compiler/rustc_middle/src/traits/solve/cache.rs
index e9e9cc418a6..4f90af0a27c 100644
--- a/compiler/rustc_middle/src/traits/solve/cache.rs
+++ b/compiler/rustc_middle/src/traits/solve/cache.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::sync::Lock;
 use rustc_query_system::cache::WithDepNode;
 use rustc_query_system::dep_graph::DepNodeIndex;
 use rustc_session::Limit;
-/// The trait solver cache used by `-Ztrait-solver=next`.
+/// The trait solver cache used by `-Znext-solver`.
 ///
 /// FIXME(@lcnr): link to some official documentation of how
 /// this works.
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index eaf5da130dd..8c29bc5a428 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -7,14 +7,13 @@ use std::fmt::Write;
 
 use crate::query::Providers;
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{self as hir, LangItem};
+use rustc_hir as hir;
+use rustc_hir::def_id::LocalDefId;
 use rustc_span::def_id::LocalDefIdMap;
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, Symbol};
 
-use super::{Ty, TyCtxt};
+use super::TyCtxt;
 
 use self::BorrowKind::*;
 
@@ -73,72 +72,6 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureLis
 /// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.
 pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;
 
-/// Represents the various closure traits in the language. This
-/// will determine the type of the environment (`self`, in the
-/// desugaring) argument that the closure expects.
-///
-/// You can get the environment type of a closure using
-/// `tcx.closure_env_ty()`.
-#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable)]
-pub enum ClosureKind {
-    // Warning: Ordering is significant here! The ordering is chosen
-    // because the trait Fn is a subtrait of FnMut and so in turn, and
-    // hence we order it so that Fn < FnMut < FnOnce.
-    Fn,
-    FnMut,
-    FnOnce,
-}
-
-impl ClosureKind {
-    /// This is the initial value used when doing upvar inference.
-    pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
-
-    pub const fn as_str(self) -> &'static str {
-        match self {
-            ClosureKind::Fn => "Fn",
-            ClosureKind::FnMut => "FnMut",
-            ClosureKind::FnOnce => "FnOnce",
-        }
-    }
-
-    /// Returns `true` if a type that impls this closure kind
-    /// must also implement `other`.
-    pub fn extends(self, other: ty::ClosureKind) -> bool {
-        self <= other
-    }
-
-    /// Converts `self` to a [`DefId`] of the corresponding trait.
-    ///
-    /// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`].
-    pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
-        tcx.require_lang_item(
-            match self {
-                ClosureKind::Fn => LangItem::Fn,
-                ClosureKind::FnMut => LangItem::FnMut,
-                ClosureKind::FnOnce => LangItem::FnOnce,
-            },
-            None,
-        )
-    }
-
-    /// Returns the representative scalar type for this closure kind.
-    /// See `Ty::to_opt_closure_kind` for more details.
-    pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match self {
-            ClosureKind::Fn => tcx.types.i8,
-            ClosureKind::FnMut => tcx.types.i16,
-            ClosureKind::FnOnce => tcx.types.i32,
-        }
-    }
-}
-
-impl IntoDiagnosticArg for ClosureKind {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Str(self.as_str().into())
-    }
-}
-
 /// A composite describing a `Place` that is captured by a closure.
 #[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 #[derive(TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index b99e5a4f813..2d3ee33489e 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -59,7 +59,7 @@ impl<'tcx> Const<'tcx> {
 
     #[inline]
     pub fn kind(self) -> ConstKind<'tcx> {
-        self.0.kind.clone()
+        self.0.kind
     }
 
     #[inline]
@@ -167,7 +167,7 @@ impl<'tcx> Const<'tcx> {
     /// becomes `Unevaluated`.
     #[instrument(skip(tcx), level = "debug")]
     pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
-        let body_id = match tcx.hir().get_by_def_id(def) {
+        let body_id = match tcx.hir_node_by_def_id(def) {
             hir::Node::AnonConst(ac) => ac.body,
             _ => span_bug!(
                 tcx.def_span(def.to_def_id()),
@@ -443,7 +443,7 @@ impl<'tcx> Const<'tcx> {
 }
 
 pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Const<'_>> {
-    let default_def_id = match tcx.hir().get_by_def_id(def_id) {
+    let default_def_id = match tcx.hir_node_by_def_id(def_id) {
         hir::Node::GenericParam(hir::GenericParam {
             kind: hir::GenericParamKind::Const { default: Some(ac), .. },
             ..
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 9d99344d5bd..310cf113b11 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -71,7 +71,7 @@ impl std::fmt::Debug for ConstInt {
                         (4, _) => write!(fmt, "_i32")?,
                         (8, _) => write!(fmt, "_i64")?,
                         (16, _) => write!(fmt, "_i128")?,
-                        _ => bug!(),
+                        (sz, _) => bug!("unexpected int size i{sz}"),
                     }
                 }
                 Ok(())
@@ -105,7 +105,7 @@ impl std::fmt::Debug for ConstInt {
                         (4, _) => write!(fmt, "_u32")?,
                         (8, _) => write!(fmt, "_u64")?,
                         (16, _) => write!(fmt, "_u128")?,
-                        _ => bug!(),
+                        (sz, _) => bug!("unexpected unsigned int size u{sz}"),
                     }
                 }
                 Ok(())
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index eb6fde83fcc..6a6ed59fabf 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -6,7 +6,7 @@ pub mod tls;
 
 use crate::arena::Arena;
 use crate::dep_graph::{DepGraph, DepKindStruct};
-use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
+use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
 use crate::lint::struct_lint_level;
 use crate::metadata::ModChild;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
@@ -28,7 +28,7 @@ use crate::ty::{
     self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
     ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
     PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
-    TypeAndMut, Visibility,
+    Visibility,
 };
 use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 use rustc_ast::{self as ast, attr};
@@ -88,7 +88,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type Term = ty::Term<'tcx>;
 
     type Binder<T> = Binder<'tcx, T>;
-    type TypeAndMut = TypeAndMut<'tcx>;
     type CanonicalVars = CanonicalVarInfos<'tcx>;
 
     type Ty = Ty<'tcx>;
@@ -128,12 +127,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type CoercePredicate = ty::CoercePredicate<'tcx>;
     type ClosureKind = ty::ClosureKind;
 
-    fn ty_and_mut_to_parts(
-        TypeAndMut { ty, mutbl }: TypeAndMut<'tcx>,
-    ) -> (Self::Ty, ty::Mutability) {
-        (ty, mutbl)
-    }
-
     fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
         self.mk_canonical_var_infos(infos)
     }
@@ -653,6 +646,8 @@ pub struct GlobalCtxt<'tcx> {
     pub new_solver_evaluation_cache: solve::EvaluationCache<'tcx>,
     pub new_solver_coherence_evaluation_cache: solve::EvaluationCache<'tcx>,
 
+    pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
+
     /// Data layout specification for the current target.
     pub data_layout: TargetDataLayout,
 
@@ -817,6 +812,7 @@ impl<'tcx> TyCtxt<'tcx> {
             evaluation_cache: Default::default(),
             new_solver_evaluation_cache: Default::default(),
             new_solver_coherence_evaluation_cache: Default::default(),
+            canonical_param_env_cache: Default::default(),
             data_layout,
             alloc_map: Lock::new(interpret::AllocMap::new()),
         }
@@ -1174,7 +1170,7 @@ impl<'tcx> TyCtxt<'tcx> {
             break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
         };
 
-        let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {
+        let is_impl_item = match self.opt_hir_node_by_def_id(suitable_region_binding_scope) {
             Some(Node::Item(..) | Node::TraitItem(..)) => false,
             Some(Node::ImplItem(..)) => {
                 self.is_bound_region_in_impl_item(suitable_region_binding_scope)
@@ -1217,8 +1213,8 @@ impl<'tcx> TyCtxt<'tcx> {
                 None,
                 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
             && let Some(local_id) = def_id.as_local()
-            && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias
-            && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics()
+            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
+            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
         {
             v.visit_ty(alias_ty);
             if !v.0.is_empty() {
@@ -2034,14 +2030,12 @@ impl<'tcx> TyCtxt<'tcx> {
         let msg = decorator.msg();
         let (level, src) = self.lint_level_at_node(lint, hir_id);
         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
-            decorator.decorate_lint(diag)
+            decorator.decorate_lint(diag);
         })
     }
 
     /// Emit a lint at the appropriate level for a hir node, with an associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     #[track_caller]
@@ -2051,9 +2045,7 @@ impl<'tcx> TyCtxt<'tcx> {
         hir_id: HirId,
         span: impl Into<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let (level, src) = self.lint_level_at_node(lint, hir_id);
         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
@@ -2068,13 +2060,13 @@ impl<'tcx> TyCtxt<'tcx> {
         id: HirId,
         decorator: impl for<'a> DecorateLint<'a, ()>,
     ) {
-        self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
+        self.struct_lint_node(lint, id, decorator.msg(), |diag| {
+            decorator.decorate_lint(diag);
+        })
     }
 
     /// Emit a lint at the appropriate level for a hir node.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     #[track_caller]
@@ -2083,9 +2075,7 @@ impl<'tcx> TyCtxt<'tcx> {
         lint: &'static Lint,
         id: HirId,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let (level, src) = self.lint_level_at_node(lint, id);
         struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
@@ -2137,7 +2127,7 @@ impl<'tcx> TyCtxt<'tcx> {
         loop {
             let parent = self.local_parent(rpit_lifetime_param_def_id);
             let hir::OpaqueTy { lifetime_mapping, .. } =
-                self.hir().get_by_def_id(parent).expect_item().expect_opaque_ty();
+                self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
 
             let Some((lifetime, _)) = lifetime_mapping
                 .iter()
@@ -2221,8 +2211,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_raw(self, def_id: DefId) -> bool {
         let Some(local_def_id) = def_id.as_local() else { return false };
-        let hir_id = self.local_def_id_to_hir_id(local_def_id);
-        let node = self.hir().get(hir_id);
+        let node = self.hir_node_by_def_id(local_def_id);
 
         matches!(
             node,
@@ -2238,15 +2227,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn next_trait_solver_globally(self) -> bool {
-        self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next
+        self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
     }
 
     pub fn next_trait_solver_in_coherence(self) -> bool {
-        matches!(
-            self.sess.opts.unstable_opts.trait_solver,
-            rustc_session::config::TraitSolver::Next
-                | rustc_session::config::TraitSolver::NextCoherence
-        )
+        self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence)
     }
 
     pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 469593fe663..0e44878524b 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -345,33 +345,35 @@ impl<'tcx> TyCtxt<'tcx> {
         short
     }
 
-    pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
+    pub fn short_ty_string(self, ty: Ty<'tcx>, path: &mut Option<PathBuf>) -> String {
         let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
             cx.pretty_print_type(ty)
         })
         .expect("could not write to `String`");
 
         if !self.sess.opts.unstable_opts.write_long_types_to_disk {
-            return (regular, None);
+            return regular;
         }
 
         let width = self.sess.diagnostic_width();
         let length_limit = width.saturating_sub(30);
         if regular.len() <= width {
-            return (regular, None);
+            return regular;
         }
         let short = self.ty_string_with_limit(ty, length_limit);
         if regular == short {
-            return (regular, None);
+            return regular;
         }
-        // Multiple types might be shortened in a single error, ensure we create a file for each.
+        // Ensure we create an unique file for the type passed in when we create a file.
         let mut s = DefaultHasher::new();
         ty.hash(&mut s);
         let hash = s.finish();
-        let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None);
-        match std::fs::write(&path, &regular) {
-            Ok(_) => (short, Some(path)),
-            Err(_) => (regular, None),
+        *path = Some(path.take().unwrap_or_else(|| {
+            self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
+        }));
+        match std::fs::write(path.as_ref().unwrap(), &format!("{regular}\n")) {
+            Ok(_) => short,
+            Err(_) => regular,
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index f95ceeff150..38a9cabca97 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -62,7 +62,7 @@ pub enum TreatParams {
     ///
     /// N.B. during deep rejection, this acts identically to `ForLookup`.
     ///
-    /// FIXME(-Ztrait-solver=next): Remove this variant and cleanup
+    /// FIXME(-Znext-solver): Remove this variant and cleanup
     /// the code.
     NextSolverLookup,
 }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 71ff7021ca5..febab23ea35 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -75,7 +75,7 @@ pub use self::binding::BindingMode;
 pub use self::binding::BindingMode::*;
 pub use self::closure::{
     is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
-    CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
+    CapturedPlace, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
     RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
 };
 pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};
@@ -473,7 +473,7 @@ impl<'tcx> IntoKind for Ty<'tcx> {
     type Kind = TyKind<'tcx>;
 
     fn kind(self) -> TyKind<'tcx> {
-        self.kind().clone()
+        *self.kind()
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 39adfac55ce..8e045397b0f 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1680,7 +1680,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         self.wrap_binder(&sig, |sig, cx| {
             define_scoped_cx!(cx);
 
-            p!(print(kind), "(");
+            p!(write("{kind}("));
             for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
                 if i > 0 {
                     p!(", ");
@@ -2754,6 +2754,10 @@ forward_display_to_print! {
 define_print! {
     (self, cx):
 
+    ty::TypeAndMut<'tcx> {
+        p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
+    }
+
     ty::ClauseKind<'tcx> {
         match *self {
             ty::ClauseKind::Trait(ref data) => {
@@ -2799,10 +2803,6 @@ define_print_and_forward_display! {
         p!("{{", comma_sep(self.iter()), "}}")
     }
 
-    ty::TypeAndMut<'tcx> {
-        p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
-    }
-
     ty::ExistentialTraitRef<'tcx> {
         // Use a type that can't appear in defaults of type parameters.
         let dummy_self = Ty::new_fresh(cx.tcx(),0);
@@ -2943,10 +2943,6 @@ define_print_and_forward_display! {
         }
     }
 
-    ty::ClosureKind {
-        p!(write("{}", self.as_str()))
-    }
-
     ty::Predicate<'tcx> {
         p!(print(self.kind()))
     }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 0cff6b77eb6..1c75d73e552 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -440,7 +440,6 @@ TrivialTypeTraversalImpls! {
 // interners).
 TrivialTypeTraversalAndLiftImpls! {
     ::rustc_hir::def_id::DefId,
-    ::rustc_hir::Mutability,
     ::rustc_hir::Unsafety,
     ::rustc_target::spec::abi::Abi,
     crate::ty::ClosureKind,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 50a1b85b169..a0debc8a165 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -15,7 +15,9 @@ use hir::def::DefKind;
 use polonius_engine::Atom;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::intern::Interned;
-use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan};
+use rustc_errors::{
+    DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
@@ -42,23 +44,18 @@ use rustc_type_ir::PredicateKind as IrPredicateKind;
 use rustc_type_ir::RegionKind as IrRegionKind;
 use rustc_type_ir::TyKind as IrTyKind;
 use rustc_type_ir::TyKind::*;
+use rustc_type_ir::TypeAndMut as IrTypeAndMut;
 
 use super::GenericParamDefKind;
 
-// Re-export the `TyKind` from `rustc_type_ir` here for convenience
+// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
 #[rustc_diagnostic_item = "TyKind"]
 pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
 pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
 pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
 pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
 pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
-pub struct TypeAndMut<'tcx> {
-    pub ty: Ty<'tcx>,
-    pub mutbl: hir::Mutability,
-}
+pub type TypeAndMut<'tcx> = IrTypeAndMut<TyCtxt<'tcx>>;
 
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
 #[derive(HashStable)]
@@ -2005,7 +2002,7 @@ impl<'tcx> Ty<'tcx> {
     pub fn new_error_with_message<S: Into<MultiSpan>>(
         tcx: TyCtxt<'tcx>,
         span: S,
-        msg: impl Into<String>,
+        msg: impl Into<DiagnosticMessage>,
     ) -> Ty<'tcx> {
         let reported = tcx.sess.span_delayed_bug(span, msg);
         Ty::new(tcx, Error(reported))
@@ -2816,6 +2813,15 @@ impl<'tcx> Ty<'tcx> {
         }
     }
 
+    /// Inverse of [`Ty::to_opt_closure_kind`].
+    pub fn from_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> {
+        match kind {
+            ty::ClosureKind::Fn => tcx.types.i8,
+            ty::ClosureKind::FnMut => tcx.types.i16,
+            ty::ClosureKind::FnOnce => tcx.types.i32,
+        }
+    }
+
     /// Fast path helper for testing if a type is `Sized`.
     ///
     /// Returning true means the type is known to be sized. Returning
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 8b1d33848ea..8b2b76764e6 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -421,13 +421,10 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let impl_args = match *self.type_of(impl_def_id).instantiate_identity().kind() {
             ty::Adt(def_, args) if def_ == def => args,
-            _ => bug!(),
+            _ => span_bug!(self.def_span(impl_def_id), "expected ADT for self type of `Drop` impl"),
         };
 
-        let item_args = match *self.type_of(def.did()).instantiate_identity().kind() {
-            ty::Adt(def_, args) if def_ == def => args,
-            _ => bug!(),
-        };
+        let item_args = ty::GenericArgs::identity_for_item(self, def.did());
 
         let result = iter::zip(item_args, impl_args)
             .filter(|&(_, k)| {
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 8ccd3c1aba0..3224f2f26df 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -154,8 +154,9 @@ pub fn recursive_type_error(
         let (_, field_id) = item_and_field_ids[i];
         let (next_item_id, _) = item_and_field_ids[(i + 1) % cycle_len];
         // Find the span(s) that contain the next item in the cycle
-        let hir_id = tcx.local_def_id_to_hir_id(field_id);
-        let hir::Node::Field(field) = tcx.hir().get(hir_id) else { bug!("expected field") };
+        let hir::Node::Field(field) = tcx.hir_node_by_def_id(field_id) else {
+            bug!("expected field")
+        };
         let mut found = Vec::new();
         find_item_ty_spans(tcx, field.ty, next_item_id, &mut found, representable_ids);
 
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 19b6496b102..dae83d4b41b 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -572,7 +572,7 @@ fn construct_const<'a, 'tcx>(
     let hir_id = tcx.local_def_id_to_hir_id(def);
 
     // Figure out what primary body this item has.
-    let (span, const_ty_span) = match tcx.hir().get(hir_id) {
+    let (span, const_ty_span) = match tcx.hir_node(hir_id) {
         Node::Item(hir::Item {
             kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _, _),
             span,
@@ -640,7 +640,9 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
         }
         DefKind::Closure if coroutine_kind.is_some() => {
             let coroutine_ty = tcx.type_of(def_id).instantiate_identity();
-            let ty::Coroutine(_, args, _) = coroutine_ty.kind() else { bug!() };
+            let ty::Coroutine(_, args, _) = coroutine_ty.kind() else {
+                bug!("expected type of coroutine-like closure to be a coroutine")
+            };
             let args = args.as_coroutine();
             let yield_ty = args.yield_ty();
             let return_ty = args.return_ty();
@@ -648,7 +650,9 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
         }
         DefKind::Closure => {
             let closure_ty = tcx.type_of(def_id).instantiate_identity();
-            let ty::Closure(_, args) = closure_ty.kind() else { bug!() };
+            let ty::Closure(_, args) = closure_ty.kind() else {
+                bug!("expected type of closure to be a closure")
+            };
             let args = args.as_closure();
             let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), args.sig());
             let self_ty = match args.kind() {
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 8c4f0257da3..a776e917de5 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -1,7 +1,6 @@
 //! Construction of MIR from HIR.
 //!
 //! This crate also contains the match exhaustiveness and usefulness checking.
-#![allow(rustc::potential_query_instability)]
 #![feature(assert_matches)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 31874b29bb3..ab88463826a 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -782,7 +782,7 @@ impl<'tcx> Cx<'tcx> {
             hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
 
             hir::ExprKind::Yield(v, _) => ExprKind::Yield { value: self.mirror_expr(v) },
-            hir::ExprKind::Err(_) => unreachable!(),
+            hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"),
         };
 
         Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind }
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 4eba7103c0c..fa3dd2afa85 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -110,7 +110,7 @@ impl<'tcx> Cx<'tcx> {
 
     #[instrument(level = "debug", skip(self))]
     fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Box<Pat<'tcx>> {
-        let p = match self.tcx.hir().get(p.hir_id) {
+        let p = match self.tcx.hir_node(p.hir_id) {
             Node::Pat(p) => p,
             node => bug!("pattern became {:?}", node),
         };
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 09e0b30a5c7..792a443c908 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -9,7 +9,7 @@ use crate::errors::*;
 
 use rustc_arena::TypedArena;
 use rustc_ast::Mutability;
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
@@ -948,7 +948,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     err.note(format!("the matched value is of type `{}`", scrut_ty));
 
     if !is_empty_match {
-        let mut non_exhaustive_tys = FxHashSet::default();
+        let mut non_exhaustive_tys = FxIndexSet::default();
         // Look at the first witness.
         collect_non_exhaustive_tys(cx, &witnesses[0], &mut non_exhaustive_tys);
 
@@ -1104,7 +1104,7 @@ fn joined_uncovered_patterns<'p, 'tcx>(
 fn collect_non_exhaustive_tys<'tcx>(
     cx: &MatchCheckCtxt<'_, 'tcx>,
     pat: &WitnessPat<'tcx>,
-    non_exhaustive_tys: &mut FxHashSet<Ty<'tcx>>,
+    non_exhaustive_tys: &mut FxIndexSet<Ty<'tcx>>,
 ) {
     if matches!(pat.ctor(), Constructor::NonExhaustive) {
         non_exhaustive_tys.insert(pat.ty());
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 391d65b338d..a7f23772193 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -492,8 +492,9 @@ impl<'tcx> ConstToPat<'tcx> {
                 PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
             }
             ty::FnPtr(..) => {
-                // Valtree construction would never succeed for these, so this is unreachable.
-                unreachable!()
+                unreachable!(
+                    "Valtree construction would never succeed for FnPtr, so this is unreachable."
+                )
             }
             _ => {
                 let err = InvalidPattern { span, non_sm_ty: ty };
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index af0dab4ebc7..c7762f8ce4e 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -174,7 +174,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         span: Span,
     ) -> Result<PatKind<'tcx>, ErrorGuaranteed> {
         if lo_expr.is_none() && hi_expr.is_none() {
-            let msg = format!("found twice-open range pattern (`..`) outside of error recovery");
+            let msg = "found twice-open range pattern (`..`) outside of error recovery";
             return Err(self.tcx.sess.span_delayed_bug(span, msg));
         }
 
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 071024a0fa3..2802f5491be 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -956,11 +956,7 @@ impl Map {
             // The local is not tracked at all, so it does not alias anything.
             return;
         };
-        let elems = place
-            .projection
-            .iter()
-            .map(|&elem| elem.try_into())
-            .chain(tail_elem.map(Ok).into_iter());
+        let elems = place.projection.iter().map(|&elem| elem.try_into()).chain(tail_elem.map(Ok));
         for elem in elems {
             // A field aliases the parent place.
             if let Some(vi) = self.places[index].value_index {
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 796150f9315..65a0924f1c9 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -13,7 +13,6 @@ use self::spans::CoverageSpans;
 
 use crate::MirPass;
 
-use rustc_data_structures::sync::Lrc;
 use rustc_middle::hir;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::coverage::*;
@@ -22,9 +21,9 @@ use rustc_middle::mir::{
     TerminatorKind,
 };
 use rustc_middle::ty::TyCtxt;
-use rustc_span::def_id::DefId;
+use rustc_span::def_id::LocalDefId;
 use rustc_span::source_map::SourceMap;
-use rustc_span::{ExpnKind, SourceFile, Span, Symbol};
+use rustc_span::{ExpnKind, Span, Symbol};
 
 /// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected
 /// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen
@@ -39,31 +38,19 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) {
         let mir_source = mir_body.source;
 
-        // If the InstrumentCoverage pass is called on promoted MIRs, skip them.
-        // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601
-        if mir_source.promoted.is_some() {
-            trace!(
-                "InstrumentCoverage skipped for {:?} (already promoted for Miri evaluation)",
-                mir_source.def_id()
-            );
-            return;
-        }
+        // This pass runs after MIR promotion, but before promoted MIR starts to
+        // be transformed, so it should never see promoted MIR.
+        assert!(mir_source.promoted.is_none());
+
+        let def_id = mir_source.def_id().expect_local();
 
-        let is_fn_like =
-            tcx.hir().get_by_def_id(mir_source.def_id().expect_local()).fn_kind().is_some();
-
-        // Only instrument functions, methods, and closures (not constants since they are evaluated
-        // at compile time by Miri).
-        // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const
-        // expressions get coverage spans, we will probably have to "carve out" space for const
-        // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might
-        // be tricky if const expressions have no corresponding statements in the enclosing MIR.
-        // Closures are carved out by their initial `Assign` statement.)
-        if !is_fn_like {
-            trace!("InstrumentCoverage skipped for {:?} (not an fn-like)", mir_source.def_id());
+        if !is_eligible_for_coverage(tcx, def_id) {
+            trace!("InstrumentCoverage skipped for {def_id:?} (not eligible)");
             return;
         }
 
+        // An otherwise-eligible function is still skipped if its start block
+        // is known to be unreachable.
         match mir_body.basic_blocks[mir::START_BLOCK].terminator().kind {
             TerminatorKind::Unreachable => {
                 trace!("InstrumentCoverage skipped for unreachable `START_BLOCK`");
@@ -72,21 +59,15 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
             _ => {}
         }
 
-        let codegen_fn_attrs = tcx.codegen_fn_attrs(mir_source.def_id());
-        if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_COVERAGE) {
-            return;
-        }
-
-        trace!("InstrumentCoverage starting for {:?}", mir_source.def_id());
+        trace!("InstrumentCoverage starting for {def_id:?}");
         Instrumentor::new(tcx, mir_body).inject_counters();
-        trace!("InstrumentCoverage done for {:?}", mir_source.def_id());
+        trace!("InstrumentCoverage done for {def_id:?}");
     }
 }
 
 struct Instrumentor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     mir_body: &'a mut mir::Body<'tcx>,
-    source_file: Lrc<SourceFile>,
     fn_sig_span: Span,
     body_span: Span,
     function_source_hash: u64,
@@ -96,37 +77,17 @@ struct Instrumentor<'a, 'tcx> {
 
 impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
     fn new(tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self {
-        let source_map = tcx.sess.source_map();
-        let def_id = mir_body.source.def_id();
-        let (some_fn_sig, hir_body) = fn_sig_and_body(tcx, def_id);
+        let hir_info @ ExtractedHirInfo { function_source_hash, fn_sig_span, body_span } =
+            extract_hir_info(tcx, mir_body.source.def_id().expect_local());
 
-        let body_span = get_body_span(tcx, hir_body, mir_body);
+        debug!(?hir_info, "instrumenting {:?}", mir_body.source.def_id());
 
-        let source_file = source_map.lookup_source_file(body_span.lo());
-        let fn_sig_span = match some_fn_sig.filter(|fn_sig| {
-            fn_sig.span.eq_ctxt(body_span)
-                && Lrc::ptr_eq(&source_file, &source_map.lookup_source_file(fn_sig.span.lo()))
-        }) {
-            Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()),
-            None => body_span.shrink_to_lo(),
-        };
-
-        debug!(
-            "instrumenting {}: {:?}, fn sig span: {:?}, body span: {:?}",
-            if tcx.is_closure(def_id) { "closure" } else { "function" },
-            def_id,
-            fn_sig_span,
-            body_span
-        );
-
-        let function_source_hash = hash_mir_source(tcx, hir_body);
         let basic_coverage_blocks = CoverageGraph::from_mir(mir_body);
         let coverage_counters = CoverageCounters::new(&basic_coverage_blocks);
 
         Self {
             tcx,
             mir_body,
-            source_file,
             fn_sig_span,
             body_span,
             function_source_hash,
@@ -136,15 +97,12 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
     }
 
     fn inject_counters(&'a mut self) {
-        let fn_sig_span = self.fn_sig_span;
-        let body_span = self.body_span;
-
         ////////////////////////////////////////////////////
         // Compute coverage spans from the `CoverageGraph`.
         let coverage_spans = CoverageSpans::generate_coverage_spans(
             self.mir_body,
-            fn_sig_span,
-            body_span,
+            self.fn_sig_span,
+            self.body_span,
             &self.basic_coverage_blocks,
         );
 
@@ -177,9 +135,10 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         let source_map = self.tcx.sess.source_map();
         let body_span = self.body_span;
 
+        let source_file = source_map.lookup_source_file(body_span.lo());
         use rustc_session::RemapFileNameExt;
         let file_name =
-            Symbol::intern(&self.source_file.name.for_codegen(self.tcx.sess).to_string_lossy());
+            Symbol::intern(&source_file.name.for_codegen(self.tcx.sess).to_string_lossy());
 
         let mut mappings = Vec::new();
 
@@ -325,27 +284,75 @@ fn make_code_region(
     }
 }
 
-fn fn_sig_and_body(
-    tcx: TyCtxt<'_>,
-    def_id: DefId,
-) -> (Option<&rustc_hir::FnSig<'_>>, &rustc_hir::Body<'_>) {
+fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
+    // Only instrument functions, methods, and closures (not constants since they are evaluated
+    // at compile time by Miri).
+    // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const
+    // expressions get coverage spans, we will probably have to "carve out" space for const
+    // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might
+    // be tricky if const expressions have no corresponding statements in the enclosing MIR.
+    // Closures are carved out by their initial `Assign` statement.)
+    if !tcx.def_kind(def_id).is_fn_like() {
+        trace!("InstrumentCoverage skipped for {def_id:?} (not an fn-like)");
+        return false;
+    }
+
+    if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_COVERAGE) {
+        return false;
+    }
+
+    true
+}
+
+/// Function information extracted from HIR by the coverage instrumentor.
+#[derive(Debug)]
+struct ExtractedHirInfo {
+    function_source_hash: u64,
+    fn_sig_span: Span,
+    body_span: Span,
+}
+
+fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHirInfo {
     // FIXME(#79625): Consider improving MIR to provide the information needed, to avoid going back
     // to HIR for it.
-    let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local");
+
+    let hir_node = tcx.hir_node_by_def_id(def_id);
     let (_, fn_body_id) =
         hir::map::associated_body(hir_node).expect("HIR node is a function with body");
-    (hir_node.fn_sig(), tcx.hir().body(fn_body_id))
+    let hir_body = tcx.hir().body(fn_body_id);
+
+    let body_span = get_body_span(tcx, hir_body, def_id);
+
+    // The actual signature span is only used if it has the same context and
+    // filename as the body, and precedes the body.
+    let maybe_fn_sig_span = hir_node.fn_sig().map(|fn_sig| fn_sig.span);
+    let fn_sig_span = maybe_fn_sig_span
+        .filter(|&fn_sig_span| {
+            let source_map = tcx.sess.source_map();
+            let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo());
+
+            fn_sig_span.eq_ctxt(body_span)
+                && fn_sig_span.hi() <= body_span.lo()
+                && file_idx(fn_sig_span) == file_idx(body_span)
+        })
+        // If so, extend it to the start of the body span.
+        .map(|fn_sig_span| fn_sig_span.with_hi(body_span.lo()))
+        // Otherwise, create a dummy signature span at the start of the body.
+        .unwrap_or_else(|| body_span.shrink_to_lo());
+
+    let function_source_hash = hash_mir_source(tcx, hir_body);
+
+    ExtractedHirInfo { function_source_hash, fn_sig_span, body_span }
 }
 
 fn get_body_span<'tcx>(
     tcx: TyCtxt<'tcx>,
     hir_body: &rustc_hir::Body<'tcx>,
-    mir_body: &mut mir::Body<'tcx>,
+    def_id: LocalDefId,
 ) -> Span {
     let mut body_span = hir_body.value.span;
-    let def_id = mir_body.source.def_id();
 
-    if tcx.is_closure(def_id) {
+    if tcx.is_closure(def_id.to_def_id()) {
         // If the MIR function is a closure, and if the closure body span
         // starts from a macro, but it's content is not in that macro, try
         // to find a non-macro callsite, and instrument the spans there
diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
index 261d9dd448d..5f01b841867 100644
--- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs
+++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
@@ -22,6 +22,18 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         return false;
     }
 
+    // This just reproduces the logic from Instance::requires_inline.
+    match tcx.def_kind(def_id) {
+        DefKind::Ctor(..) | DefKind::Closure => return true,
+        DefKind::Fn | DefKind::AssocFn => {}
+        _ => return false,
+    }
+
+    // From this point on, it is valid to return true or false.
+    if tcx.sess.opts.unstable_opts.cross_crate_inline_threshold == InliningThreshold::Always {
+        return true;
+    }
+
     // Obey source annotations first; this is important because it means we can use
     // #[inline(never)] to force code generation.
     match codegen_fn_attrs.inline {
@@ -30,13 +42,6 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         _ => {}
     }
 
-    // This just reproduces the logic from Instance::requires_inline.
-    match tcx.def_kind(def_id) {
-        DefKind::Ctor(..) | DefKind::Closure => return true,
-        DefKind::Fn | DefKind::AssocFn => {}
-        _ => return false,
-    }
-
     // Don't do any inference when incremental compilation is enabled; the additional inlining that
     // inference permits also creates more work for small edits.
     if tcx.sess.opts.incremental.is_some() {
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 146cc33e8c6..ad12bce9b02 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -496,7 +496,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
             FlatSet::Elem(scalar) => {
                 let ty = op.ty(self.local_decls, self.tcx);
                 self.tcx.layout_of(self.param_env.and(ty)).map_or(FlatSet::Top, |layout| {
-                    FlatSet::Elem(ImmTy::from_scalar(scalar.into(), layout))
+                    FlatSet::Elem(ImmTy::from_scalar(scalar, layout))
                 })
             }
             FlatSet::Bottom => FlatSet::Bottom,
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 2358661738a..928db471298 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -65,7 +65,7 @@ pub(crate) struct RequiresUnsafe {
 impl<'sess> IntoDiagnostic<'sess> for RequiresUnsafe {
     #[track_caller]
     fn into_diagnostic(self, handler: &'sess Handler) -> DiagnosticBuilder<'sess, ErrorGuaranteed> {
-        let mut diag = handler.struct_diagnostic(fluent::mir_transform_requires_unsafe);
+        let mut diag = handler.struct_err(fluent::mir_transform_requires_unsafe);
         diag.code(rustc_errors::DiagnosticId::Error("E0133".to_string()));
         diag.set_span(self.span);
         diag.span_label(self.span, self.details.label());
@@ -180,10 +180,7 @@ pub(crate) struct UnsafeOpInUnsafeFn {
 
 impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn {
     #[track_caller]
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, ()>) {
         let handler = diag.handler().expect("lint should not yet be emitted");
         let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter());
         diag.set_arg("details", desc);
@@ -198,8 +195,6 @@ impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn {
                 Applicability::MaybeIncorrect,
             );
         }
-
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -213,10 +208,7 @@ pub(crate) enum AssertLint<P> {
 }
 
 impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, ()>) {
         let span = self.span();
         let assert_kind = self.panic();
         let message = assert_kind.diagnostic_message();
@@ -224,8 +216,6 @@ impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> {
             diag.set_arg(name, value);
         });
         diag.span_label(span, message);
-
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -284,10 +274,7 @@ pub(crate) struct MustNotSupend<'tcx, 'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.span_label(self.yield_sp, fluent::_subdiag::label);
         if let Some(reason) = self.reason {
             diag.subdiagnostic(reason);
@@ -296,7 +283,6 @@ impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> {
         diag.set_arg("pre", self.pre);
         diag.set_arg("def_path", self.tcx.def_path_str(self.def_id));
         diag.set_arg("post", self.post);
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index 36a15f47276..a41d8e21245 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -649,7 +649,7 @@ impl OpportunitySet {
 
             // `succ` must be a successor of `current`. If it is not, this means this TO is not
             // satisfiable and a previous TO erased this edge, so we bail out.
-            if basic_blocks[current].terminator().successors().find(|s| *s == succ).is_none() {
+            if !basic_blocks[current].terminator().successors().any(|s| s == succ) {
                 debug!("impossible");
                 return;
             }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 71b3754fac8..feceff10f95 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -176,6 +176,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor;
 use rustc_middle::mir::{self, Location};
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
+use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
     self, AssocKind, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable,
@@ -923,6 +924,21 @@ fn visit_instance_use<'tcx>(
         return;
     }
 
+    // The intrinsics assert_inhabited, assert_zero_valid, and assert_mem_uninitialized_valid will
+    // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
+    // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
+    // codegen a call to that function without generating code for the function itself.
+    if let ty::InstanceDef::Intrinsic(def_id) = instance.def {
+        let name = tcx.item_name(def_id);
+        if let Some(_requirement) = ValidityRequirement::from_intrinsic(name) {
+            let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap();
+            let panic_instance = Instance::mono(tcx, def_id);
+            if should_codegen_locally(tcx, &panic_instance) {
+                output.push(create_fn_mono_item(tcx, panic_instance, source));
+            }
+        }
+    }
+
     match instance.def {
         ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(_) => {
             if !is_direct_call {
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index c2b307910e4..d47d3e5e7d3 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -212,11 +212,17 @@ where
     let cgu_name_cache = &mut FxHashMap::default();
 
     for mono_item in mono_items {
-        // Handle only root items directly here. Inlined items are handled at
-        // the bottom of the loop based on reachability.
+        // Handle only root (GloballyShared) items directly here. Inlined (LocalCopy) items
+        // are handled at the bottom of the loop based on reachability, with one exception.
+        // The #[lang = "start"] item is the program entrypoint, so there are no calls to it in MIR.
+        // So even if its mode is LocalCopy, we need to treat it like a root.
         match mono_item.instantiation_mode(cx.tcx) {
             InstantiationMode::GloballyShared { .. } => {}
-            InstantiationMode::LocalCopy => continue,
+            InstantiationMode::LocalCopy => {
+                if Some(mono_item.def_id()) != cx.tcx.lang_items().start_fn() {
+                    continue;
+                }
+            }
         }
 
         let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
@@ -883,7 +889,7 @@ fn mono_item_visibility<'tcx>(
 }
 
 fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
-    if !tcx.sess.target.default_hidden_visibility {
+    if !tcx.sess.default_hidden_visibility() {
         return Visibility::Default;
     }
 
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index cb1f328577d..ac2e8960b06 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -242,16 +242,10 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
 
             ty::ReVar(vid) => {
                 assert_eq!(
-                    self.infcx.root_lt_var(vid),
-                    vid,
-                    "region vid should have been resolved fully before canonicalization"
-                );
-                assert_eq!(
-                    self.infcx.probe_lt_var(vid),
+                    self.infcx.opportunistic_resolve_lt_var(vid),
                     None,
                     "region vid should have been resolved fully before canonicalization"
                 );
-
                 match self.canonicalize_mode {
                     CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
                     CanonicalizeMode::Response { .. } => {
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index bc53ab83439..c51a5c095ee 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1046,7 +1046,7 @@ impl<'a> IntoDiagnostic<'a> for ExpectedIdentifier {
     ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> {
         let token_descr = TokenDescription::from_token(&self.token);
 
-        let mut diag = handler.struct_diagnostic(match token_descr {
+        let mut diag = handler.struct_err(match token_descr {
             Some(TokenDescription::ReservedIdentifier) => {
                 fluent::parse_expected_identifier_found_reserved_identifier_str
             }
@@ -1103,7 +1103,7 @@ impl<'a> IntoDiagnostic<'a> for ExpectedSemi {
     ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> {
         let token_descr = TokenDescription::from_token(&self.token);
 
-        let mut diag = handler.struct_diagnostic(match token_descr {
+        let mut diag = handler.struct_err(match token_descr {
             Some(TokenDescription::ReservedIdentifier) => {
                 fluent::parse_expected_semi_found_reserved_identifier_str
             }
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index bbfb160ebf7..0dc60688955 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -350,8 +350,7 @@ pub(super) fn check_for_substitution(
 
     let Some((_, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(s, _, _)| s == ascii_str) else {
         let msg = format!("substitution character not found for '{ch}'");
-        reader.sess.span_diagnostic.span_bug_no_panic(span, msg);
-        return (None, None);
+        reader.sess.span_diagnostic.span_bug(span, msg);
     };
 
     // special help suggestion for "directed" double quotes
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 95352dbdc13..9887a85e6a4 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -51,8 +51,8 @@ macro_rules! panictry_buffer {
         match $e {
             Ok(e) => e,
             Err(errs) => {
-                for mut e in errs {
-                    $handler.emit_diagnostic(&mut e);
+                for e in errs {
+                    $handler.emit_diagnostic(e);
                 }
                 FatalError.raise()
             }
@@ -165,8 +165,8 @@ fn try_file_to_source_file(
 fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) -> Lrc<SourceFile> {
     match try_file_to_source_file(sess, path, spanopt) {
         Ok(source_file) => source_file,
-        Err(mut d) => {
-            sess.span_diagnostic.emit_diagnostic(&mut d);
+        Err(d) => {
+            sess.span_diagnostic.emit_diagnostic(d);
             FatalError.raise();
         }
     }
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 5295172b25e..221fc70d9ff 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -249,8 +249,8 @@ impl<'a> Parser<'a> {
         self.diagnostic().struct_span_err(sp, m)
     }
 
-    pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: impl Into<String>) -> ! {
-        self.diagnostic().span_bug(sp, m)
+    pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! {
+        self.diagnostic().span_bug(sp, msg)
     }
 
     pub(super) fn diagnostic(&self) -> &'a Handler {
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 5b0011e9f70..509cef9826b 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1440,21 +1440,23 @@ impl<'a> Parser<'a> {
             } else if this.eat_keyword(kw::Underscore) {
                 Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore))
             } else if this.token.uninterpolated_span().at_least_rust_2018() {
-                // `Span:.at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
-                if this.check_keyword(kw::Async) {
+                // `Span::at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
+                if this.token.uninterpolated_span().at_least_rust_2024()
+                    // check for `gen {}` and `gen move {}`
+                    // or `async gen {}` and `async gen move {}`
+                    && (this.is_gen_block(kw::Gen, 0)
+                        || (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1)))
+                {
+                    // FIXME: (async) gen closures aren't yet parsed.
+                    this.parse_gen_block()
+                } else if this.check_keyword(kw::Async) {
                     // FIXME(gen_blocks): Parse `gen async` and suggest swap
                     if this.is_gen_block(kw::Async, 0) {
                         // Check for `async {` and `async move {`,
-                        // or `async gen {` and `async gen move {`.
                         this.parse_gen_block()
                     } else {
                         this.parse_expr_closure()
                     }
-                } else if this.token.uninterpolated_span().at_least_rust_2024()
-                    && (this.is_gen_block(kw::Gen, 0)
-                        || (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1)))
-                {
-                    this.parse_gen_block()
                 } else if this.eat_keyword_noexpect(kw::Await) {
                     this.recover_incorrect_await_syntax(lo, this.prev_token.span)
                 } else {
@@ -3227,9 +3229,16 @@ impl<'a> Parser<'a> {
             if self.eat_keyword(kw::Gen) { GenBlockKind::AsyncGen } else { GenBlockKind::Async }
         } else {
             assert!(self.eat_keyword(kw::Gen));
-            self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.token.span));
             GenBlockKind::Gen
         };
+        match kind {
+            GenBlockKind::Async => {
+                // `async` blocks are stable
+            }
+            GenBlockKind::Gen | GenBlockKind::AsyncGen => {
+                self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.prev_token.span));
+            }
+        }
         let capture_clause = self.parse_capture_clause()?;
         let (attrs, body) = self.parse_inner_attrs_and_block()?;
         let kind = ExprKind::Gen(capture_clause, body, kind);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 89919247e82..fd7dad36c9d 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -923,7 +923,7 @@ impl<'a> Parser<'a> {
         );
         let where_predicates_split = before_where_clause.predicates.len();
         let mut predicates = before_where_clause.predicates;
-        predicates.extend(after_where_clause.predicates.into_iter());
+        predicates.extend(after_where_clause.predicates);
         let where_clause = WhereClause {
             has_where_token: before_where_clause.has_where_token
                 || after_where_clause.has_where_token,
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 81055431f64..d10c8c92257 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -215,7 +215,7 @@ fn emit_malformed_attribute(
                 } else {
                     "the following are the possible correct uses"
                 },
-                suggestions.into_iter(),
+                suggestions,
                 Applicability::HasPlaceholders,
             )
             .emit();
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 4910d63010c..c5073048be3 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -604,7 +604,7 @@ impl CheckAttrVisitor<'_> {
                     && !self.tcx.sess.target.is_like_wasm
                     && !self.tcx.sess.opts.actually_rustdoc
                 {
-                    let hir::Node::Item(item) = self.tcx.hir().get(hir_id) else {
+                    let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else {
                         unreachable!();
                     };
                     let hir::ItemKind::Fn(sig, _, _) = item.kind else {
@@ -820,7 +820,7 @@ impl CheckAttrVisitor<'_> {
             self.doc_attr_str_error(meta, "keyword");
             return false;
         }
-        match self.tcx.hir().find(hir_id).and_then(|node| match node {
+        match self.tcx.opt_hir_node(hir_id).and_then(|node| match node {
             hir::Node::Item(item) => Some(&item.kind),
             _ => None,
         }) {
@@ -846,7 +846,7 @@ impl CheckAttrVisitor<'_> {
     }
 
     fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool {
-        match self.tcx.hir().find(hir_id).and_then(|node| match node {
+        match self.tcx.opt_hir_node(hir_id).and_then(|node| match node {
             hir::Node::Item(item) => Some(&item.kind),
             _ => None,
         }) {
@@ -1387,7 +1387,7 @@ impl CheckAttrVisitor<'_> {
     /// Checks if `#[link]` is applied to an item other than a foreign module.
     fn check_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
         if target == Target::ForeignMod
-            && let hir::Node::Item(item) = self.tcx.hir().get(hir_id)
+            && let hir::Node::Item(item) = self.tcx.hir_node(hir_id)
             && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item
             && !matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic)
         {
@@ -1456,7 +1456,7 @@ impl CheckAttrVisitor<'_> {
     }
 
     fn is_impl_item(&self, hir_id: HirId) -> bool {
-        matches!(self.tcx.hir().get(hir_id), hir::Node::ImplItem(..))
+        matches!(self.tcx.hir_node(hir_id), hir::Node::ImplItem(..))
     }
 
     /// Checks if `#[export_name]` is applied to a function or static. Returns `true` if valid.
@@ -2074,7 +2074,7 @@ impl CheckAttrVisitor<'_> {
             && let hir::Node::Item(Item {
                 kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. },
                 ..
-            }) = hir.get(parent)
+            }) = self.tcx.hir_node(parent)
         {
             return true;
         }
@@ -2222,7 +2222,7 @@ impl CheckAttrVisitor<'_> {
         } else {
             // special case when `#[macro_export]` is applied to a macro 2.0
             let (macro_definition, _) =
-                self.tcx.hir().find(hir_id).unwrap().expect_item().expect_macro();
+                self.tcx.opt_hir_node(hir_id).unwrap().expect_item().expect_macro();
             let is_decl_macro = !macro_definition.macro_rules;
 
             if is_decl_macro {
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 7d1cc81e21f..d270794978b 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -32,7 +32,7 @@ use crate::errors::{
 // may need to be marked as live.
 fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     matches!(
-        tcx.hir().find_by_def_id(def_id),
+        tcx.opt_hir_node_by_def_id(def_id),
         Some(
             Node::Item(..)
                 | Node::ImplItem(..)
@@ -297,7 +297,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
             // tuple struct constructor function
             let id = self.struct_constructors.get(&id).copied().unwrap_or(id);
 
-            if let Some(node) = self.tcx.hir().find_by_def_id(id) {
+            if let Some(node) = self.tcx.opt_hir_node_by_def_id(id) {
                 // When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement
                 // by declaring fn calls, statics, ... within said items as live, as well as
                 // the item itself, although technically this is not the case.
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index d8b9f4fae87..5f767c9acaa 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -83,6 +83,9 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
 
     // Collect diagnostic items in other crates.
     for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
+        // We are collecting many DiagnosticItems hash maps into one
+        // DiagnosticItems hash map. The iteration order does not matter.
+        #[allow(rustc::potential_query_instability)]
         for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
             collect_item(tcx, &mut items, name, def_id);
         }
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 2629b281756..7667fc21eee 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -126,7 +126,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
         {
             // non-local main imports are handled below
             if let Some(def_id) = def_id.as_local()
-                && matches!(tcx.hir().find_by_def_id(def_id), Some(Node::ForeignItem(_)))
+                && matches!(tcx.opt_hir_node_by_def_id(def_id), Some(Node::ForeignItem(_)))
             {
                 tcx.sess.emit_err(ExternMain { span: tcx.def_span(def_id) });
                 return None;
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 28354ab0986..c2392620cb2 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -121,6 +121,8 @@ impl<'k> StatCollector<'k> {
     }
 
     fn print(&self, title: &str, prefix: &str) {
+        // We will soon sort, so the initial order does not matter.
+        #[allow(rustc::potential_query_instability)]
         let mut nodes: Vec<_> = self.nodes.iter().collect();
         nodes.sort_by_key(|(_, node)| node.stats.count * node.stats.size);
 
@@ -147,6 +149,8 @@ impl<'k> StatCollector<'k> {
                 to_readable_str(node.stats.size)
             );
             if !node.subnodes.is_empty() {
+                // We will soon sort, so the initial order does not matter.
+                #[allow(rustc::potential_query_instability)]
                 let mut subnodes: Vec<_> = node.subnodes.iter().collect();
                 subnodes.sort_by_key(|(_, subnode)| subnode.count * subnode.size);
 
@@ -425,7 +429,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) {
         record_variants!(
             (self, b, b, Id::None, hir, GenericBound, GenericBound),
-            [Trait, LangItemTrait, Outlives]
+            [Trait, Outlives]
         );
         hir_visit::walk_param_bound(self, b)
     }
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index d0b782ba4ca..6d14a14096d 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -7,18 +7,18 @@
 //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
 //! * Functions called by the compiler itself.
 
-use crate::check_attr::target_from_impl_item;
 use crate::errors::{
     DuplicateLangItem, IncorrectTarget, LangItemOnIncorrectTarget, UnknownLangItem,
 };
 use crate::weak_lang_items;
 
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_ast as ast;
+use rustc_ast::visit;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::{extract, GenericRequirement};
-use rustc_hir::{LangItem, LanguageItems, Target};
-use rustc_middle::ty::TyCtxt;
+use rustc_hir::{LangItem, LanguageItems, MethodKind, Target};
+use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_session::cstore::ExternCrate;
 use rustc_span::symbol::kw::Empty;
 use rustc_span::Span;
@@ -31,28 +31,55 @@ pub(crate) enum Duplicate {
     CrateDepends,
 }
 
-struct LanguageItemCollector<'tcx> {
+struct LanguageItemCollector<'ast, 'tcx> {
     items: LanguageItems,
     tcx: TyCtxt<'tcx>,
+    resolver: &'ast ResolverAstLowering,
+    // FIXME(#118552): We should probably feed def_span eagerly on def-id creation
+    // so we can avoid constructing this map for local def-ids.
+    item_spans: FxHashMap<DefId, Span>,
+    parent_item: Option<&'ast ast::Item>,
 }
 
-impl<'tcx> LanguageItemCollector<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> {
-        LanguageItemCollector { tcx, items: LanguageItems::new() }
+impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
+    fn new(
+        tcx: TyCtxt<'tcx>,
+        resolver: &'ast ResolverAstLowering,
+    ) -> LanguageItemCollector<'ast, 'tcx> {
+        LanguageItemCollector {
+            tcx,
+            resolver,
+            items: LanguageItems::new(),
+            item_spans: FxHashMap::default(),
+            parent_item: None,
+        }
     }
 
-    fn check_for_lang(&mut self, actual_target: Target, def_id: LocalDefId) {
-        let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id));
-        if let Some((name, span)) = extract(attrs) {
+    fn check_for_lang(
+        &mut self,
+        actual_target: Target,
+        def_id: LocalDefId,
+        attrs: &'ast [ast::Attribute],
+        item_span: Span,
+        generics: Option<&'ast ast::Generics>,
+    ) {
+        if let Some((name, attr_span)) = extract(attrs) {
             match LangItem::from_name(name) {
                 // Known lang item with attribute on correct target.
                 Some(lang_item) if actual_target == lang_item.target() => {
-                    self.collect_item_extended(lang_item, def_id, span);
+                    self.collect_item_extended(
+                        lang_item,
+                        def_id,
+                        item_span,
+                        attr_span,
+                        generics,
+                        actual_target,
+                    );
                 }
                 // Known lang item with attribute on incorrect target.
                 Some(lang_item) => {
                     self.tcx.sess.emit_err(LangItemOnIncorrectTarget {
-                        span,
+                        span: attr_span,
                         name,
                         expected_target: lang_item.target(),
                         actual_target,
@@ -60,127 +87,131 @@ impl<'tcx> LanguageItemCollector<'tcx> {
                 }
                 // Unknown lang item.
                 _ => {
-                    self.tcx.sess.emit_err(UnknownLangItem { span, name });
+                    self.tcx.sess.emit_err(UnknownLangItem { span: attr_span, name });
                 }
             }
         }
     }
 
-    fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId) {
+    fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId, item_span: Option<Span>) {
         // Check for duplicates.
-        if let Some(original_def_id) = self.items.get(lang_item) {
-            if original_def_id != item_def_id {
-                let local_span = self.tcx.hir().span_if_local(item_def_id);
-                let lang_item_name = lang_item.name();
-                let crate_name = self.tcx.crate_name(item_def_id.krate);
-                let mut dependency_of = Empty;
-                let is_local = item_def_id.is_local();
-                let path = if is_local {
-                    String::new()
-                } else {
-                    self.tcx
-                        .crate_extern_paths(item_def_id.krate)
-                        .iter()
-                        .map(|p| p.display().to_string())
-                        .collect::<Vec<_>>()
-                        .join(", ")
-                };
-                let first_defined_span = self.tcx.hir().span_if_local(original_def_id);
-                let mut orig_crate_name = Empty;
-                let mut orig_dependency_of = Empty;
-                let orig_is_local = original_def_id.is_local();
-                let orig_path = if orig_is_local {
-                    String::new()
-                } else {
-                    self.tcx
-                        .crate_extern_paths(original_def_id.krate)
-                        .iter()
-                        .map(|p| p.display().to_string())
-                        .collect::<Vec<_>>()
-                        .join(", ")
-                };
-                if first_defined_span.is_none() {
-                    orig_crate_name = self.tcx.crate_name(original_def_id.krate);
-                    if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) =
-                        self.tcx.extern_crate(original_def_id)
-                    {
-                        orig_dependency_of = self.tcx.crate_name(*inner_dependency_of);
-                    }
+        if let Some(original_def_id) = self.items.get(lang_item)
+            && original_def_id != item_def_id
+        {
+            let lang_item_name = lang_item.name();
+            let crate_name = self.tcx.crate_name(item_def_id.krate);
+            let mut dependency_of = Empty;
+            let is_local = item_def_id.is_local();
+            let path = if is_local {
+                String::new()
+            } else {
+                self.tcx
+                    .crate_extern_paths(item_def_id.krate)
+                    .iter()
+                    .map(|p| p.display().to_string())
+                    .collect::<Vec<_>>()
+                    .join(", ")
+            };
+
+            let first_defined_span = self.item_spans.get(&original_def_id).copied();
+            let mut orig_crate_name = Empty;
+            let mut orig_dependency_of = Empty;
+            let orig_is_local = original_def_id.is_local();
+            let orig_path = if orig_is_local {
+                String::new()
+            } else {
+                self.tcx
+                    .crate_extern_paths(original_def_id.krate)
+                    .iter()
+                    .map(|p| p.display().to_string())
+                    .collect::<Vec<_>>()
+                    .join(", ")
+            };
+
+            if first_defined_span.is_none() {
+                orig_crate_name = self.tcx.crate_name(original_def_id.krate);
+                if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) =
+                    self.tcx.extern_crate(original_def_id)
+                {
+                    orig_dependency_of = self.tcx.crate_name(*inner_dependency_of);
                 }
+            }
 
-                let duplicate = if local_span.is_some() {
-                    Duplicate::Plain
-                } else {
-                    match self.tcx.extern_crate(item_def_id) {
-                        Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => {
-                            dependency_of = self.tcx.crate_name(*inner_dependency_of);
-                            Duplicate::CrateDepends
-                        }
-                        _ => Duplicate::Crate,
+            let duplicate = if item_span.is_some() {
+                Duplicate::Plain
+            } else {
+                match self.tcx.extern_crate(item_def_id) {
+                    Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => {
+                        dependency_of = self.tcx.crate_name(*inner_dependency_of);
+                        Duplicate::CrateDepends
                     }
-                };
-
-                self.tcx.sess.emit_err(DuplicateLangItem {
-                    local_span,
-                    lang_item_name,
-                    crate_name,
-                    dependency_of,
-                    is_local,
-                    path,
-                    first_defined_span,
-                    orig_crate_name,
-                    orig_dependency_of,
-                    orig_is_local,
-                    orig_path,
-                    duplicate,
-                });
+                    _ => Duplicate::Crate,
+                }
+            };
+
+            self.tcx.sess.emit_err(DuplicateLangItem {
+                local_span: item_span,
+                lang_item_name,
+                crate_name,
+                dependency_of,
+                is_local,
+                path,
+                first_defined_span,
+                orig_crate_name,
+                orig_dependency_of,
+                orig_is_local,
+                orig_path,
+                duplicate,
+            });
+        } else {
+            // Matched.
+            self.items.set(lang_item, item_def_id);
+            // Collect span for error later
+            if let Some(item_span) = item_span {
+                self.item_spans.insert(item_def_id, item_span);
             }
         }
-
-        // Matched.
-        self.items.set(lang_item, item_def_id);
     }
 
     // Like collect_item() above, but also checks whether the lang item is declared
     // with the right number of generic arguments.
-    fn collect_item_extended(&mut self, lang_item: LangItem, item_def_id: LocalDefId, span: Span) {
+    fn collect_item_extended(
+        &mut self,
+        lang_item: LangItem,
+        item_def_id: LocalDefId,
+        item_span: Span,
+        attr_span: Span,
+        generics: Option<&'ast ast::Generics>,
+        target: Target,
+    ) {
         let name = lang_item.name();
 
-        // Now check whether the lang_item has the expected number of generic
-        // arguments. Generally speaking, binary and indexing operations have
-        // one (for the RHS/index), unary operations have none, the closure
-        // traits have one for the argument list, coroutines have one for the
-        // resume argument, and ordering/equality relations have one for the RHS
-        // Some other types like Box and various functions like drop_in_place
-        // have minimum requirements.
+        if let Some(generics) = generics {
+            // Now check whether the lang_item has the expected number of generic
+            // arguments. Generally speaking, binary and indexing operations have
+            // one (for the RHS/index), unary operations have none, the closure
+            // traits have one for the argument list, coroutines have one for the
+            // resume argument, and ordering/equality relations have one for the RHS
+            // Some other types like Box and various functions like drop_in_place
+            // have minimum requirements.
 
-        if let hir::Node::Item(hir::Item { kind, span: item_span, .. }) =
-            self.tcx.hir().get_by_def_id(item_def_id)
-        {
-            let (actual_num, generics_span) = match kind.generics() {
-                Some(generics) => (
-                    generics
-                        .params
-                        .iter()
-                        .filter(|p| {
-                            !matches!(
-                                p.kind,
-                                hir::GenericParamKind::Const { is_host_effect: true, .. }
-                            )
-                        })
-                        .count(),
-                    generics.span,
-                ),
-                None => (0, *item_span),
-            };
+            // FIXME: This still doesn't count, e.g., elided lifetimes and APITs.
+            let mut actual_num = generics.params.len();
+            if target.is_associated_item() {
+                actual_num += self
+                    .parent_item
+                    .unwrap()
+                    .opt_generics()
+                    .map_or(0, |generics| generics.params.len());
+            }
 
             let mut at_least = false;
             let required = match lang_item.required_generics() {
                 GenericRequirement::Exact(num) if num != actual_num => Some(num),
                 GenericRequirement::Minimum(num) if actual_num < num => {
                     at_least = true;
-                    Some(num)}
-                ,
+                    Some(num)
+                }
                 // If the number matches, or there is no requirement, handle it normally
                 _ => None,
             };
@@ -190,10 +221,10 @@ impl<'tcx> LanguageItemCollector<'tcx> {
                 // item kind of the target is correct, the target is still wrong
                 // because of the wrong number of generic arguments.
                 self.tcx.sess.emit_err(IncorrectTarget {
-                    span,
-                    generics_span,
+                    span: attr_span,
+                    generics_span: generics.span,
                     name: name.as_str(),
-                    kind: kind.descr(),
+                    kind: target.name(),
                     num,
                     actual_num,
                     at_least,
@@ -204,58 +235,117 @@ impl<'tcx> LanguageItemCollector<'tcx> {
             }
         }
 
-        self.collect_item(lang_item, item_def_id.to_def_id());
+        self.collect_item(lang_item, item_def_id.to_def_id(), Some(item_span));
     }
 }
 
 /// Traverses and collects all the lang items in all crates.
 fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
+    let resolver = tcx.resolver_for_lowering(()).borrow();
+    let (resolver, krate) = &*resolver;
+
     // Initialize the collector.
-    let mut collector = LanguageItemCollector::new(tcx);
+    let mut collector = LanguageItemCollector::new(tcx, resolver);
 
     // Collect lang items in other crates.
     for &cnum in tcx.crates(()).iter() {
         for &(def_id, lang_item) in tcx.defined_lang_items(cnum).iter() {
-            collector.collect_item(lang_item, def_id);
+            collector.collect_item(lang_item, def_id, None);
         }
     }
 
-    // Collect lang items in this crate.
-    let crate_items = tcx.hir_crate_items(());
+    // Collect lang items local to this crate.
+    visit::Visitor::visit_crate(&mut collector, krate);
 
-    for id in crate_items.items() {
-        collector
-            .check_for_lang(Target::from_def_kind(tcx.def_kind(id.owner_id)), id.owner_id.def_id);
+    // Find all required but not-yet-defined lang items.
+    weak_lang_items::check_crate(tcx, &mut collector.items, krate);
 
-        if matches!(tcx.def_kind(id.owner_id), DefKind::Enum) {
-            let item = tcx.hir().item(id);
-            if let hir::ItemKind::Enum(def, ..) = &item.kind {
-                for variant in def.variants {
-                    collector.check_for_lang(Target::Variant, variant.def_id);
-                }
-            }
-        }
-    }
+    // Return all the lang items that were found.
+    collector.items
+}
+
+impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
+    fn visit_item(&mut self, i: &'ast ast::Item) {
+        let target = match &i.kind {
+            ast::ItemKind::ExternCrate(_) => Target::ExternCrate,
+            ast::ItemKind::Use(_) => Target::Use,
+            ast::ItemKind::Static(_) => Target::Static,
+            ast::ItemKind::Const(_) => Target::Const,
+            ast::ItemKind::Fn(_) => Target::Fn,
+            ast::ItemKind::Mod(_, _) => Target::Mod,
+            ast::ItemKind::ForeignMod(_) => Target::ForeignFn,
+            ast::ItemKind::GlobalAsm(_) => Target::GlobalAsm,
+            ast::ItemKind::TyAlias(_) => Target::TyAlias,
+            ast::ItemKind::Enum(_, _) => Target::Enum,
+            ast::ItemKind::Struct(_, _) => Target::Struct,
+            ast::ItemKind::Union(_, _) => Target::Union,
+            ast::ItemKind::Trait(_) => Target::Trait,
+            ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias,
+            ast::ItemKind::Impl(_) => Target::Impl,
+            ast::ItemKind::MacroDef(_) => Target::MacroDef,
+            ast::ItemKind::MacCall(_) => unreachable!("macros should have been expanded"),
+        };
 
-    // FIXME: avoid calling trait_item() when possible
-    for id in crate_items.trait_items() {
-        let item = tcx.hir().trait_item(id);
-        collector.check_for_lang(Target::from_trait_item(item), item.owner_id.def_id)
+        self.check_for_lang(
+            target,
+            self.resolver.node_id_to_def_id[&i.id],
+            &i.attrs,
+            i.span,
+            i.opt_generics(),
+        );
+
+        let parent_item = self.parent_item.replace(i);
+        visit::walk_item(self, i);
+        self.parent_item = parent_item;
     }
 
-    // FIXME: avoid calling impl_item() when possible
-    for id in crate_items.impl_items() {
-        let item = tcx.hir().impl_item(id);
-        collector.check_for_lang(target_from_impl_item(tcx, item), item.owner_id.def_id)
+    fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef) {
+        for variant in &enum_definition.variants {
+            self.check_for_lang(
+                Target::Variant,
+                self.resolver.node_id_to_def_id[&variant.id],
+                &variant.attrs,
+                variant.span,
+                None,
+            );
+        }
+
+        visit::walk_enum_def(self, enum_definition);
     }
 
-    // Extract out the found lang items.
-    let LanguageItemCollector { mut items, .. } = collector;
+    fn visit_assoc_item(&mut self, i: &'ast ast::AssocItem, ctxt: visit::AssocCtxt) {
+        let (target, generics) = match &i.kind {
+            ast::AssocItemKind::Fn(fun) => (
+                match &self.parent_item.unwrap().kind {
+                    ast::ItemKind::Impl(i) => {
+                        if i.of_trait.is_some() {
+                            Target::Method(MethodKind::Trait { body: fun.body.is_some() })
+                        } else {
+                            Target::Method(MethodKind::Inherent)
+                        }
+                    }
+                    ast::ItemKind::Trait(_) => {
+                        Target::Method(MethodKind::Trait { body: fun.body.is_some() })
+                    }
+                    _ => unreachable!(),
+                },
+                &fun.generics,
+            ),
+            ast::AssocItemKind::Const(ct) => (Target::AssocConst, &ct.generics),
+            ast::AssocItemKind::Type(ty) => (Target::AssocTy, &ty.generics),
+            ast::AssocItemKind::MacCall(_) => unreachable!("macros should have been expanded"),
+        };
 
-    // Find all required but not-yet-defined lang items.
-    weak_lang_items::check_crate(tcx, &mut items);
+        self.check_for_lang(
+            target,
+            self.resolver.node_id_to_def_id[&i.id],
+            &i.attrs,
+            i.span,
+            Some(generics),
+        );
 
-    items
+        visit::walk_assoc_item(self, i, ctxt);
+    }
 }
 
 pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 4c4d5e58232..c969867e871 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -4,7 +4,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 8e6d5805275..bfaf4a5a957 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -4,7 +4,6 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Destination, Movability, Node};
-use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
@@ -30,16 +29,16 @@ enum Context {
 }
 
 #[derive(Copy, Clone)]
-struct CheckLoopVisitor<'a, 'hir> {
+struct CheckLoopVisitor<'a, 'tcx> {
     sess: &'a Session,
-    hir_map: Map<'hir>,
+    tcx: TyCtxt<'tcx>,
     cx: Context,
 }
 
 fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
-        &mut CheckLoopVisitor { sess: tcx.sess, hir_map: tcx.hir(), cx: Normal },
+        &mut CheckLoopVisitor { sess: tcx.sess, tcx, cx: Normal },
     );
 }
 
@@ -51,7 +50,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
-        self.hir_map
+        self.tcx.hir()
     }
 
     fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
@@ -136,13 +135,13 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
                     Err(hir::LoopIdError::UnresolvedLabel) => None,
                 };
 
-                if let Some(Node::Block(_)) = loop_id.and_then(|id| self.hir_map.find(id)) {
+                if let Some(Node::Block(_)) = loop_id.and_then(|id| self.tcx.opt_hir_node(id)) {
                     return;
                 }
 
                 if let Some(break_expr) = opt_expr {
                     let (head, loop_label, loop_kind) = if let Some(loop_id) = loop_id {
-                        match self.hir_map.expect_expr(loop_id).kind {
+                        match self.tcx.hir().expect_expr(loop_id).kind {
                             hir::ExprKind::Loop(_, label, source, sp) => {
                                 (Some(sp), label, Some(source))
                             }
@@ -188,7 +187,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
 
                 match destination.target_id {
                     Ok(loop_id) => {
-                        if let Node::Block(block) = self.hir_map.find(loop_id).unwrap() {
+                        if let Node::Block(block) = self.tcx.opt_hir_node(loop_id).unwrap() {
                             self.sess.emit_err(ContinueLabeledBlock {
                                 span: e.span,
                                 block_span: block.span,
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index bd73fa78442..25637f935fb 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -35,7 +35,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
             continue;
         }
 
-        let (fn_header, body_id) = match tcx.hir().get_by_def_id(def_id) {
+        let (fn_header, body_id) = match tcx.hir_node_by_def_id(def_id) {
             hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })
             | hir::Node::TraitItem(hir::TraitItem {
                 kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index f89c1b0e47c..f46f831ddd7 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -115,7 +115,7 @@ impl<'tcx> ReachableContext<'tcx> {
             return false;
         };
 
-        match self.tcx.hir().find_by_def_id(def_id) {
+        match self.tcx.opt_hir_node_by_def_id(def_id) {
             Some(Node::Item(item)) => match item.kind {
                 hir::ItemKind::Fn(..) => item_might_be_inlined(self.tcx, def_id.into()),
                 _ => false,
@@ -146,7 +146,7 @@ impl<'tcx> ReachableContext<'tcx> {
                 continue;
             }
 
-            if let Some(ref item) = self.tcx.hir().find_by_def_id(search_item) {
+            if let Some(ref item) = self.tcx.opt_hir_node_by_def_id(search_item) {
                 self.propagate_node(item, search_item);
             }
         }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 26bd52f55d4..676622cef45 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -1048,6 +1048,9 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
         tcx.sess.emit_err(errors::UnknownFeature { span, feature: *feature });
     }
 
+    // We only use the hash map contents to emit errors, and the order of
+    // emitted errors do not affect query stability.
+    #[allow(rustc::potential_query_instability)]
     for (implied_by, feature) in remaining_implications {
         let local_defined_features = tcx.lib_features(LOCAL_CRATE);
         let span = local_defined_features
diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index 9a6fb88c281..b226c65e96c 100644
--- a/compiler/rustc_passes/src/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
@@ -1,5 +1,7 @@
 //! Validity checking for weak lang items
 
+use rustc_ast as ast;
+use rustc_ast::visit;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::lang_items::{self, LangItem};
 use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
@@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem}
 
 /// Checks the crate for usage of weak lang items, returning a vector of all the
 /// language items required by this crate, but not defined yet.
-pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
+pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) {
     // These are never called by user code, they're generated by the compiler.
     // They will never implicitly be added to the `missing` array unless we do
     // so here.
@@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
         items.missing.push(LangItem::EhCatchTypeinfo);
     }
 
-    let crate_items = tcx.hir_crate_items(());
-    for id in crate_items.foreign_items() {
-        let attrs = tcx.hir().attrs(id.hir_id());
-        if let Some((lang_item, _)) = lang_items::extract(attrs) {
+    visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate);
+
+    verify(tcx, items);
+}
+
+struct WeakLangItemVisitor<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    items: &'a mut lang_items::LanguageItems,
+}
+
+impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> {
+    fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) {
+        if let Some((lang_item, _)) = lang_items::extract(&i.attrs) {
             if let Some(item) = LangItem::from_name(lang_item)
                 && item.is_weak()
             {
-                if items.get(item).is_none() {
-                    items.missing.push(item);
+                if self.items.get(item).is_none() {
+                    self.items.missing.push(item);
                 }
             } else {
-                let span = tcx.def_span(id.owner_id);
-                tcx.sess.emit_err(UnknownExternLangItem { span, lang_item });
+                self.tcx.sess.emit_err(UnknownExternLangItem { span: i.span, lang_item });
             }
         }
     }
-
-    verify(tcx, items);
 }
 
 fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 716ccdd4dcd..6486ad8b483 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -923,7 +923,7 @@ impl ConstructorSet {
             }
             ConstructorSet::Integers { range_1, range_2 } => {
                 let seen_ranges: Vec<_> =
-                    seen.iter().map(|ctor| ctor.as_int_range().unwrap().clone()).collect();
+                    seen.iter().map(|ctor| *ctor.as_int_range().unwrap()).collect();
                 for (seen, splitted_range) in range_1.split(seen_ranges.iter().cloned()) {
                     match seen {
                         Presence::Unseen => missing.push(IntRange(splitted_range)),
@@ -979,7 +979,8 @@ impl ConstructorSet {
             && !(pcx.is_top_level && matches!(self, Self::NoConstructors))
         {
             // Treat all missing constructors as nonempty.
-            missing.extend(missing_empty.drain(..));
+            // This clears `missing_empty`.
+            missing.append(&mut missing_empty);
         }
 
         SplitConstructorSet { present, missing, missing_empty }
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index e49282e638a..6a8e23d9a8f 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1783,7 +1783,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
         Some(vis) => *vis,
         None => {
             let hir_id = tcx.local_def_id_to_hir_id(def_id);
-            match tcx.hir().get(hir_id) {
+            match tcx.hir_node(hir_id) {
                 // Unique types created for closures participate in type privacy checking.
                 // They have visibilities inherited from the module they are defined in.
                 Node::Expr(hir::Expr { kind: hir::ExprKind::Closure{..}, .. })
@@ -1800,7 +1800,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
                 // Visibilities of trait impl items are inherited from their traits
                 // and are not filled in resolve.
                 Node::ImplItem(impl_item) => {
-                    match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(hir_id).def_id) {
+                    match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(hir_id).def_id) {
                         Node::Item(hir::Item {
                             kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }),
                             ..
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index bc09972185a..3b8ccb67bbe 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -926,8 +926,8 @@ impl<D: Deps> DepGraphData<D> {
 
             let handle = qcx.dep_context().sess().diagnostic();
 
-            for mut diagnostic in side_effects.diagnostics {
-                handle.emit_diagnostic(&mut diagnostic);
+            for diagnostic in side_effects.diagnostics {
+                handle.emit_diagnostic(diagnostic);
             }
         }
     }
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index a70f4138cfb..504763f6cdb 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -70,7 +70,7 @@ const DEP_NODE_PAD: usize = DEP_NODE_SIZE - 1;
 const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2;
 
 /// Data for use when recompiling the **current crate**.
-#[derive(Debug)]
+#[derive(Debug, Default)]
 pub struct SerializedDepGraph {
     /// The set of all DepNodes in the graph
     nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
@@ -89,18 +89,6 @@ pub struct SerializedDepGraph {
     index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>,
 }
 
-impl Default for SerializedDepGraph {
-    fn default() -> Self {
-        SerializedDepGraph {
-            nodes: Default::default(),
-            fingerprints: Default::default(),
-            edge_list_indices: Default::default(),
-            edge_list_data: Default::default(),
-            index: Default::default(),
-        }
-    }
-}
-
 impl SerializedDepGraph {
     #[inline]
     pub fn edge_targets_from(
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index e601ceaa50c..39e82da6d9d 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -1063,12 +1063,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             initial_binding.res()
                         });
                         let res = binding.res();
-                        let has_ambiguity_error = this
-                            .ambiguity_errors
-                            .iter()
-                            .filter(|error| !error.warning)
-                            .next()
-                            .is_some();
+                        let has_ambiguity_error =
+                            this.ambiguity_errors.iter().any(|error| !error.warning);
                         if res == Res::Err || has_ambiguity_error {
                             this.tcx
                                 .sess
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 61c7846ea61..d767ed74139 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1829,13 +1829,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
             )
             .iter()
             .filter_map(|candidate| candidate.did)
-            .filter(|did| {
+            .find(|did| {
                 self.r
                     .tcx
                     .get_attrs(*did, sym::rustc_diagnostic_item)
                     .any(|attr| attr.value_str() == Some(sym::Default))
-            })
-            .next();
+            });
         let Some(default_trait) = default_trait else {
             return;
         };
@@ -1880,11 +1879,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         };
 
         fields.is_some_and(|fields| {
-            fields
-                .iter()
-                .filter(|vis| !self.r.is_accessible_from(**vis, self.parent_scope.module))
-                .next()
-                .is_some()
+            fields.iter().any(|vis| !self.r.is_accessible_from(*vis, self.parent_scope.module))
         })
     }
 
@@ -2178,7 +2173,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 let (span, text) = match path.segments.first() {
                     Some(seg) if let Some(name) = seg.ident.as_str().strip_prefix("let") => {
                         // a special case for #117894
-                        let name = name.strip_prefix("_").unwrap_or(name);
+                        let name = name.strip_prefix('_').unwrap_or(name);
                         (ident_span, format!("let {name}"))
                     }
                     _ => (ident_span.shrink_to_lo(), "let ".to_string()),
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index f95c0acd750..4ff4ccf5e98 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -407,8 +407,7 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
         doc,
         main_body_opts(),
         Some(&mut broken_link_callback),
-    )
-    .into_iter();
+    );
     let mut links = Vec::new();
 
     while let Some(event) = event_iter.next() {
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 8dc9a29c2ad..20d18fa4b83 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -755,13 +755,14 @@ pub enum PrintKind {
 }
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub enum TraitSolver {
-    /// Classic trait solver in `rustc_trait_selection::traits::select`
-    Classic,
-    /// Experimental trait solver in `rustc_trait_selection::solve`
-    Next,
-    /// Use the new trait solver during coherence
-    NextCoherence,
+pub struct NextSolverConfig {
+    /// Whether the new trait solver should be enabled in coherence.
+    pub coherence: bool,
+    /// Whether the new trait solver should be enabled everywhere.
+    /// This is only `true` if `coherence` is also enabled.
+    pub globally: bool,
+    /// Whether to dump proof trees after computing a proof tree.
+    pub dump_tree: DumpSolverProofTree,
 }
 
 #[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)]
@@ -1485,10 +1486,12 @@ impl CheckCfg {
         ins!(sym::sanitizer_cfi_generalize_pointers, no_values);
         ins!(sym::sanitizer_cfi_normalize_integers, no_values);
 
-        // rustc_codegen_ssa has a list of known target features and their
-        // stability, but we should allow any target feature as a new target or
-        // rustc version may introduce new target features.
-        ins!(sym::target_feature, || ExpectedValues::Any);
+        ins!(sym::target_feature, empty_values).extend(
+            rustc_target::target_features::all_known_features()
+                .map(|(f, _sb)| f)
+                .chain(rustc_target::target_features::RUSTC_SPECIFIC_FEATURES.iter().cloned())
+                .map(Symbol::intern),
+        );
 
         // sym::target_*
         {
@@ -1576,7 +1579,7 @@ impl CheckCfg {
 pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items.
-    user_cfg.extend(default_configuration(sess).into_iter());
+    user_cfg.extend(default_configuration(sess));
     user_cfg
 }
 
@@ -3220,10 +3223,10 @@ pub(crate) mod dep_tracking {
     use super::{
         BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
         ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay,
-        LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType,
-        OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
-        SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
-        WasiExecModel,
+        LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel,
+        OutFileName, OutputType, OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks,
+        SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
+        TrimmedDefPaths, WasiExecModel,
     };
     use crate::lint;
     use crate::utils::NativeLib;
@@ -3326,7 +3329,7 @@ pub(crate) mod dep_tracking {
         BranchProtection,
         OomStrategy,
         LanguageIdentifier,
-        TraitSolver,
+        NextSolverConfig,
         Polonius,
         InliningThreshold,
         FunctionReturn,
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 7eed59709c8..aab7595ef6e 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -19,7 +19,7 @@ impl<'a> IntoDiagnostic<'a> for FeatureGateError {
         self,
         handler: &'a rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> {
-        let mut diag = handler.struct_diagnostic(self.explain);
+        let mut diag = handler.struct_err(self.explain);
         diag.set_span(self.span);
         diag.code(error_code!(E0658));
         diag
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index d666c5d4d70..e8ca556aa42 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -396,8 +396,7 @@ mod desc {
     pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
     pub const parse_unpretty: &str = "`string` or `string=string`";
     pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
-    pub const parse_trait_solver: &str =
-        "one of the supported solver modes (`classic`, `next`, or `next-coherence`)";
+    pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error";
     pub const parse_lto: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
     pub const parse_linker_plugin_lto: &str =
@@ -429,7 +428,6 @@ mod desc {
         "a `,` separated combination of `bti`, `b-key`, `pac-ret`, or `leaf`";
     pub const parse_proc_macro_execution_strategy: &str =
         "one of supported execution strategies (`same-thread`, or `cross-thread`)";
-    pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`";
     pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`";
     pub const parse_inlining_threshold: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
@@ -1032,15 +1030,48 @@ mod parse {
         }
     }
 
-    pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool {
-        match v {
-            Some("classic") => *slot = TraitSolver::Classic,
-            Some("next") => *slot = TraitSolver::Next,
-            Some("next-coherence") => *slot = TraitSolver::NextCoherence,
-            // default trait solver is subject to change..
-            Some("default") => *slot = TraitSolver::Classic,
-            _ => return false,
+    pub(crate) fn parse_next_solver_config(
+        slot: &mut Option<NextSolverConfig>,
+        v: Option<&str>,
+    ) -> bool {
+        if let Some(config) = v {
+            let mut coherence = false;
+            let mut globally = true;
+            let mut dump_tree = None;
+            for c in config.split(',') {
+                match c {
+                    "globally" => globally = true,
+                    "coherence" => {
+                        globally = false;
+                        coherence = true;
+                    }
+                    "dump-tree" => {
+                        if dump_tree.replace(DumpSolverProofTree::Always).is_some() {
+                            return false;
+                        }
+                    }
+                    "dump-tree-on-error" => {
+                        if dump_tree.replace(DumpSolverProofTree::OnError).is_some() {
+                            return false;
+                        }
+                    }
+                    _ => return false,
+                }
+            }
+
+            *slot = Some(NextSolverConfig {
+                coherence: coherence || globally,
+                globally,
+                dump_tree: dump_tree.unwrap_or_default(),
+            });
+        } else {
+            *slot = Some(NextSolverConfig {
+                coherence: true,
+                globally: true,
+                dump_tree: Default::default(),
+            });
         }
+
         true
     }
 
@@ -1305,19 +1336,6 @@ mod parse {
         true
     }
 
-    pub(crate) fn parse_dump_solver_proof_tree(
-        slot: &mut DumpSolverProofTree,
-        v: Option<&str>,
-    ) -> bool {
-        match v {
-            None | Some("always") => *slot = DumpSolverProofTree::Always,
-            Some("never") => *slot = DumpSolverProofTree::Never,
-            Some("on-error") => *slot = DumpSolverProofTree::OnError,
-            _ => return false,
-        };
-        true
-    }
-
     pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool {
         match v {
             Some("always" | "yes") => {
@@ -1552,6 +1570,8 @@ options! {
         "compress debug info sections (none, zlib, zstd, default: none)"),
     deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED],
         "deduplicate identical diagnostics (default: yes)"),
+    default_hidden_visibility: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "overrides the `default_hidden_visibility` setting of the target"),
     dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
         "in dep-info output, omit targets for tracking dependencies of the dep-info files \
         themselves (default: no)"),
@@ -1589,9 +1609,6 @@ options! {
         "output statistics about monomorphization collection"),
     dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED],
         "the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"),
-    dump_solver_proof_tree: DumpSolverProofTree = (DumpSolverProofTree::Never, parse_dump_solver_proof_tree, [UNTRACKED],
-        "dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it
-        then it defaults to `always`. If the flag is not specified at all it defaults to `on-request`."),
     dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED],
         "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
     dylib_lto: bool = (false, parse_bool, [UNTRACKED],
@@ -1720,6 +1737,8 @@ options! {
         "the size at which the `large_assignments` lint starts to be emitted"),
     mutable_noalias: bool = (true, parse_bool, [TRACKED],
         "emit noalias metadata for mutable references (default: yes)"),
+    next_solver: Option<NextSolverConfig> = (None, parse_next_solver_config, [TRACKED],
+        "enable and configure the next generation trait solver used by rustc"),
     nll_facts: bool = (false, parse_bool, [UNTRACKED],
         "dump facts from NLL analysis into side files (default: no)"),
     nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],
@@ -1920,8 +1939,6 @@ written to standard error output)"),
         "for every macro invocation, print its name and arguments (default: no)"),
     track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
         "tracks where in rustc a diagnostic was emitted"),
-    trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED],
-        "specify the trait solver mode used by rustc (default: classic)"),
     // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
     // alongside query results and changes to translation options can affect diagnostics - so
     // translation options should be tracked.
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 881e1de6755..525f00f5cd0 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -14,7 +14,7 @@ use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
 use rustc_errors::{emitter::SilentEmitter, Handler};
 use rustc_errors::{
     fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
-    EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey,
+    ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey,
 };
 use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
 use rustc_span::edition::Edition;
@@ -390,13 +390,4 @@ impl ParseSess {
     pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
         self.span_diagnostic.struct_fatal(msg)
     }
-
-    #[rustc_lint_diagnostics]
-    #[track_caller]
-    pub fn struct_diagnostic<G: EmissionGuarantee>(
-        &self,
-        msg: impl Into<DiagnosticMessage>,
-    ) -> DiagnosticBuilder<'_, G> {
-        self.span_diagnostic.struct_diagnostic(msg)
-    }
 }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 24c7459392a..08a9b3d9fa0 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -632,7 +632,7 @@ impl Session {
     pub fn span_delayed_bug<S: Into<MultiSpan>>(
         &self,
         sp: S,
-        msg: impl Into<String>,
+        msg: impl Into<DiagnosticMessage>,
     ) -> ErrorGuaranteed {
         self.diagnostic().span_delayed_bug(sp, msg)
     }
@@ -961,6 +961,14 @@ impl Session {
             termize::dimensions().map_or(default_column_width, |(w, _)| w)
         }
     }
+
+    /// Whether the default visibility of symbols should be "hidden" rather than "default".
+    pub fn default_hidden_visibility(&self) -> bool {
+        self.opts
+            .unstable_opts
+            .default_hidden_visibility
+            .unwrap_or(self.target.options.default_hidden_visibility)
+    }
 }
 
 // JUSTIFICATION: defn of the suggested wrapper fns
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index 4ec5e2a5387..3a8289f38bd 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -5,7 +5,9 @@
 
 use rustc_middle::ty;
 use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
-use rustc_middle::ty::{GenericPredicates, Instance, ParamEnv, ScalarInt, ValTree};
+use rustc_middle::ty::{
+    GenericPredicates, Instance, ParamEnv, ScalarInt, TypeVisitableExt, ValTree,
+};
 use rustc_span::def_id::LOCAL_CRATE;
 use stable_mir::compiler_interface::Context;
 use stable_mir::mir::alloc::GlobalAlloc;
@@ -156,8 +158,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
                 let crate_name = tables.tcx.crate_name(*crate_num).to_string();
                 (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
             })
-            .into_iter()
-            .filter_map(|c| c)
+            .flatten()
             .collect();
         crates
     }
@@ -324,7 +325,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
     fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
         let mut tables = self.0.borrow_mut();
         let instance = tables.instances[def];
-        instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables)
+        assert!(!instance.has_non_region_param(), "{instance:?} needs further substitution");
+        instance.ty(tables.tcx, ParamEnv::reveal_all()).stable(&mut *tables)
     }
 
     fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 0cea3fcc7f7..41ab4007a67 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -36,6 +36,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
                 .collect(),
             self.arg_count,
             self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
+            self.spread_arg.stable(tables),
         )
     }
 }
@@ -707,7 +708,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
                 let id = tables.intern_const(*self);
                 Const::new(kind, ty, id)
             }
-            mir::Const::Val(val, ty) if matches!(val, mir::ConstValue::ZeroSized) => {
+            mir::Const::Val(mir::ConstValue::ZeroSized, ty) => {
                 let ty = ty.stable(tables);
                 let id = tables.intern_const(*self);
                 Const::new(ConstantKind::ZeroSized, ty, id)
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
index 7d8339ab503..7021bdda735 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
@@ -57,7 +57,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
                 stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
             }
             CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
-            CoroutineKind::AsyncGen(_) => todo!(),
+            CoroutineKind::AsyncGen(source) => {
+                stable_mir::mir::CoroutineKind::AsyncGen(source.stable(tables))
+            }
         }
     }
 }
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index e49d134659e..3d673f2f1ec 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -364,7 +364,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
     //     _ZTSFvu27NvNtC1234_5crate6Trait13fooIu22NtC1234_5crate7Struct1Iu3i32ES_EE
     //
     // The reason for not using v0's extended form of paths is to use a consistent and simpler
-    // encoding, as the reasoning for using it isn't relevand for type metadata identifiers (i.e.,
+    // encoding, as the reasoning for using it isn't relevant for type metadata identifiers (i.e.,
     // keep symbol names close to how methods are represented in error messages). See
     // https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html#methods.
     let mut s = String::new();
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index e17b81d4652..257c6777996 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -35,6 +35,7 @@ pub mod abi;
 pub mod asm;
 pub mod json;
 pub mod spec;
+pub mod target_features;
 
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index f32cb06d68f..afd60b40c3b 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -1,8 +1,8 @@
 use std::{borrow::Cow, env};
 
 use crate::spec::{add_link_args, add_link_args_iter};
-use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs};
-use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, Target, TargetOptions};
+use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs, LinkerFlavor, Lld};
+use crate::spec::{SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions};
 
 #[cfg(test)]
 mod tests;
@@ -81,6 +81,14 @@ impl Arch {
             Arm64_sim => "apple-a12",
         }
     }
+
+    fn stack_probes(self) -> StackProbeType {
+        match self {
+            Armv7k | Armv7s => StackProbeType::None,
+            Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h | X86_64_sim
+            | X86_64_macabi | Arm64_macabi | Arm64_sim => StackProbeType::Inline,
+        }
+    }
 }
 
 fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
@@ -147,6 +155,7 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
         eh_frame_header: false,
+        stack_probes: arch.stack_probes(),
 
         debuginfo_kind: DebuginfoKind::DwarfDsym,
         // The historical default for macOS targets is to run `dsymutil` which
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 24893bda9e7..a78df69f187 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2094,7 +2094,11 @@ pub struct TargetOptions {
     pub no_builtins: bool,
 
     /// The default visibility for symbols in this target should be "hidden"
-    /// rather than "default"
+    /// rather than "default".
+    ///
+    /// This value typically shouldn't be accessed directly, but through
+    /// the `rustc_session::Session::default_hidden_visibility` method, which
+    /// allows `rustc` users to override this setting using cmdline flags.
     pub default_hidden_visibility: bool,
 
     /// Whether a .debug_gdb_scripts section will be added to the output object file
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
index bbaa870ec2e..739a9e4a3dc 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
@@ -1,5 +1,5 @@
 use crate::abi::Endian;
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v8a,+outline-atomics".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             mcount: "\u{1}_mcount".into(),
             endian: Endian::Big,
             ..base::linux_gnu::opts()
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
index 7536e507b3d..1b87c09e3fe 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
@@ -1,5 +1,5 @@
 use crate::abi::Endian;
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = base::linux_gnu::opts();
@@ -13,6 +13,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             abi: "ilp32".into(),
             features: "+v8a,+outline-atomics".into(),
+            stack_probes: StackProbeType::Inline,
             mcount: "\u{1}_mcount".into(),
             endian: Endian::Big,
             ..base
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
index 21de8a71a0d..02e156f19de 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
@@ -1,5 +1,5 @@
 use crate::abi::Endian;
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             mcount: "__mcount".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             endian: Endian::Big,
             ..base::netbsd::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs
index e5e22fd1ee2..5b4ffc08a57 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, RelocModel, Target, TargetOptions};
+use crate::spec::{base, RelocModel, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let base = base::solid::opts("asp3");
@@ -13,6 +13,7 @@ pub fn target() -> Target {
             relocation_model: RelocModel::Static,
             disable_redzone: true,
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs
index 7c6fed7ab99..db9a1808560 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, SanitizerSet, Target, TargetOptions};
+use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
 // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a
 // for target ABI requirements.
@@ -14,6 +14,7 @@ pub fn target() -> Target {
             // As documented in https://developer.android.com/ndk/guides/cpu-features.html
             // the neon (ASIMD) and FP must exist on all android aarch64 targets.
             features: "+v8a,+neon,+fp-armv8".into(),
+            stack_probes: StackProbeType::Inline,
             supported_sanitizers: SanitizerSet::CFI
                 | SanitizerSet::HWADDRESS
                 | SanitizerSet::MEMTAG
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs
index 02fcc2bb43e..5a92225c496 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs
@@ -1,4 +1,6 @@
-use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, Target, TargetOptions};
+use crate::spec::{
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, StackProbeType, Target, TargetOptions,
+};
 
 const LINKER_SCRIPT: &str = include_str!("./aarch64_nintendo_switch_freestanding_linker_script.ld");
 
@@ -16,6 +18,7 @@ pub fn target() -> Target {
             link_script: Some(LINKER_SCRIPT.into()),
             os: "horizon".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             panic_strategy: PanicStrategy::Abort,
             position_independent_executables: true,
             dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs
index 0f95984a31f..0ba91a54f1d 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, SanitizerSet, Target, TargetOptions};
+use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -9,6 +9,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v8a".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             supported_sanitizers: SanitizerSet::ADDRESS
                 | SanitizerSet::CFI
                 | SanitizerSet::MEMORY
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
index cacc6ea235a..430a1c5e7f1 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, SanitizerSet, Target, TargetOptions};
+use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -9,6 +9,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v8a".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             supported_sanitizers: SanitizerSet::ADDRESS
                 | SanitizerSet::CFI
                 | SanitizerSet::SHADOWCALLSTACK,
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs
index 3839e0b9c46..50813b81b8d 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -9,6 +9,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v8a,+strict-align,+neon,+fp-armv8".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             ..base::hermit::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs
index c0b07db3818..5b3a2ffa599 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, SanitizerSet, Target, TargetOptions};
+use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -10,6 +10,7 @@ pub fn target() -> Target {
             features: "+v8a,+outline-atomics".into(),
             mcount: "\u{1}_mcount".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             supported_sanitizers: SanitizerSet::ADDRESS
                 | SanitizerSet::CFI
                 | SanitizerSet::LEAK
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs
index d4c6271b241..0ff5c8651e6 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -10,6 +10,7 @@ pub fn target() -> Target {
             abi: "ilp32".into(),
             features: "+v8a,+outline-atomics".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             mcount: "\u{1}_mcount".into(),
             ..base::linux_gnu::opts()
         },
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 364df677e44..d16ccd803a9 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
@@ -1,10 +1,11 @@
-use crate::spec::{base, SanitizerSet, Target, TargetOptions};
+use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.max_atomic_width = Some(128);
     base.supports_xray = true;
     base.features = "+v8a".into();
+    base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers = SanitizerSet::ADDRESS
         | SanitizerSet::CFI
         | SanitizerSet::LEAK
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
index 5f3bef63aa6..1be27a51108 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
@@ -1,5 +1,5 @@
 use crate::spec::SanitizerSet;
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = base::linux_ohos::opts();
@@ -14,6 +14,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+reserve-x18".into(),
             mcount: "\u{1}_mcount".into(),
+            stack_probes: StackProbeType::Inline,
             supported_sanitizers: SanitizerSet::ADDRESS
                 | SanitizerSet::CFI
                 | SanitizerSet::LEAK
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs
index 3194d16ff47..32a0816cf81 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -10,6 +10,7 @@ pub fn target() -> Target {
             features: "+v8a".into(),
             mcount: "__mcount".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             ..base::netbsd::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
index 63a8144f69f..518597b3811 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
@@ -7,7 +7,8 @@
 // For example, `-C target-cpu=cortex-a53`.
 
 use crate::spec::{
-    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, TargetOptions,
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target,
+    TargetOptions,
 };
 
 pub fn target() -> Target {
@@ -24,6 +25,7 @@ pub fn target() -> Target {
         relocation_model: RelocModel::Static,
         disable_redzone: true,
         max_atomic_width: Some(128),
+        stack_probes: StackProbeType::Inline,
         panic_strategy: PanicStrategy::Abort,
         ..Default::default()
     };
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
index 48b79b0b9ba..d56fbdbbe90 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
@@ -6,7 +6,9 @@
 //
 // For example, `-C target-cpu=cortex-a53`.
 
-use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
+use crate::spec::{
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, StackProbeType, Target, TargetOptions,
+};
 
 pub fn target() -> Target {
     let opts = TargetOptions {
@@ -17,6 +19,7 @@ pub fn target() -> Target {
         relocation_model: RelocModel::Static,
         disable_redzone: true,
         max_atomic_width: Some(128),
+        stack_probes: StackProbeType::Inline,
         panic_strategy: PanicStrategy::Abort,
         ..Default::default()
     };
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs
index e3f5aafc7d4..d5fca5c31a6 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -9,6 +9,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v8a".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             ..base::openbsd::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs
index de875e29ffd..844fed472a2 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs
@@ -1,8 +1,9 @@
-use crate::spec::{base, Target};
+use crate::spec::{base, StackProbeType, Target};
 
 pub fn target() -> Target {
     let mut base = base::redox::opts();
     base.max_atomic_width = Some(128);
+    base.stack_probes = StackProbeType::Inline;
     base.features = "+v8a".into();
 
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs
index b490e80258c..204e9b061ce 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs
@@ -1,9 +1,10 @@
-use crate::spec::{base, Target};
+use crate::spec::{base, StackProbeType, Target};
 
 pub fn target() -> Target {
     let mut base = base::teeos::opts();
     base.features = "+strict-align,+neon,+fp-armv8".into();
     base.max_atomic_width = Some(128);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "aarch64-unknown-none".into(),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
index 29f61d85778..48e142347d7 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     Target {
@@ -9,6 +9,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v8a".into(),
             max_atomic_width: Some(128),
+            stack_probes: StackProbeType::Inline,
             ..base::vxworks::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
index ce0d604f57c..13f8b6b5a0a 100644
--- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch};
-use crate::spec::{StackProbeType, Target, TargetOptions};
+use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::I386;
@@ -14,10 +14,6 @@ pub fn target() -> Target {
             f64:32:64-f80:128-n8:16:32-S128"
             .into(),
         arch: arch.target_arch(),
-        options: TargetOptions {
-            max_atomic_width: Some(64),
-            stack_probes: StackProbeType::Inline,
-            ..opts("ios", arch)
-        },
+        options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch) },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
index c4c9023419d..59069fe4e3a 100644
--- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
-use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
+use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions};
 
 pub fn target() -> Target {
     // ld64 only understands i386 and not i686
@@ -7,7 +7,6 @@ pub fn target() -> Target {
     let mut base = opts("macos", arch);
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);
-    base.stack_probes = StackProbeType::Inline;
     base.frame_pointer = FramePointer::Always;
 
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
index 81173a16f96..59df3937ea6 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
@@ -1,6 +1,6 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet};
-use crate::spec::{StackProbeType, Target, TargetOptions};
+use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::X86_64;
@@ -8,7 +8,6 @@ pub fn target() -> Target {
     base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b
     base.frame_pointer = FramePointer::Always;
     base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
-    base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
 
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
index 221635526d1..d0e2ac44a2a 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch};
-use crate::spec::{SanitizerSet, StackProbeType, Target, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::X86_64_sim;
@@ -12,10 +12,6 @@ pub fn target() -> Target {
         data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
             .into(),
         arch: arch.target_arch(),
-        options: TargetOptions {
-            max_atomic_width: Some(128),
-            stack_probes: StackProbeType::Inline,
-            ..base
-        },
+        options: TargetOptions { max_atomic_width: Some(128), ..base },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
index 5f6b4b500d0..8ef4b88b8b1 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{opts, Arch};
-use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions};
+use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};
 
 pub fn target() -> Target {
     let llvm_target = "x86_64-apple-ios14.0-macabi";
@@ -15,10 +15,6 @@ pub fn target() -> Target {
         data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
             .into(),
         arch: arch.target_arch(),
-        options: TargetOptions {
-            max_atomic_width: Some(128),
-            stack_probes: StackProbeType::Inline,
-            ..base
-        },
+        options: TargetOptions { max_atomic_width: Some(128), ..base },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
index a7d5f28e0e5..17efd437f2f 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch};
-use crate::spec::{StackProbeType, Target, TargetOptions};
+use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::X86_64_sim;
@@ -9,10 +9,6 @@ pub fn target() -> Target {
         data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
             .into(),
         arch: arch.target_arch(),
-        options: TargetOptions {
-            max_atomic_width: Some(128),
-            stack_probes: StackProbeType::Inline,
-            ..opts("tvos", arch)
-        },
+        options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch) },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
index 3c5bf30ef5f..b1f72ee2f21 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch};
-use crate::spec::{StackProbeType, Target, TargetOptions};
+use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::X86_64_sim;
@@ -9,10 +9,6 @@ pub fn target() -> Target {
         data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
             .into(),
         arch: arch.target_arch(),
-        options: TargetOptions {
-            max_atomic_width: Some(128),
-            stack_probes: StackProbeType::Inline,
-            ..opts("watchos", arch)
-        },
+        options: TargetOptions { max_atomic_width: Some(128), ..opts("watchos", arch) },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
index 32d15c18678..0c731e369eb 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
@@ -1,6 +1,6 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet};
-use crate::spec::{StackProbeType, Target, TargetOptions};
+use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::X86_64h;
@@ -8,7 +8,6 @@ pub fn target() -> Target {
     base.max_atomic_width = Some(128);
     base.frame_pointer = FramePointer::Always;
     base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
-    base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
 
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
new file mode 100644
index 00000000000..5f5de57dd1d
--- /dev/null
+++ b/compiler/rustc_target/src/target_features.rs
@@ -0,0 +1,429 @@
+use rustc_span::symbol::sym;
+use rustc_span::symbol::Symbol;
+
+/// Features that control behaviour of rustc, rather than the codegen.
+pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
+
+/// Stability information for target features.
+#[derive(Debug, Clone, Copy)]
+pub enum Stability {
+    /// 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),
+}
+use Stability::*;
+
+impl Stability {
+    pub fn as_feature_name(self) -> Option<Symbol> {
+        match self {
+            Stable => None,
+            Unstable(s) => Some(s),
+        }
+    }
+
+    pub fn is_stable(self) -> bool {
+        matches!(self, Stable)
+    }
+}
+
+// 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`.
+//
+// When adding features to the below lists
+// check whether they're named already elsewhere in rust
+// e.g. in stdarch and whether the given name matches LLVM's
+// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted.
+//
+// Also note that all target features listed here must be purely additive: for target_feature 1.1 to
+// be sound, we can never allow features like `+soft-float` (on x86) to be controlled on a
+// per-function level, since we would then allow safe calls from functions with `+soft-float` to
+// functions without that feature!
+//
+// When adding a new feature, be particularly mindful of features that affect function ABIs. Those
+// need to be treated very carefully to avoid introducing unsoundness! This often affects features
+// that enable/disable hardfloat support (see https://github.com/rust-lang/rust/issues/116344 for an
+// example of this going wrong), but features enabling new SIMD registers are also a concern (see
+// https://github.com/rust-lang/rust/issues/116558 for an example of this going wrong).
+//
+// Stabilizing a target feature requires t-lang approval.
+
+const ARM_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("aclass", Unstable(sym::arm_target_feature)),
+    ("aes", Unstable(sym::arm_target_feature)),
+    ("crc", Unstable(sym::arm_target_feature)),
+    ("d32", Unstable(sym::arm_target_feature)),
+    ("dotprod", Unstable(sym::arm_target_feature)),
+    ("dsp", Unstable(sym::arm_target_feature)),
+    ("fp-armv8", Unstable(sym::arm_target_feature)),
+    ("i8mm", Unstable(sym::arm_target_feature)),
+    ("mclass", Unstable(sym::arm_target_feature)),
+    ("neon", Unstable(sym::arm_target_feature)),
+    ("rclass", Unstable(sym::arm_target_feature)),
+    ("sha2", Unstable(sym::arm_target_feature)),
+    // 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)),
+    ("v6k", Unstable(sym::arm_target_feature)),
+    ("v6t2", Unstable(sym::arm_target_feature)),
+    ("v7", Unstable(sym::arm_target_feature)),
+    ("v8", Unstable(sym::arm_target_feature)),
+    ("vfp2", Unstable(sym::arm_target_feature)),
+    ("vfp3", Unstable(sym::arm_target_feature)),
+    ("vfp4", Unstable(sym::arm_target_feature)),
+    ("virtualization", Unstable(sym::arm_target_feature)),
+    // tidy-alphabetical-end
+];
+
+const AARCH64_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    // FEAT_AES
+    ("aes", Stable),
+    // FEAT_BF16
+    ("bf16", Stable),
+    // FEAT_BTI
+    ("bti", Stable),
+    // FEAT_CRC
+    ("crc", Stable),
+    // FEAT_DIT
+    ("dit", Stable),
+    // FEAT_DotProd
+    ("dotprod", Stable),
+    // FEAT_DPB
+    ("dpb", Stable),
+    // FEAT_DPB2
+    ("dpb2", Stable),
+    // FEAT_F32MM
+    ("f32mm", Stable),
+    // FEAT_F64MM
+    ("f64mm", Stable),
+    // FEAT_FCMA
+    ("fcma", Stable),
+    // FEAT_FHM
+    ("fhm", Stable),
+    // FEAT_FLAGM
+    ("flagm", Stable),
+    // FEAT_FP16
+    ("fp16", Stable),
+    // FEAT_FRINTTS
+    ("frintts", Stable),
+    // FEAT_I8MM
+    ("i8mm", Stable),
+    // FEAT_JSCVT
+    ("jsconv", Stable),
+    // FEAT_LOR
+    ("lor", Stable),
+    // FEAT_LSE
+    ("lse", Stable),
+    // FEAT_MTE
+    ("mte", Stable),
+    // FEAT_AdvSimd & FEAT_FP
+    ("neon", Stable),
+    // FEAT_PAUTH (address authentication)
+    ("paca", Stable),
+    // FEAT_PAUTH (generic authentication)
+    ("pacg", Stable),
+    // FEAT_PAN
+    ("pan", Stable),
+    // FEAT_PMUv3
+    ("pmuv3", Stable),
+    // FEAT_RAND
+    ("rand", Stable),
+    // FEAT_RAS
+    ("ras", Stable),
+    // FEAT_RCPC
+    ("rcpc", Stable),
+    // FEAT_RCPC2
+    ("rcpc2", Stable),
+    // FEAT_RDM
+    ("rdm", Stable),
+    // FEAT_SB
+    ("sb", Stable),
+    // FEAT_SHA1 & FEAT_SHA256
+    ("sha2", Stable),
+    // FEAT_SHA512 & FEAT_SHA3
+    ("sha3", Stable),
+    // FEAT_SM3 & FEAT_SM4
+    ("sm4", Stable),
+    // FEAT_SPE
+    ("spe", Stable),
+    // FEAT_SSBS
+    ("ssbs", Stable),
+    // FEAT_SVE
+    ("sve", Stable),
+    // FEAT_SVE2
+    ("sve2", Stable),
+    // FEAT_SVE2_AES
+    ("sve2-aes", Stable),
+    // FEAT_SVE2_BitPerm
+    ("sve2-bitperm", Stable),
+    // FEAT_SVE2_SHA3
+    ("sve2-sha3", Stable),
+    // FEAT_SVE2_SM4
+    ("sve2-sm4", Stable),
+    // FEAT_TME
+    ("tme", Stable),
+    ("v8.1a", Unstable(sym::aarch64_ver_target_feature)),
+    ("v8.2a", Unstable(sym::aarch64_ver_target_feature)),
+    ("v8.3a", Unstable(sym::aarch64_ver_target_feature)),
+    ("v8.4a", Unstable(sym::aarch64_ver_target_feature)),
+    ("v8.5a", Unstable(sym::aarch64_ver_target_feature)),
+    ("v8.6a", Unstable(sym::aarch64_ver_target_feature)),
+    ("v8.7a", Unstable(sym::aarch64_ver_target_feature)),
+    // FEAT_VHE
+    ("vh", Stable),
+    // tidy-alphabetical-end
+];
+
+const AARCH64_TIED_FEATURES: &[&[&str]] = &[
+    &["paca", "pacg"], // Together these represent `pauth` in LLVM
+];
+
+const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("adx", Stable),
+    ("aes", Stable),
+    ("avx", Stable),
+    ("avx2", Stable),
+    ("avx512bf16", Unstable(sym::avx512_target_feature)),
+    ("avx512bitalg", Unstable(sym::avx512_target_feature)),
+    ("avx512bw", Unstable(sym::avx512_target_feature)),
+    ("avx512cd", Unstable(sym::avx512_target_feature)),
+    ("avx512dq", Unstable(sym::avx512_target_feature)),
+    ("avx512er", Unstable(sym::avx512_target_feature)),
+    ("avx512f", Unstable(sym::avx512_target_feature)),
+    ("avx512ifma", Unstable(sym::avx512_target_feature)),
+    ("avx512pf", Unstable(sym::avx512_target_feature)),
+    ("avx512vbmi", Unstable(sym::avx512_target_feature)),
+    ("avx512vbmi2", Unstable(sym::avx512_target_feature)),
+    ("avx512vl", Unstable(sym::avx512_target_feature)),
+    ("avx512vnni", Unstable(sym::avx512_target_feature)),
+    ("avx512vp2intersect", Unstable(sym::avx512_target_feature)),
+    ("avx512vpopcntdq", Unstable(sym::avx512_target_feature)),
+    ("bmi1", Stable),
+    ("bmi2", Stable),
+    ("cmpxchg16b", Stable),
+    ("ermsb", Unstable(sym::ermsb_target_feature)),
+    ("f16c", Stable),
+    ("fma", Stable),
+    ("fxsr", Stable),
+    ("gfni", Unstable(sym::avx512_target_feature)),
+    ("lzcnt", Stable),
+    ("movbe", Stable),
+    ("pclmulqdq", Stable),
+    ("popcnt", Stable),
+    ("rdrand", Stable),
+    ("rdseed", Stable),
+    ("rtm", Unstable(sym::rtm_target_feature)),
+    ("sha", Stable),
+    ("sse", Stable),
+    ("sse2", Stable),
+    ("sse3", Stable),
+    ("sse4.1", Stable),
+    ("sse4.2", Stable),
+    ("sse4a", Unstable(sym::sse4a_target_feature)),
+    ("ssse3", Stable),
+    ("tbm", Unstable(sym::tbm_target_feature)),
+    ("vaes", Unstable(sym::avx512_target_feature)),
+    ("vpclmulqdq", Unstable(sym::avx512_target_feature)),
+    ("xsave", Stable),
+    ("xsavec", Stable),
+    ("xsaveopt", Stable),
+    ("xsaves", Stable),
+    // tidy-alphabetical-end
+];
+
+const HEXAGON_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("hvx", Unstable(sym::hexagon_target_feature)),
+    ("hvx-length128b", Unstable(sym::hexagon_target_feature)),
+    // tidy-alphabetical-end
+];
+
+const POWERPC_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("altivec", Unstable(sym::powerpc_target_feature)),
+    ("power10-vector", Unstable(sym::powerpc_target_feature)),
+    ("power8-altivec", Unstable(sym::powerpc_target_feature)),
+    ("power8-vector", Unstable(sym::powerpc_target_feature)),
+    ("power9-altivec", Unstable(sym::powerpc_target_feature)),
+    ("power9-vector", Unstable(sym::powerpc_target_feature)),
+    ("vsx", Unstable(sym::powerpc_target_feature)),
+    // tidy-alphabetical-end
+];
+
+const MIPS_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("fp64", Unstable(sym::mips_target_feature)),
+    ("msa", Unstable(sym::mips_target_feature)),
+    ("virt", Unstable(sym::mips_target_feature)),
+    // tidy-alphabetical-end
+];
+
+const RISCV_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("a", Stable),
+    ("c", Stable),
+    ("d", Unstable(sym::riscv_target_feature)),
+    ("e", Unstable(sym::riscv_target_feature)),
+    ("f", Unstable(sym::riscv_target_feature)),
+    ("fast-unaligned-access", Unstable(sym::riscv_target_feature)),
+    ("m", Stable),
+    ("relax", Unstable(sym::riscv_target_feature)),
+    ("v", 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)),
+    ("zfh", Unstable(sym::riscv_target_feature)),
+    ("zfhmin", Unstable(sym::riscv_target_feature)),
+    ("zfinx", Unstable(sym::riscv_target_feature)),
+    ("zhinx", Unstable(sym::riscv_target_feature)),
+    ("zhinxmin", Unstable(sym::riscv_target_feature)),
+    ("zk", Stable),
+    ("zkn", Stable),
+    ("zknd", Stable),
+    ("zkne", Stable),
+    ("zknh", Stable),
+    ("zkr", Stable),
+    ("zks", Stable),
+    ("zksed", Stable),
+    ("zksh", Stable),
+    ("zkt", Stable),
+    // tidy-alphabetical-end
+];
+
+const WASM_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("atomics", Unstable(sym::wasm_target_feature)),
+    ("bulk-memory", Unstable(sym::wasm_target_feature)),
+    ("exception-handling", Unstable(sym::wasm_target_feature)),
+    ("multivalue", Unstable(sym::wasm_target_feature)),
+    ("mutable-globals", Unstable(sym::wasm_target_feature)),
+    ("nontrapping-fptoint", Unstable(sym::wasm_target_feature)),
+    ("reference-types", Unstable(sym::wasm_target_feature)),
+    ("relaxed-simd", Unstable(sym::wasm_target_feature)),
+    ("sign-ext", Unstable(sym::wasm_target_feature)),
+    ("simd128", Stable),
+    // tidy-alphabetical-end
+];
+
+const BPF_ALLOWED_FEATURES: &[(&str, Stability)] = &[("alu32", Unstable(sym::bpf_target_feature))];
+
+const CSKY_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("10e60", Unstable(sym::csky_target_feature)),
+    ("2e3", Unstable(sym::csky_target_feature)),
+    ("3e3r1", Unstable(sym::csky_target_feature)),
+    ("3e3r2", Unstable(sym::csky_target_feature)),
+    ("3e3r3", Unstable(sym::csky_target_feature)),
+    ("3e7", Unstable(sym::csky_target_feature)),
+    ("7e10", Unstable(sym::csky_target_feature)),
+    ("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)),
+    ("e2", Unstable(sym::csky_target_feature)),
+    ("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)),
+    ("mp1e2", Unstable(sym::csky_target_feature)),
+    ("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)),
+    // tidy-alphabetical-end
+];
+
+const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[
+    // tidy-alphabetical-start
+    ("d", Unstable(sym::loongarch_target_feature)),
+    ("f", Unstable(sym::loongarch_target_feature)),
+    ("lasx", Unstable(sym::loongarch_target_feature)),
+    ("lbt", Unstable(sym::loongarch_target_feature)),
+    ("lsx", Unstable(sym::loongarch_target_feature)),
+    ("lvz", Unstable(sym::loongarch_target_feature)),
+    ("ual", Unstable(sym::loongarch_target_feature)),
+    // tidy-alphabetical-end
+];
+
+/// When rustdoc is running, provide a list of all known features so that all their respective
+/// primitives may be documented.
+///
+/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
+pub fn all_known_features() -> impl Iterator<Item = (&'static str, Stability)> {
+    std::iter::empty()
+        .chain(ARM_ALLOWED_FEATURES.iter())
+        .chain(AARCH64_ALLOWED_FEATURES.iter())
+        .chain(X86_ALLOWED_FEATURES.iter())
+        .chain(HEXAGON_ALLOWED_FEATURES.iter())
+        .chain(POWERPC_ALLOWED_FEATURES.iter())
+        .chain(MIPS_ALLOWED_FEATURES.iter())
+        .chain(RISCV_ALLOWED_FEATURES.iter())
+        .chain(WASM_ALLOWED_FEATURES.iter())
+        .chain(BPF_ALLOWED_FEATURES.iter())
+        .chain(CSKY_ALLOWED_FEATURES)
+        .chain(LOONGARCH_ALLOWED_FEATURES)
+        .cloned()
+}
+
+impl super::spec::Target {
+    pub fn supported_target_features(&self) -> &'static [(&'static str, Stability)] {
+        match &*self.arch {
+            "arm" => ARM_ALLOWED_FEATURES,
+            "aarch64" => AARCH64_ALLOWED_FEATURES,
+            "x86" | "x86_64" => X86_ALLOWED_FEATURES,
+            "hexagon" => HEXAGON_ALLOWED_FEATURES,
+            "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES,
+            "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
+            "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
+            "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
+            "bpf" => BPF_ALLOWED_FEATURES,
+            "csky" => CSKY_ALLOWED_FEATURES,
+            "loongarch64" => LOONGARCH_ALLOWED_FEATURES,
+            _ => &[],
+        }
+    }
+
+    pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
+        match &*self.arch {
+            "aarch64" => AARCH64_TIED_FEATURES,
+            _ => &[],
+        }
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 4b11cc3ace9..251f0628a71 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -101,11 +101,10 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
                         self.tcx.impl_trait_ref(impl_def_id).map(|r| (impl_def_id, r))
                     })
                     .map(|(impl_def_id, imp)| (impl_def_id, imp.skip_binder()))
-                    .filter(|(_, imp)| match imp.self_ty().peel_refs().kind() {
+                    .find(|(_, imp)| match imp.self_ty().peel_refs().kind() {
                         ty::Adt(i_def, _) if i_def.did() == def.did() => true,
                         _ => false,
                     })
-                    .next()
             {
                 let mut fulfill_cx = FulfillmentCtxt::new(self);
                 // We get all obligations from the impl to talk about specific
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index b3e7a63c972..cafb858794a 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -200,9 +200,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         let result = f(&mut ecx);
 
         let tree = ecx.inspect.finalize();
-        if let (Some(tree), DumpSolverProofTree::Always) =
-            (&tree, infcx.tcx.sess.opts.unstable_opts.dump_solver_proof_tree)
-        {
+        if let (Some(tree), DumpSolverProofTree::Always) = (
+            &tree,
+            infcx.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default(),
+        ) {
             let mut lock = std::io::stdout().lock();
             let _ = lock.write_fmt(format_args!("{tree:?}\n"));
             let _ = lock.flush();
@@ -377,7 +378,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         //
         // This assert was removed as it did not hold for goals constraining
         // an inference variable to a recursive alias, e.g. in
-        // tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs.
+        // tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs.
         //
         // Once we have decided on how to handle trait-system-refactor-initiative#75,
         // we should re-add an assert here.
@@ -421,7 +422,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                     self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
                 }
                 ty::PredicateKind::ConstEquate(_, _) => {
-                    bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active")
+                    bug!("ConstEquate should not be emitted when `-Znext-solver` is active")
                 }
                 ty::PredicateKind::NormalizesTo(predicate) => {
                     self.compute_normalizes_to_goal(Goal { param_env, predicate })
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
index 0d46df44c91..c857aae572d 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
@@ -265,7 +265,7 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
             GenerateProofTree::Never => ProofTreeBuilder::new_noop(),
             GenerateProofTree::IfEnabled => {
                 let opts = &tcx.sess.opts.unstable_opts;
-                match opts.dump_solver_proof_tree {
+                match opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() {
                     DumpSolverProofTree::Always => ProofTreeBuilder::new_root(),
                     // `OnError` is handled by reevaluating goals in error
                     // reporting with `GenerateProofTree::Yes`.
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index f45473e06dc..1e58106e353 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -1,7 +1,6 @@
 //! The next-generation trait solver, currently still WIP.
 //!
-//! As a user of rust, you can use `-Ztrait-solver=next` or `next-coherence`
-//! to enable the new trait solver always, or just within coherence, respectively.
+//! As a user of rust, you can use `-Znext-solver` to enable the new trait solver.
 //!
 //! As a developer of rustc, you shouldn't be using the new trait
 //! solver without asking the trait-system-refactor-initiative, but it can
@@ -248,7 +247,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             return None;
         }
 
-        // FIXME(-Ztrait-solver=next): We should instead try to find a `Certainty::Yes` response with
+        // FIXME(-Znext-solver): We should instead try to find a `Certainty::Yes` response with
         // a subset of the constraints that all the other responses have.
         let one = responses[0];
         if responses[1..].iter().all(|&resp| resp == one) {
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 2fe51b400ec..980ef862366 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -203,7 +203,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                     )
                     .into(),
                     ty::AssocKind::Type => Ty::new_error(tcx, guar).into(),
-                    ty::AssocKind::Fn => unreachable!(),
+                    // This makes no sense...
+                    ty::AssocKind::Fn => span_bug!(
+                        tcx.def_span(assoc_def.item.def_id),
+                        "cannot project to an associated function"
+                    ),
                 };
                 ecx.eq(goal.param_env, goal.predicate.term, error_term)
                     .expect("expected goal term to be fully unconstrained");
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 0b80969c307..d0e92a54ceb 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -8,16 +8,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         &mut self,
         goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
     ) -> QueryResult<'tcx> {
-        match goal.predicate.term.unpack() {
-            ty::TermKind::Ty(term) => {
-                let alias = goal.predicate.projection_ty.to_ty(self.tcx());
-                self.eq(goal.param_env, alias, term)?;
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-            }
-            // FIXME(associated_const_equality): actually do something here.
-            ty::TermKind::Const(_) => {
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-            }
-        }
+        let tcx = self.tcx();
+        let projection_term = match goal.predicate.term.unpack() {
+            ty::TermKind::Ty(_) => goal.predicate.projection_ty.to_ty(tcx).into(),
+            ty::TermKind::Const(_) => ty::Const::new_unevaluated(
+                tcx,
+                ty::UnevaluatedConst::new(
+                    goal.predicate.projection_ty.def_id,
+                    goal.predicate.projection_ty.args,
+                ),
+                tcx.type_of(goal.predicate.projection_ty.def_id)
+                    .instantiate(tcx, goal.predicate.projection_ty.args),
+            )
+            .into(),
+        };
+        self.add_goal(goal.with(
+            tcx,
+            ty::PredicateKind::AliasRelate(
+                projection_term,
+                goal.predicate.term,
+                ty::AliasRelationDirection::Equate,
+            ),
+        ));
+        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs
index 71adebffc15..2a08b80e02a 100644
--- a/compiler/rustc_trait_selection/src/solve/search_graph.rs
+++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs
@@ -38,7 +38,7 @@ struct StackEntry<'tcx> {
     /// If we were to use that result when later trying to prove another cycle
     /// participant, we can end up with unstable query results.
     ///
-    /// See tests/ui/new-solver/coinduction/incompleteness-unstable-result.rs for
+    /// See tests/ui/next-solver/coinduction/incompleteness-unstable-result.rs for
     /// an example of where this is needed.
     cycle_participants: FxHashSet<CanonicalInput<'tcx>>,
 }
@@ -237,7 +237,7 @@ impl<'tcx> SearchGraph<'tcx> {
                     // in unstable results due to incompleteness.
                     //
                     // However, a test for this would be an even more complex version of
-                    // tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs.
+                    // tests/ui/traits/next-solver/coinduction/incompleteness-unstable-result.rs.
                     // I did not bother to write such a test and we have no regression test
                     // for this. It would be good to have such a test :)
                     #[allow(rustc::potential_query_instability)]
@@ -248,7 +248,7 @@ impl<'tcx> SearchGraph<'tcx> {
                 // until we reach a fixpoint. It is not enough to simply retry the
                 // `root` goal of this cycle.
                 //
-                // See tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
+                // See tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
                 // for an example.
                 self.stack[stack_depth].has_been_used = true;
                 return if let Some(result) = self.stack[stack_depth].provisional_result {
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 5807f7c6153..deb50e6aefd 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -256,7 +256,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                     Err(NoSolution)
                 }
             }
-            ty::ImplPolarity::Reservation => bug!(),
+            // FIXME: Goal polarity should be split from impl polarity
+            ty::ImplPolarity::Reservation => {
+                bug!("we never expect a `Reservation` polarity in a trait goal")
+            }
         }
     }
 
@@ -445,7 +448,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             return Err(NoSolution);
         }
 
-        // FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
+        // FIXME(-Znext-solver): Implement this when we get const working in the new solver
 
         // `Destruct` is automatically implemented for every type in
         // non-const environments.
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index db4d4a93e54..533fe32f70d 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -273,7 +273,6 @@ fn overlap<'tcx>(
                                     causing the impls to overlap",
                                 infcx.resolve_vars_if_possible(failing_obligation.predicate)
                             ));
-                            lint
                         },
                     );
                 }
@@ -487,7 +486,7 @@ fn plug_infer_with_placeholders<'tcx>(
                         ),
                     )
                 else {
-                    bug!()
+                    bug!("we always expect to be able to plug an infer var with placeholder")
                 };
                 assert_eq!(obligations, &[]);
                 ControlFlow::Continue(())
@@ -510,7 +509,7 @@ fn plug_infer_with_placeholders<'tcx>(
                         ),
                     )
                 else {
-                    bug!()
+                    bug!("we always expect to be able to plug an infer var with placeholder")
                 };
                 assert_eq!(obligations, &[]);
                 ControlFlow::Continue(())
@@ -544,7 +543,7 @@ fn plug_infer_with_placeholders<'tcx>(
                             ),
                         )
                     else {
-                        bug!()
+                        bug!("we always expect to be able to plug an infer var with placeholder")
                     };
                     assert_eq!(obligations, &[]);
                 }
@@ -855,7 +854,7 @@ where
     }
 
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-        // Need to lazily normalize here in with `-Ztrait-solver=next-coherence`.
+        // Need to lazily normalize here in with `-Znext-solver=coherence`.
         let ty = match (self.lazily_normalize_ty)(ty) {
             Ok(ty) => ty,
             Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)),
@@ -1069,7 +1068,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
                 let lazily_normalize_ty = |ty: Ty<'tcx>| {
                     let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx);
                     if matches!(ty.kind(), ty::Alias(..)) {
-                        // FIXME(-Ztrait-solver=next-coherence): we currently don't
+                        // FIXME(-Znext-solver=coherence): we currently don't
                         // normalize opaque types here, resulting in diverging behavior
                         // for TAITs.
                         match infcx
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 67718d0a348..013a50f9fa1 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -25,7 +25,6 @@ use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::TypeFoldable;
 use rustc_middle::ty::Variance;
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_session::config::TraitSolver;
 
 pub trait TraitEngineExt<'tcx> {
     fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
@@ -33,18 +32,16 @@ pub trait TraitEngineExt<'tcx> {
 
 impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
     fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
-        match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) {
-            (TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => {
-                Box::new(FulfillmentContext::new(infcx))
-            }
-            (TraitSolver::Classic | TraitSolver::Next | TraitSolver::NextCoherence, true) => {
-                Box::new(NextFulfillmentCtxt::new(infcx))
-            }
-            (TraitSolver::Next, false) => bug!(
-                "incompatible combination of -Ztrait-solver flag ({:?}) and InferCtxt::next_trait_solver ({:?})",
-                infcx.tcx.sess.opts.unstable_opts.trait_solver,
-                infcx.next_trait_solver()
-            ),
+        if infcx.next_trait_solver() {
+            Box::new(NextFulfillmentCtxt::new(infcx))
+        } else {
+            let new_solver_globally =
+                infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally);
+            assert!(
+                !new_solver_globally,
+                "using old solver even though new solver is enabled globally"
+            );
+            Box::new(FulfillmentContext::new(infcx))
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index c07db12b25b..61e97dde5f8 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -103,7 +103,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     /// to be the enclosing (async) block/function/closure
     fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> {
         let hir = self.tcx.hir();
-        let node = hir.find(hir_id)?;
+        let node = self.tcx.opt_hir_node(hir_id)?;
         match &node {
             hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => {
                 self.describe_coroutine(*body_id).or_else(|| {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index f7e8dc62a62..a1b896d2251 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -530,7 +530,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
         // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
         //        don't suggest `T: Sized + ?Sized`.
-        while let Some(node) = self.tcx.hir().find_by_def_id(body_id) {
+        while let Some(node) = self.tcx.opt_hir_node_by_def_id(body_id) {
             match node {
                 hir::Node::Item(hir::Item {
                     ident,
@@ -732,7 +732,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let Some(typeck_results) = &self.typeck_results else {
             return false;
         };
-        let hir::Node::Expr(expr) = self.tcx.hir().get(*arg_hir_id) else {
+        let hir::Node::Expr(expr) = self.tcx.hir_node(*arg_hir_id) else {
             return false;
         };
         let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr) else {
@@ -785,7 +785,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             kind:
                                 hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, expr),
                             ..
-                        })) = self.tcx.hir().find(*arg_hir_id)
+                        })) = self.tcx.opt_hir_node(*arg_hir_id)
                         {
                             let derefs = "*".repeat(steps);
                             err.span_suggestion_verbose(
@@ -821,7 +821,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     if self.predicate_may_hold(&obligation)
                         && self.predicate_must_hold_modulo_regions(&sized_obligation)
                     {
-                        let call_node = self.tcx.hir().get(*call_hir_id);
+                        let call_node = self.tcx.hir_node(*call_hir_id);
                         let msg = "consider dereferencing here";
                         let is_receiver = matches!(
                             call_node,
@@ -1046,7 +1046,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let Res::Local(hir_id) = path.res else {
             return;
         };
-        let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else {
+        let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else {
             return;
         };
         let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =
@@ -1106,7 +1106,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         else {
             return false;
         };
-        let arg_node = self.tcx.hir().get(*arg_hir_id);
+        let arg_node = self.tcx.hir_node(*arg_hir_id);
         let Node::Expr(Expr { kind: hir::ExprKind::Path(_), .. }) = arg_node else { return false };
 
         let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None);
@@ -1387,14 +1387,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         err.message =
                             vec![(rustc_errors::DiagnosticMessage::from(msg), Style::NoStyle)];
                     }
+                    let mut file = None;
                     err.span_label(
                         span,
                         format!(
                             "the trait `{}` is not implemented for `{}`",
                             old_pred.print_modifiers_and_trait_path(),
-                            old_pred.self_ty().skip_binder(),
+                            self.tcx.short_ty_string(old_pred.self_ty().skip_binder(), &mut file),
                         ),
                     );
+                    if let Some(file) = file {
+                        err.note(format!(
+                            "the full type name has been written to '{}'",
+                            file.display()
+                        ));
+                    }
 
                     if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
                         err.span_suggestions(
@@ -1628,7 +1635,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let Res::Local(hir_id) = path.res
-                && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id)
+                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(hir_id)
                 && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
                 && let None = local.ty
                 && let Some(binding_expr) = local.init
@@ -1644,7 +1651,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) {
         let hir = self.tcx.hir();
         if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives()
-            && let hir::Node::Expr(expr) = hir.get(*hir_id)
+            && let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id)
         {
             // FIXME: use `obligation.predicate.kind()...trait_ref.self_ty()` to see if we have `()`
             // and if not maybe suggest doing something else? If we kept the expression around we
@@ -1794,7 +1801,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
         let hir = self.tcx.hir();
-        let node = hir.find_by_def_id(obligation.cause.body_id);
+        let node = self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id);
         if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node
             && let hir::ExprKind::Block(blk, _) = &hir.body(*body_id).value.kind
             && sig.decl.output.span().overlaps(span)
@@ -1829,9 +1836,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     }
 
     fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
-        let hir = self.tcx.hir();
         let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) =
-            hir.find_by_def_id(obligation.cause.body_id)
+            self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id)
         else {
             return None;
         };
@@ -1923,7 +1929,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         }
 
         let hir = self.tcx.hir();
-        let node = hir.find_by_def_id(obligation.cause.body_id);
+        let node = self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id);
         if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) =
             node
         {
@@ -2041,7 +2047,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let ty::FnPtr(found) = found.kind() else {
             return;
         };
-        let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) else {
+        let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id) else {
             return;
         };
         let hir::ExprKind::Path(path) = arg.kind else {
@@ -2167,7 +2173,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             })
             .collect();
         err.multipart_suggestion(
-            format!("consider wrapping the function in a closure"),
+            "consider wrapping the function in a closure",
             vec![
                 (arg.span.shrink_to_lo(), format!("|{}| ", closure_names.join(", "))),
                 (arg.span.shrink_to_hi(), format!("({})", call_names.join(", "))),
@@ -2917,22 +2923,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             ObligationCauseCode::Coercion { source, target } => {
-                let (source, source_file) =
-                    self.tcx.short_ty_string(self.resolve_vars_if_possible(source));
-                let (target, target_file) =
-                    self.tcx.short_ty_string(self.resolve_vars_if_possible(target));
+                let mut file = None;
+                let source =
+                    self.tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut file);
+                let target =
+                    self.tcx.short_ty_string(self.resolve_vars_if_possible(target), &mut file);
                 err.note(with_forced_trimmed_paths!(format!(
                     "required for the cast from `{source}` to `{target}`",
                 )));
-                if let Some(file) = source_file {
-                    err.note(format!(
-                        "the full name for the source type has been written to '{}'",
-                        file.display(),
-                    ));
-                }
-                if let Some(file) = target_file {
+                if let Some(file) = file {
                     err.note(format!(
-                        "the full name for the target type has been written to '{}'",
+                        "the full name for the type has been written to '{}'",
                         file.display(),
                     ));
                 }
@@ -2986,7 +2987,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             ObligationCauseCode::VariableType(hir_id) => {
                 let parent_node = self.tcx.hir().parent_id(hir_id);
-                match self.tcx.hir().find(parent_node) {
+                match self.tcx.opt_hir_node(parent_node) {
                     Some(Node::Local(hir::Local { ty: Some(ty), .. })) => {
                         err.span_suggestion_verbose(
                             ty.span.shrink_to_lo(),
@@ -3130,7 +3131,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     "all values captured by value by a closure must have a statically known size",
                 );
                 let hir::ExprKind::Closure(closure) =
-                    self.tcx.hir().get_by_def_id(closure_def_id).expect_expr().kind
+                    self.tcx.hir_node_by_def_id(closure_def_id).expect_expr().kind
                 else {
                     bug!("expected closure in SizedClosureCapture obligation");
                 };
@@ -3185,9 +3186,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 // Don't print the tuple of capture types
                 'print: {
                     if !is_upvar_tys_infer_tuple {
-                        let msg = with_forced_trimmed_paths!(format!(
-                            "required because it appears within the type `{ty}`",
-                        ));
+                        let mut file = None;
+                        let ty_str = self.tcx.short_ty_string(ty, &mut file);
+                        let msg = format!("required because it appears within the type `{ty_str}`");
                         match ty.kind() {
                             ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) {
                                 Some(ident) => err.span_note(ident.span, msg),
@@ -3284,8 +3285,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 let mut parent_trait_pred =
                     self.resolve_vars_if_possible(data.derived.parent_trait_pred);
                 let parent_def_id = parent_trait_pred.def_id();
-                let (self_ty, file) =
-                    self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
+                let mut file = None;
+                let self_ty =
+                    self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file);
                 let msg = format!(
                     "required for `{self_ty}` to implement `{}`",
                     parent_trait_pred.print_modifiers_and_trait_path()
@@ -3382,8 +3384,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         count,
                         pluralize!(count)
                     ));
-                    let (self_ty, file) =
-                        self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
+                    let mut file = None;
+                    let self_ty = self
+                        .tcx
+                        .short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file);
                     err.note(format!(
                         "required for `{self_ty}` to implement `{}`",
                         parent_trait_pred.print_modifiers_and_trait_path()
@@ -3701,8 +3705,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         call_hir_id: HirId,
     ) {
         let tcx = self.tcx;
-        let hir = tcx.hir();
-        if let Some(Node::Expr(expr)) = hir.find(arg_hir_id)
+        if let Some(Node::Expr(expr)) = tcx.opt_hir_node(arg_hir_id)
             && let Some(typeck_results) = &self.typeck_results
         {
             if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
@@ -3735,7 +3738,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             && let hir::ExprKind::Closure(hir::Closure {
                                 body, fn_decl_span, ..
                             }) = value.kind
-                            && let body = hir.body(*body)
+                            && let body = tcx.hir().body(*body)
                             && !matches!(body.value.kind, hir::ExprKind::Block(..))
                         {
                             // Check if the failed predicate was an expectation of a closure type
@@ -3818,9 +3821,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: Res::Local(hir_id), .. } = path
-                && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
+                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
                 && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id)
-                && let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
+                && let Some(hir::Node::Local(local)) = self.tcx.opt_hir_node(parent_hir_id)
                 && let Some(binding_expr) = local.init
             {
                 // If the expression we're calling on is a binding, we want to point at the
@@ -3831,7 +3834,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
             }
         }
-        let call_node = hir.find(call_hir_id);
+        let call_node = tcx.opt_hir_node(call_hir_id);
         if let Some(Node::Expr(hir::Expr {
             kind: hir::ExprKind::MethodCall(path, rcvr, ..), ..
         })) = call_node
@@ -3841,7 +3844,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         }
 
-        if let Some(Node::Expr(expr)) = hir.find(call_hir_id) {
+        if let Some(Node::Expr(expr)) = tcx.opt_hir_node(call_hir_id) {
             if let hir::ExprKind::Call(hir::Expr { span, .. }, _)
             | hir::ExprKind::MethodCall(
                 hir::PathSegment { ident: Ident { span, .. }, .. },
@@ -4002,7 +4005,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             continue;
                         };
                         let hir = tcx.hir();
-                        let node = hir.get_by_def_id(hir.get_parent_item(expr.hir_id).def_id);
+                        let node = tcx.hir_node_by_def_id(hir.get_parent_item(expr.hir_id).def_id);
 
                         let pred = ty::Binder::dummy(ty::TraitPredicate {
                             trait_ref: ty::TraitRef::from_lang_item(
@@ -4078,7 +4081,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: Res::Local(hir_id), .. } = path
-                && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
+                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
                 && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
                 // We've reached the root of the method call chain...
@@ -4457,7 +4460,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             return;
         };
-        let Some(hir::Node::TraitItem(item)) = self.tcx.hir().find_by_def_id(fn_def_id) else {
+        let Some(hir::Node::TraitItem(item)) = self.tcx.opt_hir_node_by_def_id(fn_def_id) else {
             return;
         };
 
@@ -4662,7 +4665,7 @@ pub trait NextTypeParamName {
 impl NextTypeParamName for &[hir::GenericParam<'_>] {
     fn next_type_param_name(&self, name: Option<&str>) -> String {
         // This is the list of possible parameter names that we might suggest.
-        let name = name.and_then(|n| n.chars().next()).map(|c| c.to_string().to_uppercase());
+        let name = name.and_then(|n| n.chars().next()).map(|c| c.to_uppercase().to_string());
         let name = name.as_deref();
         let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"];
         let used_names = self
@@ -4709,6 +4712,7 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
 }
 
 pub(super) fn get_explanation_based_on_obligation<'tcx>(
+    tcx: TyCtxt<'tcx>,
     obligation: &PredicateObligation<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>,
     trait_predicate: &ty::PolyTraitPredicate<'tcx>,
@@ -4729,13 +4733,13 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
                 pre_message,
                 trait_predicate.print_modifiers_and_trait_path(),
                 desc,
-                trait_ref.skip_binder().self_ty(),
+                tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None),
             ),
             None => format!(
                 "{}the trait `{}` is not implemented for `{}`",
                 pre_message,
                 trait_predicate.print_modifiers_and_trait_path(),
-                trait_ref.skip_binder().self_ty(),
+                tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None),
             ),
         }
     }
@@ -4778,9 +4782,15 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
         return None;
     };
 
-    let future = tcx.hir().get_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
-    let Some(hir::GenericBound::LangItemTrait(_, _, _, generics)) = future.bounds.get(0) else {
-        // `async fn` should always lower to a lang item bound... but don't ICE.
+    let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
+    let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
+        // `async fn` should always lower to a single bound... but don't ICE.
+        return None;
+    };
+    let Some(hir::PathSegment { args: Some(generics), .. }) =
+        trait_ref.trait_ref.path.segments.last()
+    else {
+        // desugaring to a single path segment for `Future<...>`.
         return None;
     };
     let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) =
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 4988222c135..5cc934e7bc5 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -37,7 +37,7 @@ use rustc_middle::ty::{
     self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
     TypeVisitable, TypeVisitableExt,
 };
-use rustc_session::config::{DumpSolverProofTree, TraitSolver};
+use rustc_session::config::DumpSolverProofTree;
 use rustc_session::Limit;
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::symbol::sym;
@@ -250,7 +250,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         err.emit();
 
         self.tcx.sess.abort_if_errors();
-        bug!();
+        // FIXME: this should be something like `build_overflow_error_fatal`, which returns
+        // `DiagnosticBuilder<', !>`. Then we don't even need anything after that `emit()`.
+        unreachable!(
+            "did not expect compilation to continue after `abort_if_errors`, \
+            since an error was definitely emitted!"
+        );
     }
 
     fn build_overflow_error<T>(
@@ -370,7 +375,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) {
         let tcx = self.tcx;
 
-        if tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError {
+        if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
+            == DumpSolverProofTree::OnError
+        {
             dump_proof_tree(root_obligation, self.infcx);
         }
 
@@ -444,21 +451,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             // reported on the binding definition (#56607).
                             return;
                         }
-                        let (post_message, pre_message, type_def, file_note) = self
+                        let mut file = None;
+                        let (post_message, pre_message, type_def) = self
                             .get_parent_trait_ref(obligation.cause.code())
                             .map(|(t, s)| {
-                                let (t, file) = self.tcx.short_ty_string(t);
+                                let t = self.tcx.short_ty_string(t, &mut file);
                                 (
                                     format!(" in `{t}`"),
                                     format!("within `{t}`, "),
                                     s.map(|s| (format!("within this `{t}`"), s)),
-                                    file.map(|file| format!(
-                                        "the full trait has been written to '{}'",
-                                        file.display(),
-                                    ))
                                 )
                             })
                             .unwrap_or_default();
+                        let file_note = file.map(|file| format!(
+                            "the full trait has been written to '{}'",
+                            file.display(),
+                        ));
 
                         let OnUnimplementedNote {
                             message,
@@ -547,6 +555,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         }
 
                         let explanation = get_explanation_based_on_obligation(
+                            self.tcx,
                             &obligation,
                             trait_ref,
                             &trait_predicate,
@@ -810,23 +819,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
                     ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {
                         let ty = self.resolve_vars_if_possible(ty);
-                        match self.tcx.sess.opts.unstable_opts.trait_solver {
-                            TraitSolver::Classic => {
-                                // WF predicates cannot themselves make
-                                // errors. They can only block due to
-                                // ambiguity; otherwise, they always
-                                // degenerate into other obligations
-                                // (which may fail).
-                                span_bug!(span, "WF predicate not satisfied for {:?}", ty);
-                            }
-                            TraitSolver::Next | TraitSolver::NextCoherence => {
-                                // FIXME: we'll need a better message which takes into account
-                                // which bounds actually failed to hold.
-                                self.tcx.sess.struct_span_err(
-                                    span,
-                                    format!("the type `{ty}` is not well-formed"),
-                                )
-                            }
+                        if self.next_trait_solver() {
+                            // FIXME: we'll need a better message which takes into account
+                            // which bounds actually failed to hold.
+                            self.tcx.sess.struct_span_err(
+                                span,
+                                format!("the type `{ty}` is not well-formed"),
+                            )
+                        } else {
+                            // WF predicates cannot themselves make
+                            // errors. They can only block due to
+                            // ambiguity; otherwise, they always
+                            // degenerate into other obligations
+                            // (which may fail).
+                            span_bug!(span, "WF predicate not satisfied for {:?}", ty);
                         }
                     }
 
@@ -984,13 +990,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool {
         if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
             obligation.cause.code()
-            && let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id)
+            && let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id)
             && let arg = arg.peel_borrows()
             && let hir::ExprKind::Path(hir::QPath::Resolved(
                 None,
                 hir::Path { res: hir::def::Res::Local(hir_id), .. },
             )) = arg.kind
-            && let Some(Node::Pat(pat)) = self.tcx.hir().find(*hir_id)
+            && let Some(Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id)
             && let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span)
             && preds.contains(&obligation.predicate)
         {
@@ -1028,7 +1034,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         }
         let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id);
-        let body_id = match self.tcx.hir().find(hir_id) {
+        let body_id = match self.tcx.opt_hir_node(hir_id) {
             Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => {
                 body_id
             }
@@ -1069,7 +1075,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             if !self.tcx.is_diagnostic_item(sym::Result, def.did()) {
                 return None;
             }
-            Some(arg.as_type()?)
+            arg.as_type()
         };
 
         let mut suggested = false;
@@ -1154,7 +1160,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
-                && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
+                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
                 && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
                 // We've reached the root of the method call chain...
@@ -1560,7 +1566,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
-        if self.tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError {
+        if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
+            == DumpSolverProofTree::OnError
+        {
             dump_proof_tree(&error.root_obligation, self.infcx);
         }
 
@@ -1666,7 +1674,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     )
                     .into(),
                 };
-                // FIXME(-Ztrait-solver=next): For diagnostic purposes, it would be nice
+                // FIXME(-Znext-solver): For diagnostic purposes, it would be nice
                 // to deeply normalize this type.
                 let normalized_term =
                     ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
@@ -2499,7 +2507,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 ident: trait_name,
                                 kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs),
                                 ..
-                            })) = self.tcx.hir().find_by_def_id(local_def_id)
+                            })) = self.tcx.opt_hir_node_by_def_id(local_def_id)
                             && let Some(method_ref) = trait_item_refs
                                 .iter()
                                 .find(|item_ref| item_ref.ident == *assoc_item_name)
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index 2f2411310a9..cf4fa233768 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -9,7 +9,7 @@ use rustc_infer::infer::canonical::Canonical;
 use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError};
-use rustc_middle::ty::{self, AdtDef, GenericArg, List, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, AdtDef, GenericArg, List, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::DUMMY_SP;
 
 use super::outlives_bounds::InferCtxtExt;
@@ -209,10 +209,10 @@ pub fn all_fields_implement_trait<'tcx>(
 
 pub fn check_tys_might_be_eq<'tcx>(
     tcx: TyCtxt<'tcx>,
-    canonical: Canonical<'tcx, (ParamEnv<'tcx>, Ty<'tcx>, Ty<'tcx>)>,
+    canonical: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>,
 ) -> Result<(), NoSolution> {
-    let (infcx, (param_env, ty_a, ty_b), _) =
-        tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical);
+    let (infcx, key, _) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical);
+    let (param_env, (ty_a, ty_b)) = key.into_parts();
     let ocx = ObligationCtxt::new(&infcx);
 
     let result = ocx.eq(&ObligationCause::dummy(), param_env, ty_a, ty_b);
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 64d2b5fc159..8c5f1e90715 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -315,7 +315,7 @@ pub fn normalize_param_env_or_error<'tcx>(
             // We do not normalize types here as there is no backwards compatibility requirement
             // for us to do so.
             //
-            // FIXME(-Ztrait-solver=next): remove this hack since we have deferred projection equality
+            // FIXME(-Znext-solver): remove this hack since we have deferred projection equality
             predicate.fold_with(&mut ConstNormalizer(tcx))
         }),
     )
@@ -386,7 +386,7 @@ pub fn normalize_param_env_or_error<'tcx>(
 
 /// Normalize a type and process all resulting obligations, returning any errors.
 ///
-/// FIXME(-Ztrait-solver=next): This should be replaced by `At::deeply_normalize`
+/// FIXME(-Znext-solver): This should be replaced by `At::deeply_normalize`
 /// which has the same behavior with the new solver. Because using a separate
 /// fulfillment context worsens caching in the old solver, `At::deeply_normalize`
 /// is still lazy with the old solver as it otherwise negatively impacts perf.
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index fbde7455145..47a79bfa9ab 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -194,7 +194,6 @@ fn lint_object_unsafe_trait(
                 // Only provide the help if its a local trait, otherwise it's not
                 violation.solution().add_to(err);
             }
-            err
         },
     );
 }
@@ -345,7 +344,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     // Search for a predicate like `Self : Sized` amongst the trait bounds.
     let predicates = tcx.predicates_of(def_id);
     let predicates = predicates.instantiate_identity(tcx).predicates;
-    elaborate(tcx, predicates.into_iter()).any(|pred| match pred.kind().skip_binder() {
+    elaborate(tcx, predicates).any(|pred| match pred.kind().skip_binder() {
         ty::ClauseKind::Trait(ref trait_pred) => {
             trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0)
         }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index a08e35b566f..d5635812c74 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -67,7 +67,7 @@ pub trait NormalizeExt<'tcx> {
     /// same goals in both a temporary and the shared context which negatively impacts
     /// performance as these don't share caching.
     ///
-    /// FIXME(-Ztrait-solver=next): This has the same behavior as `traits::fully_normalize`
+    /// FIXME(-Znext-solver): This has the same behavior as `traits::fully_normalize`
     /// in the new solver, but because of performance reasons, we currently reuse an
     /// existing fulfillment context in the old solver. Once we also eagerly prove goals with
     /// the old solver or have removed the old solver, remove `traits::fully_normalize` and
@@ -191,7 +191,9 @@ impl<'tcx> ProjectionCandidateSet<'tcx> {
                 match (current, candidate) {
                     (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (),
                     (ParamEnv(..), _) => return false,
-                    (_, ParamEnv(..)) => unreachable!(),
+                    (_, ParamEnv(..)) => bug!(
+                        "should never prefer non-param-env candidates over param-env candidates"
+                    ),
                     (_, _) => convert_to_ambiguous = (),
                 }
             }
@@ -2080,10 +2082,11 @@ fn confirm_coroutine_candidate<'cx, 'tcx>(
     obligation: &ProjectionTyObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let ty::Coroutine(_, args, _) =
-        selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
-    else {
-        unreachable!()
+    let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
+    let ty::Coroutine(_, args, _) = self_ty.kind() else {
+        unreachable!(
+            "expected coroutine self type for built-in coroutine candidate, found {self_ty}"
+        )
     };
     let coroutine_sig = args.as_coroutine().sig();
     let Normalized { value: coroutine_sig, obligations } = normalize_with_depth(
@@ -2113,7 +2116,10 @@ fn confirm_coroutine_candidate<'cx, 'tcx>(
     } else if name == sym::Yield {
         yield_ty
     } else {
-        bug!()
+        span_bug!(
+            tcx.def_span(obligation.predicate.def_id),
+            "unexpected associated type: `Coroutine::{name}`"
+        );
     };
 
     let predicate = ty::ProjectionPredicate {
@@ -2131,10 +2137,11 @@ fn confirm_future_candidate<'cx, 'tcx>(
     obligation: &ProjectionTyObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let ty::Coroutine(_, args, _) =
-        selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
-    else {
-        unreachable!()
+    let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
+    let ty::Coroutine(_, args, _) = self_ty.kind() else {
+        unreachable!(
+            "expected coroutine self type for built-in async future candidate, found {self_ty}"
+        )
     };
     let coroutine_sig = args.as_coroutine().sig();
     let Normalized { value: coroutine_sig, obligations } = normalize_with_depth(
@@ -2174,10 +2181,9 @@ fn confirm_iterator_candidate<'cx, 'tcx>(
     obligation: &ProjectionTyObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let ty::Coroutine(_, args, _) =
-        selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
-    else {
-        unreachable!()
+    let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
+    let ty::Coroutine(_, args, _) = self_ty.kind() else {
+        unreachable!("expected coroutine self type for built-in gen candidate, found {self_ty}")
     };
     let gen_sig = args.as_coroutine().sig();
     let Normalized { value: gen_sig, obligations } = normalize_with_depth(
@@ -2341,9 +2347,9 @@ fn confirm_closure_candidate<'cx, 'tcx>(
     obligation: &ProjectionTyObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let ty::Closure(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
-    else {
-        unreachable!()
+    let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
+    let ty::Closure(_, args) = self_ty.kind() else {
+        unreachable!("expected closure self type for closure candidate, found {self_ty}")
     };
     let closure_sig = args.as_closure().sig();
     let Normalized { value: closure_sig, obligations } = normalize_with_depth(
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index 04b3119323f..d812d537d8c 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -72,7 +72,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
                 let mut fulfill_cx = crate::solve::FulfillmentCtxt::new(self);
                 fulfill_cx.register_predicate_obligation(self, obligation.clone());
                 // True errors
-                // FIXME(-Ztrait-solver=next): Overflows are reported as ambig here, is that OK?
+                // FIXME(-Znext-solver): Overflows are reported as ambig here, is that OK?
                 if !fulfill_cx.select_where_possible(self).is_empty() {
                     Ok(EvaluationResult::EvaluatedToErr)
                 } else if !fulfill_cx.select_all_or_error(self).is_empty() {
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 4728fcf3301..ed55533bc55 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -285,7 +285,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
                     ty::Projection => tcx.normalize_projection_ty(c_data),
                     ty::Weak => tcx.normalize_weak_ty(c_data),
                     ty::Inherent => tcx.normalize_inherent_projection_ty(c_data),
-                    _ => unreachable!(),
+                    kind => unreachable!("did not expect {kind:?} due to match arm above"),
                 }?;
                 // We don't expect ambiguity.
                 if !result.value.is_proven() {
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 302b6016e5e..152ceeee869 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
@@ -26,7 +26,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
         tcx.type_op_ascribe_user_type(canonicalized)
     }
 
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution> {
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs
index f6589308806..57e649f3e43 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs
@@ -23,7 +23,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> {
         tcx.type_op_eq(canonicalized)
     }
 
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution> {
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index f9b8ea32d89..ba6ed298774 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -50,7 +50,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
         tcx.implied_outlives_bounds(canonicalized)
     }
 
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution> {
@@ -184,7 +184,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
                 push_outlives_components(tcx, ty_a, &mut components);
                 implied_bounds.extend(implied_bounds_from_components(r_b, components))
             }
-            ty::GenericArgKind::Const(_) => unreachable!(),
+            ty::GenericArgKind::Const(_) => {
+                unreachable!("consts do not participate in outlives bounds")
+            }
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index cd09aaff2d9..272f1a54f81 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -89,7 +89,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
     /// make sure to feed it predefined opaque types and the defining anchor
     /// and that would require duplicating all of the tcx queries. Instead,
     /// just perform these ops locally.
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution>;
@@ -149,7 +149,7 @@ where
         if infcx.next_trait_solver() {
             return Ok(scrape_region_constraints(
                 infcx,
-                |ocx| QueryTypeOp::perform_locally_in_new_solver(ocx, self),
+                |ocx| QueryTypeOp::perform_locally_with_next_solver(ocx, self),
                 "query type op",
                 span,
             )?
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
index 9559f5002f6..3b33f6e6144 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
@@ -25,11 +25,11 @@ where
         T::type_op_method(tcx, canonicalized)
     }
 
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution> {
-        // FIXME(-Ztrait-solver=next): shouldn't be using old normalizer
+        // FIXME(-Znext-solver): shouldn't be using old normalizer
         Ok(ocx.normalize(&ObligationCause::dummy(), key.param_env, key.value.value))
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
index f2c1243f931..07587e37411 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
@@ -42,7 +42,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
         tcx.dropck_outlives(canonicalized)
     }
 
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution> {
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
index 789ef647246..e21ede47f6d 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
@@ -40,7 +40,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
         tcx.type_op_prove_predicate(canonicalized)
     }
 
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution> {
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs
index 10976d5cd71..ae11b0825bd 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs
@@ -20,7 +20,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> {
         tcx.type_op_subtype(canonicalized)
     }
 
-    fn perform_locally_in_new_solver(
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
     ) -> Result<Self::QueryResponse, NoSolution> {
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 4a342a7f6b1..7e3d304d1cd 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -942,8 +942,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let a_ty = self.infcx.shallow_resolve(predicate.self_ty());
         let b_ty = self.infcx.shallow_resolve(predicate.trait_ref.args.type_at(1));
 
-        let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else { bug!() };
-        let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else { bug!() };
+        let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else {
+            bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
+        };
+        let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else {
+            bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
+        };
 
         let source_principal = a_data.principal().unwrap().with_self_ty(tcx, a_ty);
         let unnormalized_upcast_principal =
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 39f5ff52eba..71a88f5f07c 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -450,7 +450,6 @@ fn report_conflicting_impls<'tcx>(
                 msg,
                 |err| {
                     decorate(tcx, &overlap, impl_span, err);
-                    err
                 },
             );
         }
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index 32de8feda81..b9ab26fe2fe 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -22,7 +22,7 @@ impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
         assert!(!ty.is_ty_var(), "should have resolved vars before calling");
 
         if self.infcx.next_trait_solver() {
-            // FIXME(-Ztrait-solver=next): correctly handle
+            // FIXME(-Znext-solver): correctly handle
             // overflow here.
             for _ in 0..256 {
                 let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, alias) = *ty.kind() else {
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 98da3bc2fe9..575010ff46d 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -220,9 +220,8 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
         selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates);
     let impl_obligations = super::predicates_for_generics(cause, param_env, predicates);
 
-    let impl_obligations = impl_obligations
-        .chain(normalization_obligations1.into_iter())
-        .chain(normalization_obligations2.into_iter());
+    let impl_obligations =
+        impl_obligations.chain(normalization_obligations1).chain(normalization_obligations2);
 
     (subject, impl_obligations)
 }
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 7a81570e55b..db37bec4b82 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -345,8 +345,7 @@ fn associated_type_for_impl_trait_in_impl(
     let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
 
     let decl = tcx
-        .hir()
-        .find_by_def_id(impl_fn_def_id)
+        .opt_hir_node_by_def_id(impl_fn_def_id)
         .expect("expected item")
         .fn_decl()
         .expect("expected decl");
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index eef90dc6dac..3f9bd509b08 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -161,7 +161,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
 }
 
 fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> + '_ {
-    let node = tcx.hir().get(tcx.local_def_id_to_hir_id(def_id));
+    let node = tcx.hir_node_by_def_id(def_id);
     if let Some(decl) = node.fn_decl() {
         decl.inputs.iter().map(|ty| ty.span).chain(iter::once(decl.output.span()))
     } else {
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index d896873fadd..7918965e04b 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -831,7 +831,10 @@ fn coroutine_layout<'tcx>(
                     Assigned(_) => bug!("assignment does not match variant"),
                     Ineligible(_) => false,
                 })
-                .map(|local| subst_field(info.field_tys[*local].ty));
+                .map(|local| {
+                    let field_ty = subst_field(info.field_tys[*local].ty);
+                    Ty::new_maybe_uninit(tcx, field_ty)
+                });
 
             let mut variant = univariant_uninterned(
                 cx,
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
index 7c0261c818f..b155a4ac87b 100644
--- a/compiler/rustc_ty_utils/src/sig_types.rs
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -28,7 +28,7 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         // Walk over the signature of the function
         DefKind::AssocFn | DefKind::Fn => {
             let ty_sig = tcx.fn_sig(item).instantiate_identity();
-            let hir_sig = tcx.hir().get_by_def_id(item).fn_decl().unwrap();
+            let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
             // Walk over the inputs and outputs manually in order to get good spans for them.
             visitor.visit(hir_sig.output.span(), ty_sig.output());
             for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
@@ -42,7 +42,7 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         DefKind::TyAlias {..} | DefKind::AssocTy |
         // Walk over the type of the item
         DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
-            let span = match tcx.hir().get_by_def_id(item).ty() {
+            let span = match tcx.hir_node_by_def_id(item).ty() {
                 Some(ty) => ty.span,
                 _ => tcx.def_span(item),
             };
@@ -70,11 +70,11 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         DefKind::InlineConst | DefKind::Closure => {}
         DefKind::Impl { of_trait } => {
             if of_trait {
-                let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
+                let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
                 let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..];
                 visitor.visit(span, args)?;
             }
-            let span = match tcx.hir().get_by_def_id(item).ty() {
+            let span = match tcx.hir_node_by_def_id(item).ty() {
                 Some(ty) => ty.span,
                 _ => tcx.def_span(item),
             };
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 56e84b6015d..2158aacab03 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -74,7 +74,7 @@ fn sized_constraint_for_ty<'tcx>(
 }
 
 fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness {
-    match tcx.hir().get_by_def_id(def_id) {
+    match tcx.hir_node_by_def_id(def_id) {
         hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.defaultness,
         hir::Node::ImplItem(hir::ImplItem { defaultness, .. })
         | hir::Node::TraitItem(hir::TraitItem { defaultness, .. }) => *defaultness,
@@ -300,7 +300,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<'
 
 /// Check if a function is async.
 fn asyncness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Asyncness {
-    let node = tcx.hir().get_by_def_id(def_id);
+    let node = tcx.hir_node_by_def_id(def_id);
     node.fn_sig().map_or(ty::Asyncness::No, |sig| match sig.header.asyncness {
         hir::IsAsync::Async(_) => ty::Asyncness::Yes,
         hir::IsAsync::NotAsync => ty::Asyncness::No,
diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs
index 8998001ec20..9c8e45b4338 100644
--- a/compiler/rustc_type_ir/src/debug.rs
+++ b/compiler/rustc_type_ir/src/debug.rs
@@ -32,11 +32,7 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
         None
     }
 
-    fn root_lt_var(&self, vid: I::InferRegion) -> I::InferRegion {
-        vid
-    }
-
-    fn probe_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
+    fn opportunistic_resolve_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
         None
     }
 
diff --git a/compiler/rustc_type_ir/src/infcx.rs b/compiler/rustc_type_ir/src/infcx.rs
index 681f129a50b..28b71f0ea13 100644
--- a/compiler/rustc_type_ir/src/infcx.rs
+++ b/compiler/rustc_type_ir/src/infcx.rs
@@ -18,14 +18,14 @@ pub trait InferCtxtLike {
         lt: <Self::Interner as Interner>::InferRegion,
     ) -> Option<UniverseIndex>;
 
-    /// Resolve `InferRegion` to its root `InferRegion`.
-    fn root_lt_var(
-        &self,
-        vid: <Self::Interner as Interner>::InferRegion,
-    ) -> <Self::Interner as Interner>::InferRegion;
-
-    /// Resolve `InferRegion` to its inferred region, if it has been equated with a non-infer region.
-    fn probe_lt_var(
+    /// Resolve `InferRegion` to its inferred region, if it has been equated with
+    /// a non-infer region.
+    ///
+    /// FIXME: This has slightly different semantics than `{probe,resolve}_{ty,ct}_var`,
+    /// that has to do with the fact unlike `Ty` or `Const` vars, in rustc, we may
+    /// not always be able to *name* the root region var from the universe of the
+    /// var we're trying to resolve. That's why it's called *opportunistic*.
+    fn opportunistic_resolve_lt_var(
         &self,
         vid: <Self::Interner as Interner>::InferRegion,
     ) -> Option<<Self::Interner as Interner>::Region>;
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index c262302133b..188910ecc52 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -3,8 +3,8 @@ use std::fmt::Debug;
 use std::hash::Hash;
 
 use crate::{
-    BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, Mutability, RegionKind,
-    TyKind, UniverseIndex,
+    BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind,
+    UniverseIndex,
 };
 
 pub trait Interner: Sized {
@@ -20,7 +20,6 @@ pub trait Interner: Sized {
     type Term: Copy + Debug + Hash + Ord;
 
     type Binder<T>;
-    type TypeAndMut: Copy + Debug + Hash + Ord;
     type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
 
     // Kinds of tys
@@ -81,8 +80,6 @@ pub trait Interner: Sized {
     type CoercePredicate: Copy + Debug + Hash + Eq;
     type ClosureKind: Copy + Debug + Hash + Eq;
 
-    fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability);
-
     fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
 
     // FIXME: We should not have all these constructors on `Interner`, but as functions on some trait.
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 200963ff7c5..bff93859645 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -359,3 +359,45 @@ rustc_index::newtype_index! {
     #[gate_rustc_only]
     pub struct BoundVar {}
 }
+
+/// Represents the various closure traits in the language. This
+/// will determine the type of the environment (`self`, in the
+/// desugaring) argument that the closure expects.
+///
+/// You can get the environment type of a closure using
+/// `tcx.closure_env_ty()`.
+#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
+#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
+pub enum ClosureKind {
+    // Warning: Ordering is significant here! The ordering is chosen
+    // because the trait Fn is a subtrait of FnMut and so in turn, and
+    // hence we order it so that Fn < FnMut < FnOnce.
+    Fn,
+    FnMut,
+    FnOnce,
+}
+
+impl ClosureKind {
+    /// This is the initial value used when doing upvar inference.
+    pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
+
+    pub const fn as_str(self) -> &'static str {
+        match self {
+            ClosureKind::Fn => "Fn",
+            ClosureKind::FnMut => "FnMut",
+            ClosureKind::FnOnce => "FnOnce",
+        }
+    }
+
+    /// Returns `true` if a type that impls this closure kind
+    /// must also implement `other`.
+    pub fn extends(self, other: ClosureKind) -> bool {
+        self <= other
+    }
+}
+
+impl fmt::Display for ClosureKind {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.as_str().fmt(f)
+    }
+}
diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs
index cfed84a35c6..82bb1bf2916 100644
--- a/compiler/rustc_type_ir/src/macros.rs
+++ b/compiler/rustc_type_ir/src/macros.rs
@@ -51,4 +51,6 @@ TrivialTypeTraversalImpls! {
     crate::DebruijnIndex,
     crate::AliasRelationDirection,
     crate::UniverseIndex,
+    crate::Mutability,
+    crate::Movability,
 }
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 72ca9199a53..70adfbee2ed 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -4,6 +4,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
 use std::fmt;
 
+use crate::fold::{FallibleTypeFolder, TypeFoldable};
+use crate::visit::{TypeVisitable, TypeVisitor};
 use crate::Interner;
 use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx};
 
@@ -158,7 +160,7 @@ pub enum TyKind<I: Interner> {
     Slice(I::Ty),
 
     /// A raw pointer. Written as `*mut T` or `*const T`
-    RawPtr(I::TypeAndMut),
+    RawPtr(TypeAndMut<I>),
 
     /// A reference; a pointer with an associated lifetime. Written as
     /// `&'a mut T` or `&'a T`.
@@ -410,8 +412,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
             Str => write!(f, "str"),
             Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)),
             Slice(t) => write!(f, "[{:?}]", &this.wrap(t)),
-            RawPtr(p) => {
-                let (ty, mutbl) = I::ty_and_mut_to_parts(*p);
+            RawPtr(TypeAndMut { ty, mutbl }) => {
                 match mutbl {
                     Mutability::Mut => write!(f, "*mut "),
                     Mutability::Not => write!(f, "*const "),
@@ -831,3 +832,42 @@ impl<I: Interner> DebugWithInfcx<I> for InferTy {
         }
     }
 }
+
+#[derive(derivative::Derivative)]
+#[derivative(
+    Clone(bound = ""),
+    Copy(bound = ""),
+    PartialOrd(bound = ""),
+    Ord(bound = ""),
+    PartialEq(bound = ""),
+    Eq(bound = ""),
+    Hash(bound = ""),
+    Debug(bound = "")
+)]
+#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
+pub struct TypeAndMut<I: Interner> {
+    pub ty: I::Ty,
+    pub mutbl: Mutability,
+}
+
+impl<I: Interner> TypeFoldable<I> for TypeAndMut<I>
+where
+    I::Ty: TypeFoldable<I>,
+{
+    fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
+        Ok(TypeAndMut {
+            ty: self.ty.try_fold_with(folder)?,
+            mutbl: self.mutbl.try_fold_with(folder)?,
+        })
+    }
+}
+
+impl<I: Interner> TypeVisitable<I> for TypeAndMut<I>
+where
+    I::Ty: TypeVisitable<I>,
+{
+    fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> std::ops::ControlFlow<V::BreakTy> {
+        self.ty.visit_with(visitor)?;
+        self.mutbl.visit_with(visitor)
+    }
+}
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 3dfe7096399..5023af9ab79 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -22,6 +22,11 @@ pub struct Body {
 
     /// Debug information pertaining to user variables, including captures.
     pub var_debug_info: Vec<VarDebugInfo>,
+
+    /// Mark an argument (which must be a tuple) as getting passed as its individual components.
+    ///
+    /// This is used for the "rust-call" ABI such as closures.
+    pub(super) spread_arg: Option<Local>,
 }
 
 pub type BasicBlockIdx = usize;
@@ -36,6 +41,7 @@ impl Body {
         locals: LocalDecls,
         arg_count: usize,
         var_debug_info: Vec<VarDebugInfo>,
+        spread_arg: Option<Local>,
     ) -> Self {
         // If locals doesn't contain enough entries, it can lead to panics in
         // `ret_local`, `arg_locals`, and `inner_locals`.
@@ -43,7 +49,7 @@ impl Body {
             locals.len() > arg_count,
             "A Body must contain at least a local for the return value and each of the function's arguments"
         );
-        Self { blocks, locals, arg_count, var_debug_info }
+        Self { blocks, locals, arg_count, var_debug_info, spread_arg }
     }
 
     /// Return local that holds this function's return value.
@@ -75,6 +81,11 @@ impl Body {
         self.locals.get(local)
     }
 
+    /// Get an iterator for all local declarations.
+    pub fn local_decls(&self) -> impl Iterator<Item = (Local, &LocalDecl)> {
+        self.locals.iter().enumerate()
+    }
+
     pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
         writeln!(w, "{}", function_body(self))?;
         self.blocks
@@ -98,6 +109,10 @@ impl Body {
             .collect::<Result<Vec<_>, _>>()?;
         Ok(())
     }
+
+    pub fn spread_arg(&self) -> Option<Local> {
+        self.spread_arg
+    }
 }
 
 type LocalDecls = Vec<LocalDecl>;
@@ -248,6 +263,57 @@ pub enum AssertMessage {
     MisalignedPointerDereference { required: Operand, found: Operand },
 }
 
+impl AssertMessage {
+    pub fn description(&self) -> Result<&'static str, Error> {
+        match self {
+            AssertMessage::Overflow(BinOp::Add, _, _) => Ok("attempt to add with overflow"),
+            AssertMessage::Overflow(BinOp::Sub, _, _) => Ok("attempt to subtract with overflow"),
+            AssertMessage::Overflow(BinOp::Mul, _, _) => Ok("attempt to multiply with overflow"),
+            AssertMessage::Overflow(BinOp::Div, _, _) => Ok("attempt to divide with overflow"),
+            AssertMessage::Overflow(BinOp::Rem, _, _) => {
+                Ok("attempt to calculate the remainder with overflow")
+            }
+            AssertMessage::OverflowNeg(_) => Ok("attempt to negate with overflow"),
+            AssertMessage::Overflow(BinOp::Shr, _, _) => Ok("attempt to shift right with overflow"),
+            AssertMessage::Overflow(BinOp::Shl, _, _) => Ok("attempt to shift left with overflow"),
+            AssertMessage::Overflow(op, _, _) => Err(error!("`{:?}` cannot overflow", op)),
+            AssertMessage::DivisionByZero(_) => Ok("attempt to divide by zero"),
+            AssertMessage::RemainderByZero(_) => {
+                Ok("attempt to calculate the remainder with a divisor of zero")
+            }
+            AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine) => {
+                Ok("coroutine resumed after completion")
+            }
+            AssertMessage::ResumedAfterReturn(CoroutineKind::Async(_)) => {
+                Ok("`async fn` resumed after completion")
+            }
+            AssertMessage::ResumedAfterReturn(CoroutineKind::Gen(_)) => {
+                Ok("`async gen fn` resumed after completion")
+            }
+            AssertMessage::ResumedAfterReturn(CoroutineKind::AsyncGen(_)) => {
+                Ok("`gen fn` should just keep returning `AssertMessage::None` after completion")
+            }
+            AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine) => {
+                Ok("coroutine resumed after panicking")
+            }
+            AssertMessage::ResumedAfterPanic(CoroutineKind::Async(_)) => {
+                Ok("`async fn` resumed after panicking")
+            }
+            AssertMessage::ResumedAfterPanic(CoroutineKind::Gen(_)) => {
+                Ok("`async gen fn` resumed after panicking")
+            }
+            AssertMessage::ResumedAfterPanic(CoroutineKind::AsyncGen(_)) => {
+                Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking")
+            }
+
+            AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"),
+            AssertMessage::MisalignedPointerDereference { .. } => {
+                Ok("misaligned pointer dereference")
+            }
+        }
+    }
+}
+
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum BinOp {
     Add,
@@ -325,6 +391,7 @@ pub enum CoroutineKind {
     Async(CoroutineSource),
     Coroutine,
     Gen(CoroutineSource),
+    AsyncGen(CoroutineSource),
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs
index bc5d4a3b8f4..c126de23c4b 100644
--- a/compiler/stable_mir/src/mir/mono.rs
+++ b/compiler/stable_mir/src/mir/mono.rs
@@ -1,6 +1,6 @@
 use crate::crate_def::CrateDef;
 use crate::mir::Body;
-use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, FnSig, GenericArgs, IndexedVal, Ty};
+use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
 use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol};
 use std::fmt::{Debug, Formatter};
 
@@ -115,11 +115,6 @@ impl Instance {
         })
     }
 
-    /// Get this function signature with all types already instantiated.
-    pub fn fn_sig(&self) -> FnSig {
-        self.ty().kind().fn_sig().unwrap().skip_binder()
-    }
-
     /// Check whether this instance is an empty shim.
     ///
     /// Allow users to check if this shim can be ignored when called directly.
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index 3a0eed521dc..8b7b488d312 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -58,18 +58,35 @@ pub fn pretty_statement(statement: &StatementKind) -> String {
             pretty.push_str(format!("        _{} = ", place.local).as_str());
             pretty.push_str(format!("{}", &pretty_rvalue(rval)).as_str());
         }
-        StatementKind::FakeRead(_, _) => todo!(),
-        StatementKind::SetDiscriminant { .. } => todo!(),
-        StatementKind::Deinit(_) => todo!(),
-        StatementKind::StorageLive(_) => todo!(),
-        StatementKind::StorageDead(_) => todo!(),
-        StatementKind::Retag(_, _) => todo!(),
-        StatementKind::PlaceMention(_) => todo!(),
-        StatementKind::AscribeUserType { .. } => todo!(),
-        StatementKind::Coverage(_) => todo!(),
-        StatementKind::Intrinsic(_) => todo!(),
-        StatementKind::ConstEvalCounter => (),
-        StatementKind::Nop => (),
+        // FIXME: Add rest of the statements
+        StatementKind::FakeRead(_, _) => {
+            return String::from("StatementKind::FakeRead:Unimplemented");
+        }
+        StatementKind::SetDiscriminant { .. } => {
+            return String::from("StatementKind::SetDiscriminant:Unimplemented");
+        }
+        StatementKind::Deinit(_) => return String::from("StatementKind::Deinit:Unimplemented"),
+        StatementKind::StorageLive(_) => {
+            return String::from("StatementKind::StorageLive:Unimplemented");
+        }
+        StatementKind::StorageDead(_) => {
+            return String::from("StatementKind::StorageDead:Unimplemented");
+        }
+        StatementKind::Retag(_, _) => return String::from("StatementKind::Retag:Unimplemented"),
+        StatementKind::PlaceMention(_) => {
+            return String::from("StatementKind::PlaceMention:Unimplemented");
+        }
+        StatementKind::AscribeUserType { .. } => {
+            return String::from("StatementKind::AscribeUserType:Unimplemented");
+        }
+        StatementKind::Coverage(_) => return String::from("StatementKind::Coverage:Unimplemented"),
+        StatementKind::Intrinsic(_) => {
+            return String::from("StatementKind::Intrinsic:Unimplemented");
+        }
+        StatementKind::ConstEvalCounter => {
+            return String::from("StatementKind::ConstEvalCounter:Unimplemented");
+        }
+        StatementKind::Nop => return String::from("StatementKind::Nop:Unimplemented"),
     }
     pretty
 }
@@ -243,6 +260,7 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
             );
             pretty
         }
+        AssertMessage::Overflow(op, _, _) => unreachable!("`{:?}` cannot overflow", op),
         AssertMessage::OverflowNeg(op) => {
             let pretty_op = pretty_operand(op);
             pretty.push_str(
@@ -262,17 +280,15 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
             );
             pretty
         }
-        AssertMessage::ResumedAfterReturn(_) => {
-            format!("attempt to resume a generator after completion")
-        }
-        AssertMessage::ResumedAfterPanic(_) => format!("attempt to resume a panicked generator"),
         AssertMessage::MisalignedPointerDereference { required, found } => {
             let pretty_required = pretty_operand(required);
             let pretty_found = pretty_operand(found);
             pretty.push_str(format!("\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}").as_str());
             pretty
         }
-        _ => todo!(),
+        AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
+            msg.description().unwrap().to_string()
+        }
     }
 }
 
@@ -355,7 +371,7 @@ pub fn pretty_rvalue(rval: &Rvalue) -> String {
             pretty.push_str(" ");
             pretty.push_str(&pretty_ty(cnst.ty().kind()));
         }
-        Rvalue::ShallowInitBox(_, _) => todo!(),
+        Rvalue::ShallowInitBox(_, _) => (),
         Rvalue::ThreadLocalRef(item) => {
             pretty.push_str("thread_local_ref");
             pretty.push_str(format!("{:#?}", item).as_str());
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
index d46caad9a01..98336a72900 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/stable_mir/src/mir/visit.rs
@@ -133,7 +133,7 @@ pub trait MirVisitor {
     }
 
     fn super_body(&mut self, body: &Body) {
-        let Body { blocks, locals: _, arg_count, var_debug_info } = body;
+        let Body { blocks, locals: _, arg_count, var_debug_info, spread_arg: _ } = body;
 
         for bb in blocks {
             self.visit_basic_block(bb);
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index f473fd8dbb7..3d5e264104b 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -22,9 +22,7 @@ impl Debug for Ty {
 /// Constructors for `Ty`.
 impl Ty {
     /// Create a new type from a given kind.
-    ///
-    /// Note that not all types may be supported at this point.
-    fn from_rigid_kind(kind: RigidTy) -> Ty {
+    pub fn from_rigid_kind(kind: RigidTy) -> Ty {
         with(|cx| cx.new_rigid_ty(kind))
     }
 
@@ -77,6 +75,16 @@ impl Ty {
     pub fn bool_ty() -> Ty {
         Ty::from_rigid_kind(RigidTy::Bool)
     }
+
+    /// Create a type representing a signed integer.
+    pub fn signed_ty(inner: IntTy) -> Ty {
+        Ty::from_rigid_kind(RigidTy::Int(inner))
+    }
+
+    /// Create a type representing an unsigned integer.
+    pub fn unsigned_ty(inner: UintTy) -> Ty {
+        Ty::from_rigid_kind(RigidTy::Uint(inner))
+    }
 }
 
 impl Ty {
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index 62856fc9a49..4a4a3abd47f 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -421,7 +421,7 @@ impl CString {
     /// Failure to call [`CString::from_raw`] will lead to a memory leak.
     ///
     /// The C side must **not** modify the length of the string (by writing a
-    /// `null` somewhere inside the string or removing the final one) before
+    /// nul byte somewhere inside the string or removing the final one) before
     /// it makes it back into Rust using [`CString::from_raw`]. See the safety section
     /// in [`CString::from_raw`].
     ///
@@ -797,7 +797,7 @@ impl From<Box<CStr>> for CString {
 #[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")]
 impl From<Vec<NonZeroU8>> for CString {
     /// Converts a <code>[Vec]<[NonZeroU8]></code> into a [`CString`] without
-    /// copying nor checking for inner null bytes.
+    /// copying nor checking for inner nul bytes.
     #[inline]
     fn from(v: Vec<NonZeroU8>) -> CString {
         unsafe {
@@ -809,7 +809,7 @@ impl From<Vec<NonZeroU8>> for CString {
                 let (ptr, len, cap): (*mut NonZeroU8, _, _) = Vec::into_raw_parts(v);
                 Vec::from_raw_parts(ptr.cast::<u8>(), len, cap)
             };
-            // SAFETY: `v` cannot contain null bytes, given the type-level
+            // SAFETY: `v` cannot contain nul bytes, given the type-level
             // invariant of `NonZeroU8`.
             Self::_from_vec_unchecked(v)
         }
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 22777fb078a..c82984d5c6b 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -695,44 +695,41 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
     intrinsics::type_name::<T>()
 }
 
-/// Returns the name of the type of the pointed-to value as a string slice.
+/// Returns the type name of the pointed-to value as a string slice.
+///
 /// This is the same as `type_name::<T>()`, but can be used where the type of a
 /// variable is not easily available.
 ///
 /// # Note
 ///
-/// This is intended for diagnostic use. The exact contents and format of the
-/// string are not specified, other than being a best-effort description of the
-/// type. For example, `type_name_of_val::<Option<String>>(None)` could return
-/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
-/// `"foobar"`. In addition, the output may change between versions of the
-/// compiler.
-///
-/// This function does not resolve trait objects,
-/// meaning that `type_name_of_val(&7u32 as &dyn Debug)`
-/// may return `"dyn Debug"`, but not `"u32"`.
+/// Like [`type_name`], this is intended for diagnostic use and the exact output is not
+/// guaranteed. It provides a best-effort description, but the output may change between
+/// versions of the compiler.
 ///
-/// The type name should not be considered a unique identifier of a type;
-/// multiple types may share the same type name.
+/// In short: use this for debugging, avoid using the output to affect program behavior. More
+/// information is available at [`type_name`].
 ///
-/// The current implementation uses the same infrastructure as compiler
-/// diagnostics and debuginfo, but this is not guaranteed.
+/// Additionally, this function does not resolve trait objects. This means that
+/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`
+/// at this time.
 ///
 /// # Examples
 ///
 /// Prints the default integer and float types.
 ///
 /// ```rust
-/// #![feature(type_name_of_val)]
 /// use std::any::type_name_of_val;
 ///
-/// let x = 1;
-/// println!("{}", type_name_of_val(&x));
-/// let y = 1.0;
-/// println!("{}", type_name_of_val(&y));
+/// let s = "foo";
+/// let x: i32 = 1;
+/// let y: f32 = 1.0;
+///
+/// assert!(type_name_of_val(&s).contains("str"));
+/// assert!(type_name_of_val(&x).contains("i32"));
+/// assert!(type_name_of_val(&y).contains("f32"));
 /// ```
 #[must_use]
-#[unstable(feature = "type_name_of_val", issue = "66359")]
+#[stable(feature = "type_name_of_val", since = "CURRENT_RUSTC_VERSION")]
 #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
 pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
     type_name::<T>()
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index e7ec1fb73cd..bb839a71e90 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -205,7 +205,7 @@ impl CStr {
     /// * The memory pointed to by `ptr` must contain a valid nul terminator at the
     ///   end of the string.
     ///
-    /// * `ptr` must be [valid] for reads of bytes up to and including the null terminator.
+    /// * `ptr` must be [valid] for reads of bytes up to and including the nul terminator.
     ///   This means in particular:
     ///
     ///     * The entire memory range of this `CStr` must be contained within a single allocated object!
@@ -415,7 +415,7 @@ impl CStr {
             let mut i = bytes.len().saturating_sub(1);
             assert!(!bytes.is_empty() && bytes[i] == 0, "input was not nul-terminated");
 
-            // Ending null byte exists, skip to the rest.
+            // Ending nul byte exists, skip to the rest.
             while i != 0 {
                 i -= 1;
                 let byte = bytes[i];
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index 778515f8616..ab2158394bf 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -15,7 +15,7 @@ trait DisplayInt:
     fn zero() -> Self;
     fn from_u8(u: u8) -> Self;
     fn to_u8(&self) -> u8;
-    fn to_u16(&self) -> u16;
+    #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))]
     fn to_u32(&self) -> u32;
     fn to_u64(&self) -> u64;
     fn to_u128(&self) -> u128;
@@ -27,7 +27,7 @@ macro_rules! impl_int {
           fn zero() -> Self { 0 }
           fn from_u8(u: u8) -> Self { u as Self }
           fn to_u8(&self) -> u8 { *self as u8 }
-          fn to_u16(&self) -> u16 { *self as u16 }
+          #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))]
           fn to_u32(&self) -> u32 { *self as u32 }
           fn to_u64(&self) -> u64 { *self as u64 }
           fn to_u128(&self) -> u128 { *self as u128 }
@@ -40,7 +40,7 @@ macro_rules! impl_uint {
           fn zero() -> Self { 0 }
           fn from_u8(u: u8) -> Self { u as Self }
           fn to_u8(&self) -> u8 { *self as u8 }
-          fn to_u16(&self) -> u16 { *self as u16 }
+          #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))]
           fn to_u32(&self) -> u32 { *self as u32 }
           fn to_u64(&self) -> u64 { *self as u64 }
           fn to_u128(&self) -> u128 { *self as u128 }
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index dafc58d3a7d..8bf15c736c3 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1437,7 +1437,7 @@ impl Ipv6Addr {
     /// - The [unspecified address] ([`is_unspecified`](Ipv6Addr::is_unspecified))
     /// - The [loopback address] ([`is_loopback`](Ipv6Addr::is_loopback))
     /// - IPv4-mapped addresses
-    /// - Addresses reserved for benchmarking
+    /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv6Addr::is_benchmarking))
     /// - Addresses reserved for documentation ([`is_documentation`](Ipv6Addr::is_documentation))
     /// - Unique local addresses ([`is_unique_local`](Ipv6Addr::is_unique_local))
     /// - Unicast addresses with link-local scope ([`is_unicast_link_local`](Ipv6Addr::is_unicast_link_local))
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index d6603681a0b..eed793186b9 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -720,7 +720,8 @@ where
 /// type or mutability, in particular if the code is refactored.
 #[inline(always)]
 #[must_use]
-#[unstable(feature = "ptr_from_ref", issue = "106116")]
+#[stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
 #[rustc_never_returns_null_ptr]
 #[rustc_diagnostic_item = "ptr_from_ref"]
 pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
@@ -733,7 +734,9 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
 /// type or mutability, in particular if the code is refactored.
 #[inline(always)]
 #[must_use]
-#[unstable(feature = "ptr_from_ref", issue = "106116")]
+#[stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_allow_const_fn_unstable(const_mut_refs)]
 #[rustc_never_returns_null_ptr]
 pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
     r
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 4cfccd2e3ce..ce04a9f4089 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -125,6 +125,7 @@ impl [u8] {
     /// assert_eq!(b"".trim_ascii_start(), b"");
     /// ```
     #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[inline]
     pub const fn trim_ascii_start(&self) -> &[u8] {
         let mut bytes = self;
         // Note: A pattern matching based approach (instead of indexing) allows
@@ -154,6 +155,7 @@ impl [u8] {
     /// assert_eq!(b"".trim_ascii_end(), b"");
     /// ```
     #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[inline]
     pub const fn trim_ascii_end(&self) -> &[u8] {
         let mut bytes = self;
         // Note: A pattern matching based approach (instead of indexing) allows
@@ -184,6 +186,7 @@ impl [u8] {
     /// assert_eq!(b"".trim_ascii(), b"");
     /// ```
     #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[inline]
     pub const fn trim_ascii(&self) -> &[u8] {
         self.trim_ascii_start().trim_ascii_end()
     }
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 27178328be5..a22c46edce2 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -2423,6 +2423,85 @@ impl str {
         me.make_ascii_lowercase()
     }
 
+    /// Returns a string slice with leading ASCII whitespace removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// [`u8::is_ascii_whitespace`].
+    ///
+    /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!(" \t \u{3000}hello world\n".trim_ascii_start(), "\u{3000}hello world\n");
+    /// assert_eq!("  ".trim_ascii_start(), "");
+    /// assert_eq!("".trim_ascii_start(), "");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
+    #[inline]
+    pub const fn trim_ascii_start(&self) -> &str {
+        // SAFETY: Removing ASCII characters from a `&str` does not invalidate
+        // UTF-8.
+        unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_start()) }
+    }
+
+    /// Returns a string slice with trailing ASCII whitespace removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// [`u8::is_ascii_whitespace`].
+    ///
+    /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!("\r hello world\u{3000}\n ".trim_ascii_end(), "\r hello world\u{3000}");
+    /// assert_eq!("  ".trim_ascii_end(), "");
+    /// assert_eq!("".trim_ascii_end(), "");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
+    #[inline]
+    pub const fn trim_ascii_end(&self) -> &str {
+        // SAFETY: Removing ASCII characters from a `&str` does not invalidate
+        // UTF-8.
+        unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_end()) }
+    }
+
+    /// Returns a string slice with leading and trailing ASCII whitespace
+    /// removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// [`u8::is_ascii_whitespace`].
+    ///
+    /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!("\r hello world\n ".trim_ascii(), "hello world");
+    /// assert_eq!("  ".trim_ascii(), "");
+    /// assert_eq!("".trim_ascii(), "");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
+    #[inline]
+    pub const fn trim_ascii(&self) -> &str {
+        // SAFETY: Removing ASCII characters from a `&str` does not invalidate
+        // UTF-8.
+        unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii()) }
+    }
+
     /// Return an iterator that escapes each char in `self` with [`char::escape_debug`].
     ///
     /// Note: only extended grapheme codepoints that begin the string will be
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 1a11291e86b..9c41b8b4f46 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -48,7 +48,7 @@ impl RawWaker {
     /// Get the `data` pointer used to create this `RawWaker`.
     #[inline]
     #[must_use]
-    #[unstable(feature = "waker_getters", issue = "87021")]
+    #[unstable(feature = "waker_getters", issue = "96992")]
     pub fn data(&self) -> *const () {
         self.data
     }
@@ -56,7 +56,7 @@ impl RawWaker {
     /// Get the `vtable` pointer used to create this `RawWaker`.
     #[inline]
     #[must_use]
-    #[unstable(feature = "waker_getters", issue = "87021")]
+    #[unstable(feature = "waker_getters", issue = "96992")]
     pub fn vtable(&self) -> &'static RawWakerVTable {
         self.vtable
     }
@@ -371,7 +371,7 @@ impl Waker {
     /// Get a reference to the underlying [`RawWaker`].
     #[inline]
     #[must_use]
-    #[unstable(feature = "waker_getters", issue = "87021")]
+    #[unstable(feature = "waker_getters", issue = "96992")]
     pub fn as_raw(&self) -> &RawWaker {
         &self.waker
     }
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 765f73636fb..3689312e6ae 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -8,6 +8,7 @@ use crate::marker::{StructuralEq, StructuralPartialEq};
 //
 // Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
 // will implement everything for (A, B, C), (A, B) and (A,).
+#[cfg(bootstrap)]
 macro_rules! tuple_impls {
     // Stopping criteria (1-ary tuple)
     ($T:ident) => {
@@ -142,6 +143,148 @@ macro_rules! tuple_impls {
     }
 }
 
+// Recursive macro for implementing n-ary tuple functions and operations
+//
+// Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
+// will implement everything for (A, B, C), (A, B) and (A,).
+#[cfg(not(bootstrap))]
+macro_rules! tuple_impls {
+    // Stopping criteria (1-ary tuple)
+    ($T:ident) => {
+        tuple_impls!(@impl $T);
+    };
+    // Running criteria (n-ary tuple, with n >= 2)
+    ($T:ident $( $U:ident )+) => {
+        tuple_impls!($( $U )+);
+        tuple_impls!(@impl $T $( $U )+);
+    };
+    // "Private" internal implementation
+    (@impl $( $T:ident )+) => {
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: PartialEq),+> PartialEq for ($($T,)+)
+            where
+                last_type!($($T,)+): ?Sized
+            {
+                #[inline]
+                fn eq(&self, other: &($($T,)+)) -> bool {
+                    $( ${ignore($T)} self.${index()} == other.${index()} )&&+
+                }
+                #[inline]
+                fn ne(&self, other: &($($T,)+)) -> bool {
+                    $( ${ignore($T)} self.${index()} != other.${index()} )||+
+                }
+            }
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: Eq),+> Eq for ($($T,)+)
+            where
+                last_type!($($T,)+): ?Sized
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[unstable(feature = "structural_match", issue = "31434")]
+            impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+)
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[unstable(feature = "structural_match", issue = "31434")]
+            impl<$($T),+> StructuralPartialEq for ($($T,)+)
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[unstable(feature = "structural_match", issue = "31434")]
+            impl<$($T),+> StructuralEq for ($($T,)+)
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
+            where
+                last_type!($($T,)+): ?Sized
+            {
+                #[inline]
+                fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
+                    lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn lt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(lt, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn le(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(le, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn ge(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(ge, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn gt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(gt, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+            }
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: Ord),+> Ord for ($($T,)+)
+            where
+                last_type!($($T,)+): ?Sized
+            {
+                #[inline]
+                fn cmp(&self, other: &($($T,)+)) -> Ordering {
+                    lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+            }
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: Default),+> Default for ($($T,)+) {
+                #[inline]
+                fn default() -> ($($T,)+) {
+                    ($({ let x: $T = Default::default(); x},)+)
+                }
+            }
+        }
+
+        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
+        impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
+            #[inline]
+            #[allow(non_snake_case)]
+            fn from(array: [T; ${count($T)}]) -> Self {
+                let [$($T,)+] = array;
+                ($($T,)+)
+            }
+        }
+
+        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
+        impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
+            #[inline]
+            #[allow(non_snake_case)]
+            fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
+                let ($($T,)+) = tuple;
+                [$($T,)+]
+            }
+        }
+    }
+}
+
 // If this is a unary tuple, it adds a doc comment.
 // Otherwise, it hides the docs entirely.
 macro_rules! maybe_tuple_doc {
diff --git a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
index bd8a38e350d..dac013cc98d 100644
--- a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
+++ b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs
@@ -55,7 +55,7 @@ where
                 16 => transize(vqtbl1q_u8, self, idxs),
                 #[cfg(all(target_feature = "avx2", not(target_feature = "avx512vbmi")))]
                 32 => transize_raw(avx2_pshufb, self, idxs),
-                #[cfg(target_feature = "avx512vl,avx512vbmi")]
+                #[cfg(all(target_feature = "avx512vl", target_feature = "avx512vbmi"))]
                 32 => transize(x86::_mm256_permutexvar_epi8, self, idxs),
                 // Notable absence: avx512bw shuffle
                 // If avx512bw is available, odds of avx512vbmi are good
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index f666b18887c..fe66788b564 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -30,8 +30,13 @@ rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] }
 [target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies]
 miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
 addr2line = { version = "0.21.0", optional = true, default-features = false }
+
+[target.'cfg(all(not(target_os = "aix"), not(all(windows, target_env = "msvc", not(target_vendor = "uwp")))))'.dependencies]
 object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] }
 
+[target.'cfg(target_os = "aix")'.dependencies]
+object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'xcoff', 'unaligned', 'archive'] }
+
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
 rand_xorshift = "0.3.0"
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index f67f6034d34..30ac0512348 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -313,17 +313,32 @@ impl Error for VarError {
 /// Sets the environment variable `key` to the value `value` for the currently running
 /// process.
 ///
-/// Note that while concurrent access to environment variables is safe in Rust,
-/// some platforms only expose inherently unsafe non-threadsafe APIs for
-/// inspecting the environment. As a result, extra care needs to be taken when
-/// auditing calls to unsafe external FFI functions to ensure that any external
-/// environment accesses are properly synchronized with accesses in Rust.
+/// # Safety
+///
+/// Even though this function is currently not marked as `unsafe`, it needs to
+/// be because invoking it can cause undefined behaviour. The function will be
+/// marked `unsafe` in a future version of Rust. This is tracked in
+/// [rust#27970](https://github.com/rust-lang/rust/issues/27970).
+///
+/// This function is safe to call in a single-threaded program.
+///
+/// In multi-threaded programs, you must ensure that are no other threads
+/// concurrently writing or *reading*(!) from the environment through functions
+/// other than the ones in this module. You are responsible for figuring out
+/// how to achieve this, but we strongly suggest not using `set_var` or
+/// `remove_var` in multi-threaded programs at all.
+///
+/// Most C libraries, including libc itself do not advertise which functions
+/// read from the environment. Even functions from the Rust standard library do
+/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`].
 ///
 /// Discussion of this unsafety on Unix may be found in:
 ///
 ///  - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
 ///  - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
 ///
+/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs
+///
 /// # Panics
 ///
 /// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
@@ -351,17 +366,32 @@ fn _set_var(key: &OsStr, value: &OsStr) {
 
 /// Removes an environment variable from the environment of the currently running process.
 ///
-/// Note that while concurrent access to environment variables is safe in Rust,
-/// some platforms only expose inherently unsafe non-threadsafe APIs for
-/// inspecting the environment. As a result extra care needs to be taken when
-/// auditing calls to unsafe external FFI functions to ensure that any external
-/// environment accesses are properly synchronized with accesses in Rust.
+/// # Safety
+///
+/// Even though this function is currently not marked as `unsafe`, it needs to
+/// be because invoking it can cause undefined behaviour. The function will be
+/// marked `unsafe` in a future version of Rust. This is tracked in
+/// [rust#27970](https://github.com/rust-lang/rust/issues/27970).
+///
+/// This function is safe to call in a single-threaded program.
+///
+/// In multi-threaded programs, you must ensure that are no other threads
+/// concurrently writing or *reading*(!) from the environment through functions
+/// other than the ones in this module. You are responsible for figuring out
+/// how to achieve this, but we strongly suggest not using `set_var` or
+/// `remove_var` in multi-threaded programs at all.
+///
+/// Most C libraries, including libc itself do not advertise which functions
+/// read from the environment. Even functions from the Rust standard library do
+/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`].
 ///
 /// Discussion of this unsafety on Unix may be found in:
 ///
 ///  - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
 ///  - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
 ///
+/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs
+///
 /// # Panics
 ///
 /// This function may panic if `key` is empty, contains an ASCII equals sign
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 3b6fbf95faf..12afdef2669 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -22,7 +22,7 @@ use crate::os::unix::fs::symlink as symlink_file;
 #[cfg(unix)]
 use crate::os::unix::fs::symlink as symlink_junction;
 #[cfg(windows)]
-use crate::os::windows::fs::{symlink_dir, symlink_file};
+use crate::os::windows::fs::{symlink_dir, symlink_file, OpenOptionsExt};
 #[cfg(windows)]
 use crate::sys::fs::symlink_junction;
 #[cfg(target_os = "macos")]
@@ -1793,3 +1793,28 @@ fn windows_unix_socket_exists() {
     assert_eq!(socket_path.try_exists().unwrap(), true);
     assert_eq!(socket_path.metadata().is_ok(), true);
 }
+
+#[cfg(windows)]
+#[test]
+fn test_hidden_file_truncation() {
+    // Make sure that File::create works on an existing hidden file. See #115745.
+    let tmpdir = tmpdir();
+    let path = tmpdir.join("hidden_file.txt");
+
+    // Create a hidden file.
+    const FILE_ATTRIBUTE_HIDDEN: u32 = 2;
+    let mut file = OpenOptions::new()
+        .write(true)
+        .create_new(true)
+        .attributes(FILE_ATTRIBUTE_HIDDEN)
+        .open(&path)
+        .unwrap();
+    file.write("hidden world!".as_bytes()).unwrap();
+    file.flush().unwrap();
+    drop(file);
+
+    // Create a new file by truncating the existing one.
+    let file = File::create(&path).unwrap();
+    let metadata = file.metadata().unwrap();
+    assert_eq!(metadata.len(), 0);
+}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 52b1fe822d6..76081833e05 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -308,6 +308,7 @@
 //
 // Library features (core):
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(c_str_literals))]
 #![feature(char_internals)]
 #![feature(core_intrinsics)]
 #![feature(core_io_borrowed_buf)]
@@ -337,7 +338,6 @@
 #![feature(portable_simd)]
 #![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
-#![feature(ptr_from_ref)]
 #![feature(raw_os_nonzero)]
 #![feature(round_ties_even)]
 #![feature(slice_internals)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 55f4917a937..66b4ec37c8e 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -588,7 +588,7 @@ pub fn panicking() -> bool {
 }
 
 /// Entry point of panics from the core crate (`panic_impl` lang item).
-#[cfg(not(test))]
+#[cfg(not(any(test, doctest)))]
 #[panic_handler]
 pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
     struct FormatStringPayload<'a> {
@@ -669,7 +669,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
 /// panic!() and assert!(). In particular, this is the only entry point that supports
 /// arbitrary payloads, not just format strings.
 #[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")]
-#[cfg_attr(not(test), lang = "begin_panic")]
+#[cfg_attr(not(any(test, doctest)), lang = "begin_panic")]
 // lang item for CTFE panic support
 // never inline unless panic_immediate_abort to avoid code
 // bloat at the call sites as much as possible
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 6004ed51bd1..4a7f5d8e0be 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -2311,7 +2311,7 @@ pub fn id() -> u32 {
 /// of the `main` function, this trait is likely to be available only on
 /// standard library's runtime for convenience. Other runtimes are not required
 /// to provide similar functionality.
-#[cfg_attr(not(test), lang = "termination")]
+#[cfg_attr(not(any(test, doctest)), lang = "termination")]
 #[stable(feature = "termination_trait_lib", since = "1.61.0")]
 #[rustc_on_unimplemented(on(
     cause = "MainFunctionType",
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 5c83f72f3c1..335944845ae 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -154,8 +154,7 @@ fn lang_start_internal(
     ret_code
 }
 
-#[cfg(not(test))]
-#[inline(never)]
+#[cfg(not(any(test, doctest)))]
 #[lang = "start"]
 fn lang_start<T: crate::process::Termination + 'static>(
     main: fn() -> T,
diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs
index 0fff53f1887..d37b8ce6346 100644
--- a/library/std/src/sys/personality/mod.rs
+++ b/library/std/src/sys/personality/mod.rs
@@ -12,7 +12,7 @@
 
 mod dwarf;
 
-#[cfg(not(test))]
+#[cfg(not(any(test, doctest)))]
 cfg_if::cfg_if! {
     if #[cfg(target_os = "emscripten")] {
         mod emcc;
diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs
index 2da17fabcd6..9f7dcc0416e 100644
--- a/library/std/src/sys/unix/args.rs
+++ b/library/std/src/sys/unix/args.rs
@@ -244,13 +244,15 @@ mod imp {
         let mut res = Vec::new();
 
         unsafe {
-            let process_info_sel = sel_registerName("processInfo\0".as_ptr());
-            let arguments_sel = sel_registerName("arguments\0".as_ptr());
-            let utf8_sel = sel_registerName("UTF8String\0".as_ptr());
-            let count_sel = sel_registerName("count\0".as_ptr());
-            let object_at_sel = sel_registerName("objectAtIndex:\0".as_ptr());
-
-            let klass = objc_getClass("NSProcessInfo\0".as_ptr());
+            let process_info_sel =
+                sel_registerName(c"processInfo".as_ptr() as *const libc::c_uchar);
+            let arguments_sel = sel_registerName(c"arguments".as_ptr() as *const libc::c_uchar);
+            let utf8_sel = sel_registerName(c"UTF8String".as_ptr() as *const libc::c_uchar);
+            let count_sel = sel_registerName(c"count".as_ptr() as *const libc::c_uchar);
+            let object_at_sel =
+                sel_registerName(c"objectAtIndex:".as_ptr() as *const libc::c_uchar);
+
+            let klass = objc_getClass(c"NSProcessInfo".as_ptr() as *const libc::c_uchar);
             let info = objc_msgSend(klass, process_info_sel);
             let args = objc_msgSend(info, arguments_sel);
 
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index e3455cfef33..72e7b1b1fc3 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -1140,7 +1140,7 @@ impl File {
         cfg_has_statx! {
             if let Some(ret) = unsafe { try_statx(
                 fd,
-                b"\0" as *const _ as *const c_char,
+                c"".as_ptr() as *const c_char,
                 libc::AT_EMPTY_PATH | libc::AT_STATX_SYNC_AS_STAT,
                 libc::STATX_ALL,
             ) } {
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 4b28f6feba5..b5da5f870ec 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -1,6 +1,5 @@
 #![allow(missing_docs, nonstandard_style)]
 
-use crate::ffi::CStr;
 use crate::io::ErrorKind;
 
 pub use self::rand::hashmap_random_keys;
@@ -75,7 +74,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
     // thread-id for the main thread and so renaming the main thread will rename the
     // process and we only want to enable this on platforms we've tested.
     if cfg!(target_os = "macos") {
-        thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0"));
+        thread::Thread::set_name(&c"main");
     }
 
     unsafe fn sanitize_standard_fds() {
@@ -127,7 +126,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
                 if pfd.revents & libc::POLLNVAL == 0 {
                     continue;
                 }
-                if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
+                if open64(c"/dev/null".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
                     // If the stream is closed but we failed to reopen it, abort the
                     // process. Otherwise we wouldn't preserve the safety of
                     // operations on the corresponding Rust object Stdin, Stdout, or
@@ -157,7 +156,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             use libc::open64;
             for fd in 0..3 {
                 if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
-                    if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
+                    if open64(c"/dev/null".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
                         // If the stream is closed but we failed to reopen it, abort the
                         // process. Otherwise we wouldn't preserve the safety of
                         // operations on the corresponding Rust object Stdin, Stdout, or
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
index bac32d9e60e..c5f04fb8b3b 100644
--- a/library/std/src/sys/unix/process/process_common.rs
+++ b/library/std/src/sys/unix/process/process_common.rs
@@ -24,11 +24,11 @@ cfg_if::cfg_if! {
     if #[cfg(target_os = "fuchsia")] {
         // fuchsia doesn't have /dev/null
     } else if #[cfg(target_os = "redox")] {
-        const DEV_NULL: &str = "null:\0";
+        const DEV_NULL: &CStr = c"null:";
     } else if #[cfg(target_os = "vxworks")] {
-        const DEV_NULL: &str = "/null\0";
+        const DEV_NULL: &CStr = c"/null";
     } else {
-        const DEV_NULL: &str = "/dev/null\0";
+        const DEV_NULL: &CStr = c"/dev/null";
     }
 }
 
@@ -481,8 +481,7 @@ impl Stdio {
                 let mut opts = OpenOptions::new();
                 opts.read(readable);
                 opts.write(!readable);
-                let path = unsafe { CStr::from_ptr(DEV_NULL.as_ptr() as *const _) };
-                let fd = File::open_c(&path, &opts)?;
+                let fd = File::open_c(DEV_NULL, &opts)?;
                 Ok((ChildStdio::Owned(fd.into_inner()), None))
             }
 
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 29db9468e5f..76b96bb37df 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -163,10 +163,9 @@ impl Thread {
     #[cfg(target_os = "netbsd")]
     pub fn set_name(name: &CStr) {
         unsafe {
-            let cname = CStr::from_bytes_with_nul_unchecked(b"%s\0".as_slice());
             let res = libc::pthread_setname_np(
                 libc::pthread_self(),
-                cname.as_ptr(),
+                c"%s".as_ptr(),
                 name.as_ptr() as *mut libc::c_void,
             );
             debug_assert_eq!(res, 0);
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 7435b21be4c..d55d9bace81 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -324,7 +324,7 @@ pub unsafe fn NtWriteFile(
 // Functions that aren't available on every version of Windows that we support,
 // but we still use them and just provide some form of a fallback implementation.
 compat_fn_with_fallback! {
-    pub static KERNEL32: &CStr = ansi_str!("kernel32");
+    pub static KERNEL32: &CStr = c"kernel32";
 
     // >= Win10 1607
     // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
@@ -357,7 +357,7 @@ compat_fn_optional! {
 }
 
 compat_fn_with_fallback! {
-    pub static NTDLL: &CStr = ansi_str!("ntdll");
+    pub static NTDLL: &CStr = c"ntdll";
 
     pub fn NtCreateKeyedEvent(
         KeyedEventHandle: LPHANDLE,
diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs
index e28dd493536..f60b3a2c700 100644
--- a/library/std/src/sys/windows/compat.rs
+++ b/library/std/src/sys/windows/compat.rs
@@ -225,9 +225,9 @@ macro_rules! compat_fn_optional {
 /// Load all needed functions from "api-ms-win-core-synch-l1-2-0".
 pub(super) fn load_synch_functions() {
     fn try_load() -> Option<()> {
-        const MODULE_NAME: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
-        const WAIT_ON_ADDRESS: &CStr = ansi_str!("WaitOnAddress");
-        const WAKE_BY_ADDRESS_SINGLE: &CStr = ansi_str!("WakeByAddressSingle");
+        const MODULE_NAME: &CStr = c"api-ms-win-core-synch-l1-2-0";
+        const WAIT_ON_ADDRESS: &CStr = c"WaitOnAddress";
+        const WAKE_BY_ADDRESS_SINGLE: &CStr = c"WakeByAddressSingle";
 
         // Try loading the library and all the required functions.
         // If any step fails, then they all fail.
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index f57034cc8d5..09dfb0caeec 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -1,7 +1,7 @@
 use crate::os::windows::prelude::*;
 
 use crate::borrow::Cow;
-use crate::ffi::OsString;
+use crate::ffi::{c_void, OsString};
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem::{self, MaybeUninit};
@@ -16,8 +16,6 @@ use crate::sys::{c, cvt, Align8};
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::thread;
 
-use core::ffi::c_void;
-
 use super::path::maybe_verbatim;
 use super::{api, to_u16s, IoResult};
 
@@ -273,7 +271,9 @@ impl OpenOptions {
             (false, false, false) => c::OPEN_EXISTING,
             (true, false, false) => c::OPEN_ALWAYS,
             (false, true, false) => c::TRUNCATE_EXISTING,
-            (true, true, false) => c::CREATE_ALWAYS,
+            // `CREATE_ALWAYS` has weird semantics so we emulate it using
+            // `OPEN_ALWAYS` and a manual truncation step. See #115745.
+            (true, true, false) => c::OPEN_ALWAYS,
             (_, _, true) => c::CREATE_NEW,
         })
     }
@@ -289,19 +289,40 @@ impl OpenOptions {
 impl File {
     pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
         let path = maybe_verbatim(path)?;
+        let creation = opts.get_creation_mode()?;
         let handle = unsafe {
             c::CreateFileW(
                 path.as_ptr(),
                 opts.get_access_mode()?,
                 opts.share_mode,
                 opts.security_attributes,
-                opts.get_creation_mode()?,
+                creation,
                 opts.get_flags_and_attributes(),
                 ptr::null_mut(),
             )
         };
         let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) };
-        if let Ok(handle) = handle.try_into() {
+        if let Ok(handle) = OwnedHandle::try_from(handle) {
+            // Manual truncation. See #115745.
+            if opts.truncate
+                && creation == c::OPEN_ALWAYS
+                && unsafe { c::GetLastError() } == c::ERROR_ALREADY_EXISTS
+            {
+                unsafe {
+                    // Setting the allocation size to zero also sets the
+                    // EOF position to zero.
+                    let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 };
+                    let result = c::SetFileInformationByHandle(
+                        handle.as_raw_handle(),
+                        c::FileAllocationInfo,
+                        ptr::addr_of!(alloc).cast::<c_void>(),
+                        mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32,
+                    );
+                    if result == 0 {
+                        return Err(io::Error::last_os_error());
+                    }
+                }
+            }
             Ok(File { handle: Handle::from_inner(handle) })
         } else {
             Err(Error::last_os_error())
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index 9c83d6eb8bf..8b722f01a5d 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -1,6 +1,6 @@
 #![allow(missing_docs, nonstandard_style)]
 
-use crate::ffi::{CStr, OsStr, OsString};
+use crate::ffi::{OsStr, OsString};
 use crate::io::ErrorKind;
 use crate::mem::MaybeUninit;
 use crate::os::windows::ffi::{OsStrExt, OsStringExt};
@@ -63,7 +63,7 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {
 
     // Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
     // exists, we have to call it ourselves.
-    thread::Thread::set_name(CStr::from_bytes_with_nul_unchecked(b"main\0"));
+    thread::Thread::set_name(&c"main");
 }
 
 // SAFETY: must be called only once during runtime cleanup.
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index 32f6a3f80d0..b1ab8dae535 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -5,7 +5,6 @@
 //! parent directory, and otherwise documentation can be found throughout the `build`
 //! directory in each respective module.
 
-#[cfg(all(any(unix, windows), not(target_os = "solaris")))]
 use std::io::Write;
 #[cfg(all(any(unix, windows), not(target_os = "solaris")))]
 use std::process;
@@ -175,7 +174,7 @@ fn check_version(config: &Config) -> Option<String> {
                 "update `config.toml` to use `change-id = {latest_change_id}` instead"
             ));
 
-            if io::stdout().is_terminal() {
+            if io::stdout().is_terminal() && !config.dry_run() {
                 t!(fs::write(warned_id_path, latest_change_id.to_string()));
             }
         }
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index c485481b9a1..98e267713da 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -1319,7 +1319,7 @@ impl Step for CodegenBackend {
                 return None;
             }
 
-            if self.compiler.host.contains("windows") {
+            if self.compiler.host.is_windows() {
                 builder.info(
                     "dist currently disabled for windows by rustc_codegen_cranelift. skipping",
                 );
@@ -1658,7 +1658,7 @@ impl Step for Extended {
             builder.run(&mut cmd);
         }
 
-        if target.contains("windows") {
+        if target.is_windows() {
             let exe = tmp.join("exe");
             let _ = fs::remove_dir_all(&exe);
 
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 8de208cd09c..4b2d3e9ab4b 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -283,7 +283,7 @@ impl Step for Llvm {
         };
 
         builder.update_submodule(&Path::new("src").join("llvm-project"));
-        if builder.llvm_link_shared() && target.contains("windows") {
+        if builder.llvm_link_shared() && target.is_windows() {
             panic!("shared linking to LLVM is not currently supported on {}", target.triple);
         }
 
@@ -361,7 +361,7 @@ impl Step for Llvm {
         // Disable zstd to avoid a dependency on libzstd.so.
         cfg.define("LLVM_ENABLE_ZSTD", "OFF");
 
-        if !target.contains("windows") {
+        if !target.is_windows() {
             cfg.define("LLVM_ENABLE_ZLIB", "ON");
         } else {
             cfg.define("LLVM_ENABLE_ZLIB", "OFF");
@@ -607,7 +607,7 @@ fn configure_cmake(
             cfg.define("CMAKE_SYSTEM_NAME", "DragonFly");
         } else if target.contains("freebsd") {
             cfg.define("CMAKE_SYSTEM_NAME", "FreeBSD");
-        } else if target.contains("windows") {
+        } else if target.is_windows() {
             cfg.define("CMAKE_SYSTEM_NAME", "Windows");
         } else if target.contains("haiku") {
             cfg.define("CMAKE_SYSTEM_NAME", "Haiku");
@@ -772,7 +772,7 @@ fn configure_cmake(
         && !target.contains("netbsd")
         && !target.contains("solaris")
     {
-        if target.contains("apple") || target.contains("windows") {
+        if target.contains("apple") || target.is_windows() {
             ldflags.push_all("-static-libstdc++");
         } else {
             ldflags.push_all("-Wl,-Bsymbolic -static-libstdc++");
@@ -1295,7 +1295,7 @@ impl Step for Libunwind {
                 cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None);
                 cfg.define("NDEBUG", None);
             }
-            if self.target.contains("windows") {
+            if self.target.is_windows() {
                 cfg.define("_LIBUNWIND_HIDE_SYMBOLS", "1");
                 cfg.define("_LIBUNWIND_IS_NATIVE_ONLY", "1");
             }
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 054c3ab14c0..28761a7ee4b 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1653,10 +1653,7 @@ impl<'a> Builder<'a> {
                 // flesh out rpath support more fully in the future.
                 rustflags.arg("-Zosx-rpath-install-name");
                 Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
-            } else if !target.contains("windows")
-                && !target.contains("aix")
-                && !target.contains("xous")
-            {
+            } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
                 rustflags.arg("-Clink-args=-Wl,-z,origin");
                 Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
             } else {
@@ -1729,8 +1726,7 @@ impl<'a> Builder<'a> {
         let split_debuginfo_is_stable = target.contains("linux")
             || target.contains("apple")
             || (target.is_msvc() && self.config.rust_split_debuginfo == SplitDebuginfo::Packed)
-            || (target.contains("windows")
-                && self.config.rust_split_debuginfo == SplitDebuginfo::Off);
+            || (target.is_windows() && self.config.rust_split_debuginfo == SplitDebuginfo::Off);
 
         if !split_debuginfo_is_stable {
             rustflags.arg("-Zunstable-options");
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index c3db5641ea4..f1e1b89d9ba 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -421,10 +421,10 @@ impl std::str::FromStr for SplitDebuginfo {
 impl SplitDebuginfo {
     /// Returns the default `-Csplit-debuginfo` value for the current target. See the comment for
     /// `rust.split-debuginfo` in `config.example.toml`.
-    fn default_for_platform(target: &str) -> Self {
+    fn default_for_platform(target: TargetSelection) -> Self {
         if target.contains("apple") {
             SplitDebuginfo::Unpacked
-        } else if target.contains("windows") {
+        } else if target.is_windows() {
             SplitDebuginfo::Packed
         } else {
             SplitDebuginfo::Off
@@ -527,6 +527,10 @@ impl TargetSelection {
     pub fn is_msvc(&self) -> bool {
         self.contains("msvc")
     }
+
+    pub fn is_windows(&self) -> bool {
+        self.contains("windows")
+    }
 }
 
 impl fmt::Display for TargetSelection {
@@ -1595,7 +1599,7 @@ impl Config {
                 .as_deref()
                 .map(SplitDebuginfo::from_str)
                 .map(|v| v.expect("invalid value for rust.split_debuginfo"))
-                .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple));
+                .unwrap_or(SplitDebuginfo::default_for_platform(config.build));
             optimize = optimize_toml;
             omit_git_hash = omit_git_hash_toml;
             config.rust_new_symbol_mangling = new_symbol_mangling;
@@ -1791,8 +1795,7 @@ impl Config {
                 config.llvm_link_shared.set(Some(true));
             }
         } else {
-            config.llvm_from_ci = config.channel == "dev"
-                && crate::core::build_steps::llvm::is_ci_llvm_available(&config, false);
+            config.llvm_from_ci = config.parse_download_ci_llvm(None, false);
         }
 
         if let Some(t) = toml.target {
@@ -1965,7 +1968,7 @@ impl Config {
         config
     }
 
-    pub(crate) fn dry_run(&self) -> bool {
+    pub fn dry_run(&self) -> bool {
         match self.dry_run {
             DryRun::Disabled => false,
             DryRun::SelfCheck | DryRun::UserSelected => true,
@@ -2337,29 +2340,30 @@ impl Config {
         download_ci_llvm: Option<StringOrBool>,
         asserts: bool,
     ) -> bool {
+        let if_unchanged = || {
+            // Git is needed to track modifications here, but tarball source is not available.
+            // If not modified here or built through tarball source, we maintain consistency
+            // with '"if available"'.
+            if !self.rust_info.is_from_tarball()
+                && self
+                    .last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true)
+                    .is_none()
+            {
+                // there are some untracked changes in the the given paths.
+                false
+            } else {
+                llvm::is_ci_llvm_available(&self, asserts)
+            }
+        };
         match download_ci_llvm {
-            None => self.channel == "dev" && llvm::is_ci_llvm_available(&self, asserts),
+            None => self.channel == "dev" && if_unchanged(),
             Some(StringOrBool::Bool(b)) => b,
             // FIXME: "if-available" is deprecated. Remove this block later (around mid 2024)
             // to not break builds between the recent-to-old checkouts.
             Some(StringOrBool::String(s)) if s == "if-available" => {
                 llvm::is_ci_llvm_available(&self, asserts)
             }
-            Some(StringOrBool::String(s)) if s == "if-unchanged" => {
-                // Git is needed to track modifications here, but tarball source is not available.
-                // If not modified here or built through tarball source, we maintain consistency
-                // with '"if available"'.
-                if !self.rust_info.is_from_tarball()
-                    && self
-                        .last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true)
-                        .is_none()
-                {
-                    // there are some untracked changes in the the given paths.
-                    false
-                } else {
-                    llvm::is_ci_llvm_available(&self, asserts)
-                }
-            }
+            Some(StringOrBool::String(s)) if s == "if-unchanged" => if_unchanged(),
             Some(StringOrBool::String(other)) => {
                 panic!("unrecognized option for download-ci-llvm: {:?}", other)
             }
diff --git a/src/bootstrap/src/tests/config.rs b/src/bootstrap/src/tests/config.rs
index c24d57fb8f8..6f432343882 100644
--- a/src/bootstrap/src/tests/config.rs
+++ b/src/bootstrap/src/tests/config.rs
@@ -31,10 +31,10 @@ fn download_ci_llvm() {
     assert_eq!(parse_llvm(""), if_unchanged);
     assert_eq!(parse_llvm("rust.channel = \"dev\""), if_unchanged);
     assert!(!parse_llvm("rust.channel = \"stable\""));
-    assert!(parse_llvm("build.build = \"x86_64-unknown-linux-gnu\""));
-    assert!(parse_llvm(
+    assert_eq!(parse_llvm("build.build = \"x86_64-unknown-linux-gnu\""), if_unchanged);
+    assert_eq!(parse_llvm(
         "llvm.assertions = true \r\n build.build = \"x86_64-unknown-linux-gnu\" \r\n llvm.download-ci-llvm = \"if-unchanged\""
-    ));
+    ), if_unchanged);
     assert!(!parse_llvm(
         "llvm.assertions = true \r\n build.build = \"aarch64-apple-darwin\" \r\n llvm.download-ci-llvm = \"if-unchanged\""
     ));
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 133792d85e8..d96608db22c 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -49,7 +49,7 @@ pub use t;
 /// Given an executable called `name`, return the filename for the
 /// executable for a particular target.
 pub fn exe(name: &str, target: TargetSelection) -> String {
-    if target.contains("windows") {
+    if target.is_windows() {
         format!("{name}.exe")
     } else if target.contains("uefi") {
         format!("{name}.efi")
@@ -72,7 +72,7 @@ pub fn is_debug_info(name: &str) -> bool {
 /// Returns the corresponding relative library directory that the compiler's
 /// dylibs will be found in.
 pub fn libdir(target: TargetSelection) -> &'static str {
-    if target.contains("windows") { "bin" } else { "lib" }
+    if target.is_windows() { "bin" } else { "lib" }
 }
 
 /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
@@ -191,7 +191,7 @@ pub fn target_supports_cranelift_backend(target: TargetSelection) -> bool {
             || target.contains("aarch64")
             || target.contains("s390x")
             || target.contains("riscv64gc")
-    } else if target.contains("darwin") || target.contains("windows") {
+    } else if target.contains("darwin") || target.is_windows() {
         target.contains("x86_64")
     } else {
         false
@@ -519,7 +519,7 @@ pub fn linker_flags(
         if matches!(lld_threads, LldThreads::No) {
             args.push(format!(
                 "-Clink-arg=-Wl,{}",
-                lld_flag_no_threads(builder.config.lld_mode, target.is_msvc())
+                lld_flag_no_threads(builder.config.lld_mode, target.is_windows())
             ));
         }
     }
diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
index 046d018543f..669dc9358eb 100644
--- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
+++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
@@ -201,7 +201,7 @@ mod bar {
 # fn main() {}
 ```
 
-Here, because `bar` is not public, `Bar` wouldn't have its own page, so there's nowhere
+Here, because `bar` is not public, `bar` wouldn't have its own page, so there's nowhere
 to link to. `rustdoc` will inline these definitions, and so we end up in the same case
 as the `#[doc(inline)]` above; `Bar` is in a `Structs` section, as if it were defined at
 the top level. If we add the `no_inline` form of the attribute:
diff --git a/src/doc/unstable-book/src/compiler-flags/default-hidden-visibility.md b/src/doc/unstable-book/src/compiler-flags/default-hidden-visibility.md
new file mode 100644
index 00000000000..579add4a9d9
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/default-hidden-visibility.md
@@ -0,0 +1,12 @@
+# `default-hidden-visibility`
+
+The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/656
+
+------------------------
+
+This flag can be used to override the target's
+[`default_hidden_visibility`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_target/spec/struct.TargetOptions.html#structfield.default_hidden_visibility)
+setting.
+Using `-Zdefault_hidden_visibility=yes` is roughly equivalent to Clang's
+[`-fvisibility=hidden`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fvisibility)
+cmdline flag.
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index dad2aa4061d..4da85885d67 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -14,7 +14,6 @@ pub(crate) struct BlanketImplFinder<'a, 'tcx> {
 impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
     pub(crate) fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
         let cx = &mut self.cx;
-        let param_env = cx.tcx.param_env(item_def_id);
         let ty = cx.tcx.type_of(item_def_id);
 
         trace!("get_blanket_impls({ty:?})");
@@ -40,7 +39,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                 let infcx = cx.tcx.infer_ctxt().build();
                 let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id);
                 let impl_ty = ty.instantiate(infcx.tcx, args);
-                let param_env = EarlyBinder::bind(param_env).instantiate(infcx.tcx, args);
+                let param_env = ty::ParamEnv::empty();
 
                 let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
                 let impl_trait_ref = trait_ref.instantiate(infcx.tcx, impl_args);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 688751627f3..828e7f959b4 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -26,7 +26,7 @@ use rustc_middle::middle::resolve_bound_vars as rbv;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::TypeVisitableExt;
-use rustc_middle::ty::{self, AdtKind, EarlyBinder, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_span::hygiene::{AstPass, MacroKind};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -184,22 +184,6 @@ fn clean_generic_bound<'tcx>(
 ) -> Option<GenericBound> {
     Some(match *bound {
         hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
-        hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
-            let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
-
-            let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(cx.tcx, def_id));
-
-            let generic_args = clean_generic_args(generic_args, cx);
-            let GenericArgs::AngleBracketed { bindings, .. } = generic_args else {
-                bug!("clean: parenthesized `GenericBound::LangItemTrait`");
-            };
-
-            let trait_ = clean_trait_ref_with_bindings(cx, trait_ref, bindings);
-            GenericBound::TraitBound(
-                PolyTrait { trait_, generic_params: vec![] },
-                hir::TraitBoundModifier::None,
-            )
-        }
         hir::GenericBound::Trait(ref t, modifier) => {
             // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
             if modifier == hir::TraitBoundModifier::MaybeConst
@@ -743,7 +727,7 @@ pub(crate) fn clean_generics<'tcx>(
                     .into_iter()
                     .map(|(lifetime, bounds)| WherePredicate::RegionPredicate { lifetime, bounds }),
             )
-            .chain(eq_predicates.into_iter())
+            .chain(eq_predicates)
             .collect(),
     }
 }
@@ -1596,7 +1580,6 @@ fn first_non_private<'tcx>(
         // Absolute paths are not. We start from the parent of the item.
         [.., parent, leaf] => (parent.res.opt_def_id()?.as_local()?, leaf.ident),
     };
-    let hir = cx.tcx.hir();
     // First we try to get the `DefId` of the item.
     for child in
         cx.tcx.module_children_local(parent_def_id).iter().filter(move |c| c.ident == ident)
@@ -1612,7 +1595,8 @@ fn first_non_private<'tcx>(
             'reexps: for reexp in child.reexport_chain.iter() {
                 if let Some(use_def_id) = reexp.id()
                     && let Some(local_use_def_id) = use_def_id.as_local()
-                    && let Some(hir::Node::Item(item)) = hir.find_by_def_id(local_use_def_id)
+                    && let Some(hir::Node::Item(item)) =
+                        cx.tcx.opt_hir_node_by_def_id(local_use_def_id)
                     && !item.ident.name.is_empty()
                     && let hir::ItemKind::Use(path, _) = item.kind
                 {
@@ -2646,6 +2630,40 @@ fn filter_tokens_from_list(
     tokens
 }
 
+fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool {
+    if is_inline {
+        ident == sym::hidden || ident == sym::inline || ident == sym::no_inline
+    } else {
+        ident == sym::cfg
+    }
+}
+
+/// 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) => {
+            let tokens = filter_tokens_from_list(&args.tokens, |token| {
+                !matches!(
+                    token,
+                    TokenTree::Token(
+                        Token {
+                            kind: TokenKind::Ident(
+                                ident,
+                                _,
+                            ),
+                            ..
+                        },
+                        _,
+                    ) if filter_doc_attr_ident(*ident, is_inline),
+                )
+            });
+            args.tokens = TokenStream::new(tokens);
+        }
+        ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {}
+    }
+}
+
 /// When inlining items, we merge their attributes (and all the reexports attributes too) with the
 /// final reexport. For example:
 ///
@@ -2672,13 +2690,6 @@ fn add_without_unwanted_attributes<'hir>(
     is_inline: bool,
     import_parent: Option<DefId>,
 ) {
-    // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
-    if !is_inline {
-        for attr in new_attrs {
-            attrs.push((Cow::Borrowed(attr), import_parent));
-        }
-        return;
-    }
     for attr in new_attrs {
         if matches!(attr.kind, ast::AttrKind::DocComment(..)) {
             attrs.push((Cow::Borrowed(attr), import_parent));
@@ -2687,33 +2698,14 @@ fn add_without_unwanted_attributes<'hir>(
         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
-                    && ident == sym::doc
-                {
-                    match normal.item.args {
-                        ast::AttrArgs::Delimited(ref mut args) => {
-                            let tokens = filter_tokens_from_list(&args.tokens, |token| {
-                                !matches!(
-                                    token,
-                                    TokenTree::Token(
-                                        Token {
-                                            kind: TokenKind::Ident(
-                                                sym::hidden | sym::inline | sym::no_inline,
-                                                _,
-                                            ),
-                                            ..
-                                        },
-                                        _,
-                                    ),
-                                )
-                            });
-                            args.tokens = TokenStream::new(tokens);
-                            attrs.push((Cow::Owned(attr), import_parent));
-                        }
-                        ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {
-                            attrs.push((Cow::Owned(attr), import_parent));
-                        }
+                if let [ident] = &*normal.item.path.segments {
+                    let ident = ident.ident.name;
+                    if ident == sym::doc {
+                        filter_doc_attr(normal, is_inline);
+                        attrs.push((Cow::Owned(attr), import_parent));
+                    } else if ident != sym::cfg {
+                        // If it's not a `cfg()` attribute, we keep it.
+                        attrs.push((Cow::Owned(attr), import_parent));
                     }
                 }
             }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 0a14404d689..150625c6d92 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -2245,8 +2245,8 @@ impl GenericArgs {
     }
     pub(crate) fn bindings<'a>(&'a self) -> Box<dyn Iterator<Item = TypeBinding> + 'a> {
         match self {
-            &GenericArgs::AngleBracketed { ref bindings, .. } => Box::new(bindings.iter().cloned()),
-            &GenericArgs::Parenthesized { ref output, .. } => Box::new(
+            GenericArgs::AngleBracketed { bindings, .. } => Box::new(bindings.iter().cloned()),
+            GenericArgs::Parenthesized { output, .. } => Box::new(
                 output
                     .as_ref()
                     .map(|ty| TypeBinding {
@@ -2270,8 +2270,8 @@ impl<'a> IntoIterator for &'a GenericArgs {
     type Item = GenericArg;
     fn into_iter(self) -> Self::IntoIter {
         match self {
-            &GenericArgs::AngleBracketed { ref args, .. } => Box::new(args.iter().cloned()),
-            &GenericArgs::Parenthesized { ref inputs, .. } => {
+            GenericArgs::AngleBracketed { args, .. } => Box::new(args.iter().cloned()),
+            GenericArgs::Parenthesized { inputs, .. } => {
                 Box::new(inputs.iter().cloned().map(GenericArg::Type))
             }
         }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 82f4a38384d..bdfda07be09 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -439,7 +439,7 @@ fn print_const_with_custom_print_scalar<'tcx>(
 }
 
 pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
-    if let hir::Node::Expr(expr) = tcx.hir().get(hir_id) {
+    if let hir::Node::Expr(expr) = tcx.hir_node(hir_id) {
         if let hir::ExprKind::Lit(_) = &expr.kind {
             return true;
         }
@@ -641,7 +641,6 @@ pub(crate) fn inherits_doc_hidden(
     mut def_id: LocalDefId,
     stop_at: Option<LocalDefId>,
 ) -> bool {
-    let hir = tcx.hir();
     while let Some(id) = tcx.opt_local_parent(def_id) {
         if let Some(stop_at) = stop_at
             && id == stop_at
@@ -651,7 +650,7 @@ pub(crate) fn inherits_doc_hidden(
         def_id = id;
         if tcx.is_doc_hidden(def_id.to_def_id()) {
             return true;
-        } else if let Some(node) = hir.find_by_def_id(def_id)
+        } else if let Some(node) = tcx.opt_hir_node_by_def_id(def_id)
             && matches!(node, hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }),)
         {
             // `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 8215926ee33..0150496990d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -380,7 +380,9 @@ pub(crate) fn run_global_ctxt(
             crate::lint::MISSING_CRATE_LEVEL_DOCS,
             DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(),
             "no documentation found for this crate's top-level module",
-            |lint| lint.help(help),
+            |lint| {
+                lint.help(help);
+            },
         );
     }
 
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index abc27bcdf07..642265f5f6b 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -27,7 +27,7 @@
 //! ```
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_errors::{DiagnosticBuilder, DiagnosticMessage};
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::TyCtxt;
 pub(crate) use rustc_resolve::rustdoc::main_body_opts;
@@ -234,10 +234,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
 
     fn next(&mut self) -> Option<Self::Item> {
         let event = self.inner.next();
-        let compile_fail;
-        let should_panic;
-        let ignore;
-        let edition;
         let Some(Event::Start(Tag::CodeBlock(kind))) = event else {
             return event;
         };
@@ -253,49 +249,44 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
             }
         }
 
-        let parse_result = match kind {
-            CodeBlockKind::Fenced(ref lang) => {
-                let parse_result = LangString::parse_without_check(
-                    lang,
-                    self.check_error_codes,
-                    false,
-                    self.custom_code_classes_in_docs,
-                );
-                if !parse_result.rust {
-                    let added_classes = parse_result.added_classes;
-                    let lang_string = if let Some(lang) = parse_result.unknown.first() {
-                        format!("language-{}", lang)
-                    } else {
-                        String::new()
-                    };
-                    let whitespace = if added_classes.is_empty() { "" } else { " " };
-                    return Some(Event::Html(
-                        format!(
-                            "<div class=\"example-wrap\">\
+        let LangString { added_classes, compile_fail, should_panic, ignore, edition, .. } =
+            match kind {
+                CodeBlockKind::Fenced(ref lang) => {
+                    let parse_result = LangString::parse_without_check(
+                        lang,
+                        self.check_error_codes,
+                        false,
+                        self.custom_code_classes_in_docs,
+                    );
+                    if !parse_result.rust {
+                        let added_classes = parse_result.added_classes;
+                        let lang_string = if let Some(lang) = parse_result.unknown.first() {
+                            format!("language-{}", lang)
+                        } else {
+                            String::new()
+                        };
+                        let whitespace = if added_classes.is_empty() { "" } else { " " };
+                        return Some(Event::Html(
+                            format!(
+                                "<div class=\"example-wrap\">\
                                  <pre class=\"{lang_string}{whitespace}{added_classes}\">\
                                      <code>{text}</code>\
                                  </pre>\
                              </div>",
-                            added_classes = added_classes.join(" "),
-                            text = Escape(&original_text),
-                        )
-                        .into(),
-                    ));
+                                added_classes = added_classes.join(" "),
+                                text = Escape(&original_text),
+                            )
+                            .into(),
+                        ));
+                    }
+                    parse_result
                 }
-                parse_result
-            }
-            CodeBlockKind::Indented => Default::default(),
-        };
+                CodeBlockKind::Indented => Default::default(),
+            };
 
-        let added_classes = parse_result.added_classes;
         let lines = original_text.lines().filter_map(|l| map_line(l).for_html());
         let text = lines.intersperse("\n".into()).collect::<String>();
 
-        compile_fail = parse_result.compile_fail;
-        should_panic = parse_result.should_panic;
-        ignore = parse_result.ignore;
-        edition = parse_result.edition;
-
         let explicit_edition = edition.is_some();
         let edition = edition.unwrap_or(self.edition);
 
@@ -844,7 +835,7 @@ impl<'tcx> ExtraInfo<'tcx> {
                 self.tcx.local_def_id_to_hir_id(def_id),
                 self.sp,
                 msg,
-                |l| l,
+                |_| {},
             );
         }
     }
@@ -852,7 +843,7 @@ impl<'tcx> ExtraInfo<'tcx> {
     fn error_invalid_codeblock_attr_with_help(
         &self,
         msg: impl Into<DiagnosticMessage>,
-        help: impl Into<SubdiagnosticMessage>,
+        f: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         if let Some(def_id) = self.def_id.as_local() {
             self.tcx.struct_span_lint_hir(
@@ -860,7 +851,7 @@ impl<'tcx> ExtraInfo<'tcx> {
                 self.tcx.local_def_id_to_hir_id(def_id),
                 self.sp,
                 msg,
-                |lint| lint.help(help),
+                f,
             );
         }
     }
@@ -1294,6 +1285,21 @@ impl LangString {
                         data.edition = x[7..].parse::<Edition>().ok();
                     }
                     LangStringToken::LangToken(x)
+                        if x.starts_with("rust") && x[4..].parse::<Edition>().is_ok() =>
+                    {
+                        if let Some(extra) = extra {
+                            extra.error_invalid_codeblock_attr_with_help(
+                                format!("unknown attribute `{x}`"),
+                                |lint| {
+                                    lint.help(format!(
+                                        "there is an attribute with a similar name: `edition{}`",
+                                        &x[4..],
+                                    ));
+                                },
+                            );
+                        }
+                    }
+                    LangStringToken::LangToken(x)
                         if allow_error_code_check && x.starts_with('E') && x.len() == 5 =>
                     {
                         if x[1..].parse::<u32>().is_ok() {
@@ -1337,8 +1343,13 @@ impl LangString {
                         } {
                             if let Some(extra) = extra {
                                 extra.error_invalid_codeblock_attr_with_help(
-                                    format!("unknown attribute `{x}`. Did you mean `{flag}`?"),
-                                    help,
+                                    format!("unknown attribute `{x}`"),
+                                    |lint| {
+                                        lint.help(format!(
+                                            "there is an attribute with a similar name: `{flag}`"
+                                        ))
+                                        .help(help);
+                                    },
                                 );
                             }
                         }
@@ -1370,7 +1381,7 @@ impl LangString {
         };
 
         if custom_code_classes_in_docs {
-            call(&mut TagIterator::new(string, extra).into_iter())
+            call(&mut TagIterator::new(string, extra))
         } else {
             call(&mut tokens(string))
         }
@@ -2000,6 +2011,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     map.insert("themeStyle".into(), 1);
     map.insert("settings-menu".into(), 1);
     map.insert("help-button".into(), 1);
+    map.insert("sidebar-button".into(), 1);
     map.insert("main-content".into(), 1);
     map.insert("toggle-all-docs".into(), 1);
     map.insert("all-types".into(), 1);
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index ff7ce01e807..5ca623f01f1 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1,5 +1,3 @@
-use clean::AttributesExt;
-
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
@@ -465,16 +463,9 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
 
             clean::ImportItem(ref import) => {
                 let stab_tags = if let Some(import_def_id) = import.source.did {
-                    let ast_attrs = tcx.get_attrs_unchecked(import_def_id);
-                    let import_attrs = Box::new(clean::Attributes::from_ast(ast_attrs));
-
                     // Just need an item with the correct def_id and attrs
-                    let import_item = clean::Item {
-                        item_id: import_def_id.into(),
-                        attrs: import_attrs,
-                        cfg: ast_attrs.cfg(tcx, &cx.cache().hidden_cfg),
-                        ..myitem.clone()
-                    };
+                    let import_item =
+                        clean::Item { item_id: import_def_id.into(), ..myitem.clone() };
 
                     let stab_tags = Some(extra_info_tags(&import_item, item, tcx).to_string());
                     stab_tags
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index b3ae720fcf6..a1029320d2d 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -488,7 +488,7 @@ pub(crate) fn build_index<'tcx>(
 
     // Collect the index into a string
     format!(
-        r#""{}":{}"#,
+        r#"["{}",{}]"#,
         krate.name(tcx),
         serde_json::to_string(&CrateData {
             doc: crate_doc,
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 5f130f1875a..d1ece73374d 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -94,7 +94,7 @@ impl<'tcx> SpanMapVisitor<'tcx> {
 
     /// Used to generate links on items' definition to go to their documentation page.
     pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
-        if let Some(Node::Item(item)) = self.tcx.hir().find(hir_id) {
+        if let Some(Node::Item(item)) = self.tcx.opt_hir_node(hir_id) {
             if let Some(span) = self.tcx.def_ident_span(item.owner_id) {
                 let cspan = clean::Span::new(span);
                 // If the span isn't from the current crate, we ignore it.
@@ -177,7 +177,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
         if !span.overlaps(m.spans.inner_span) {
             // Now that we confirmed it's a file import, we want to get the span for the module
             // name only and not all the "mod foo;".
-            if let Some(Node::Item(item)) = self.tcx.hir().find(id) {
+            if let Some(Node::Item(item)) = self.tcx.opt_hir_node(id) {
                 self.matches.insert(
                     item.ident.span,
                     LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs
index ee581173a4a..738ea0aee7e 100644
--- a/src/librustdoc/html/render/type_layout.rs
+++ b/src/librustdoc/html/render/type_layout.rs
@@ -79,6 +79,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>(
             TypeLayoutSize { is_unsized, is_uninhabited, size }
         });
 
-        Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap())
+        TypeLayout { variants, type_layout_size }.render_into(f).unwrap();
+        Ok(())
     })
 }
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index b04776e91dc..6408e97df50 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -167,23 +167,24 @@ pub(super) fn write_shared(
         let mut krates = Vec::new();
 
         if path.exists() {
-            let prefix = format!("\"{krate}\"");
+            let prefix = format!("[\"{krate}\"");
             for line in BufReader::new(File::open(path)?).lines() {
                 let line = line?;
-                if !line.starts_with('"') {
+                if !line.starts_with("[\"") {
                     continue;
                 }
                 if line.starts_with(&prefix) {
                     continue;
                 }
-                if line.ends_with(",\\") {
+                if line.ends_with("],\\") {
                     ret.push(line[..line.len() - 2].to_string());
                 } else {
                     // Ends with "\\" (it's the case for the last added crate line)
                     ret.push(line[..line.len() - 1].to_string());
                 }
                 krates.push(
-                    line.split('"')
+                    line[1..] // We skip the `[` parent at the beginning of the line.
+                        .split('"')
                         .find(|s| !s.is_empty())
                         .map(|s| s.to_owned())
                         .unwrap_or_else(String::new),
@@ -285,7 +286,7 @@ pub(super) fn write_shared(
             let (mut all_sources, _krates) =
                 try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst);
             all_sources.push(format!(
-                r#""{}":{}"#,
+                r#"["{}",{}]"#,
                 &krate.name(cx.tcx()),
                 hierarchy
                     .to_json_string()
@@ -296,9 +297,12 @@ pub(super) fn write_shared(
                     .replace("\\\"", "\\\\\"")
             ));
             all_sources.sort();
-            let mut v = String::from("var srcIndex = JSON.parse('{\\\n");
+            // This needs to be `var`, not `const`.
+            // This variable needs declared in the current global scope so that if
+            // src-script.js loads first, it can pick it up.
+            let mut v = String::from("var srcIndex = new Map(JSON.parse('[\\\n");
             v.push_str(&all_sources.join(",\\\n"));
-            v.push_str("\\\n}');\ncreateSrcSidebar();\n");
+            v.push_str("\\\n]'));\ncreateSrcSidebar();\n");
             Ok(v.into_bytes())
         };
         write_invocation_specific("src-files.js", &make_sources)?;
@@ -316,13 +320,16 @@ pub(super) fn write_shared(
     // with rustdoc running in parallel.
     all_indexes.sort();
     write_invocation_specific("search-index.js", &|| {
-        let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
+        // This needs to be `var`, not `const`.
+        // This variable needs declared in the current global scope so that if
+        // search.js loads first, it can pick it up.
+        let mut v = String::from("var searchIndex = new Map(JSON.parse('[\\\n");
         v.push_str(&all_indexes.join(",\\\n"));
         v.push_str(
             r#"\
-}');
-if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)};
-if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
+]'));
+if (typeof exports !== 'undefined') exports.searchIndex = searchIndex;
+else if (window.initSearch) window.initSearch(searchIndex);
 "#,
         );
         Ok(v.into_bytes())
diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index fe0cf6dc8cc..390e812772a 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -9,7 +9,7 @@ rules.
 	margin-left: 0 !important;
 }
 
-#copy-path {
+#copy-path, #sidebar-button, .sidebar-resizer {
 	/* It requires JS to work so no need to display it in this case. */
 	display: none;
 }
@@ -132,6 +132,8 @@ nav.sub {
 	--scrape-example-help-hover-color: #000;
 	--scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1);
 	--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
+	--sidebar-resizer-hover: hsl(207, 90%, 66%);
+	--sidebar-resizer-active: hsl(207, 90%, 54%);
 }
 /* End theme: light */
 
@@ -238,6 +240,8 @@ nav.sub {
 		--scrape-example-help-hover-color: #fff;
 		--scrape-example-code-wrapper-background-start: rgba(53, 53, 53, 1);
 		--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
+		--sidebar-resizer-hover: hsl(207, 30%, 54%);
+		--sidebar-resizer-active: hsl(207, 90%, 54%);
 	}
 /* End theme: dark */
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 6e61969a8c1..6e673aa77c5 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -9,6 +9,11 @@
 :root {
 	--nav-sub-mobile-padding: 8px;
 	--search-typename-width: 6.75rem;
+	/* DEFAULT_SIDEBAR_WIDTH
+	   see main.js for information on these values
+	   and on the RUSTDOC_MOBILE_BREAKPOINT */
+	--desktop-sidebar-width: 200px;
+	--src-sidebar-width: 300px;
 }
 
 /* See FiraSans-LICENSE.txt for the Fira Sans license. */
@@ -383,13 +388,15 @@ img {
 
 .sidebar {
 	font-size: 0.875rem;
-	flex: 0 0 200px;
+	flex: 0 0 var(--desktop-sidebar-width);
+	width: var(--desktop-sidebar-width);
 	overflow-y: scroll;
 	overscroll-behavior: contain;
 	position: sticky;
 	height: 100vh;
 	top: 0;
 	left: 0;
+	z-index: 100;
 }
 
 .rustdoc.src .sidebar {
@@ -398,7 +405,95 @@ img {
 	overflow-x: hidden;
 	/* The sidebar is by default hidden  */
 	overflow-y: hidden;
-	z-index: 1;
+}
+
+.hide-sidebar .sidebar,
+.hide-sidebar .sidebar-resizer {
+	display: none;
+}
+
+.sidebar-resizer {
+	touch-action: none;
+	width: 9px;
+	cursor: col-resize;
+	z-index: 200;
+	position: fixed;
+	height: 100%;
+	/* make sure there's a 1px gap between the scrollbar and resize handle */
+	left: calc(var(--desktop-sidebar-width) + 1px);
+}
+
+.rustdoc.src .sidebar-resizer {
+	/* when closed, place resizer glow on top of the normal src sidebar border (no need to worry
+	   about sidebar) */
+	left: 49px;
+}
+
+.src-sidebar-expanded .rustdoc.src .sidebar-resizer {
+	/* for src sidebar, gap is already provided by 1px border on sidebar itself, so place resizer
+	   to right of it */
+	left: var(--src-sidebar-width);
+}
+
+.sidebar-resizing {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.sidebar-resizing * {
+	cursor: col-resize !important;
+}
+
+.sidebar-resizing .sidebar {
+	position: fixed;
+	z-index: 100;
+}
+.sidebar-resizing > body {
+	padding-left: var(--resizing-sidebar-width);
+}
+
+.sidebar-resizer:hover,
+.sidebar-resizer:active,
+.sidebar-resizer:focus,
+.sidebar-resizer.active {
+	width: 10px;
+	margin: 0;
+	/* when active or hovered, place resizer glow on top of the sidebar (right next to, or even
+	   on top of, the scrollbar) */
+	left: var(--desktop-sidebar-width);
+	border-left: solid 1px var(--sidebar-resizer-hover);
+}
+
+.src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover,
+.src-sidebar-expanded .rustdoc.src .sidebar-resizer:active,
+.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus,
+.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active {
+	/* when active or hovered, place resizer glow on top of the normal src sidebar border */
+	left: calc(var(--src-sidebar-width) - 1px);
+}
+
+@media (pointer: coarse) {
+	.sidebar-resizer {
+		/* too easy to hit the resizer while trying to hit the [-] toggle */
+		display: none !important;
+	}
+}
+
+.sidebar-resizer.active {
+	/* make the resize tool bigger when actually resizing, to avoid :hover styles on other stuff
+		while resizing */
+	padding: 0 140px;
+	width: 2px;
+	margin-left: -140px;
+	border-left: none;
+}
+.sidebar-resizer.active:before {
+	border-left: solid 2px var(--sidebar-resizer-active);
+	display: block;
+	height: 100%;
+	content: "";
 }
 
 .sidebar, .mobile-topbar, .sidebar-menu-toggle,
@@ -416,7 +511,8 @@ img {
 
 .src-sidebar-expanded .src .sidebar {
 	overflow-y: auto;
-	flex-basis: 300px;
+	flex-basis: var(--src-sidebar-width);
+	width: var(--src-sidebar-width);
 }
 
 .src-sidebar-expanded .src .sidebar > *:not(#src-sidebar-toggle) {
@@ -477,6 +573,7 @@ ul.block, .block li {
 	display: block;
 	padding: 0.25rem; /* 4px */
 	margin-left: -0.25rem;
+	margin-right: 0.25rem;
 }
 
 .sidebar h2 {
@@ -775,7 +872,7 @@ h2.section-header > .anchor {
 	text-decoration: underline;
 }
 
-.crate.block a.current { font-weight: 500; }
+.crate.block li.current a { font-weight: 500; }
 
 /*  In most contexts we use `overflow-wrap: anywhere` to ensure that we can wrap
 	as much as needed on mobile (see
@@ -1478,7 +1575,20 @@ a.tooltip:hover::after {
 	margin-left: 4px;
 	display: flex;
 }
-#settings-menu > a, #help-button > a {
+#sidebar-button {
+	display: none;
+}
+.hide-sidebar #sidebar-button {
+	display: flex;
+	margin-right: 4px;
+	position: fixed;
+	left: 6px;
+	height: 34px;
+	width: 34px;
+	background-color: var(--main-background-color);
+	z-index: 1;
+}
+#settings-menu > a, #help-button > a, #sidebar-button > a {
 	display: flex;
 	align-items: center;
 	justify-content: center;
@@ -1493,10 +1603,21 @@ a.tooltip:hover::after {
 }
 
 #settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
+#help-button > a:hover, #help-button > a:focus,
+#sidebar-button > a:hover, #sidebar-button > a:focus {
 	border-color: var(--settings-button-border-focus);
 }
 
+#sidebar-button > a:before {
+	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" \
+		fill="none" stroke="black">\
+		<rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5"/>\
+		<circle cx="4.375" cy="4.375" r="1" stroke-width=".75"/>\
+		<path d="m7.6121 3v16 M5.375 7.625h-2 m2 3h-2 m2 3h-2" stroke-width="1.25"/></svg>');
+	width: 22px;
+	height: 22px;
+}
+
 #copy-path {
 	color: var(--copy-path-button-color);
 	background: var(--main-background-color);
@@ -1711,7 +1832,7 @@ However, it's not needed with smaller screen width because the doc/code block is
 /*
 WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
 If you update this line, then you also need to update the line with the same warning
-in src-script.js
+in src-script.js and main.js
 */
 @media (max-width: 700px) {
 	/* When linking to an item with an `id` (for instance, by clicking a link in the sidebar,
@@ -1722,6 +1843,10 @@ in src-script.js
 		scroll-margin-top: 45px;
 	}
 
+	.hide-sidebar #sidebar-button {
+		position: static;
+	}
+
 	.rustdoc {
 		/* Sidebar should overlay main content, rather than pushing main content to the right.
 		   Turn off `display: flex` on the body element. */
@@ -1750,7 +1875,8 @@ in src-script.js
 	/* Hide the logo and item name from the sidebar. Those are displayed
 	   in the mobile-topbar instead. */
 	.sidebar .logo-container,
-	.sidebar .location {
+	.sidebar .location,
+	.sidebar-resizer {
 		display: none;
 	}
 
@@ -1818,6 +1944,10 @@ in src-script.js
 		top: 0;
 	}
 
+	.hide-sidebar .mobile-topbar {
+		display: none;
+	}
+
 	.sidebar-menu-toggle {
 		width: 45px;
 		/* Rare exception to specifying font sizes in rem. Since this is acting
@@ -1827,6 +1957,10 @@ in src-script.js
 		color: var(--main-color);
 	}
 
+	.hide-sidebar .sidebar-menu-toggle {
+		display: none;
+	}
+
 	.sidebar-elems {
 		margin-top: 1em;
 	}
@@ -1870,6 +2004,17 @@ in src-script.js
 		display: none;
 	}
 
+	/* sidebar button becomes topbar button */
+	#sidebar-button > a:before {
+		content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
+			viewBox="0 0 22 22" fill="none" stroke="black">\
+			<rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5"/>\
+			<circle cx="4.375" cy="4.375" r="1" stroke-width=".75"/>\
+			<path d="m3 7.375h16m0-3h-4" stroke-width="1.25"/></svg>');
+		width: 22px;
+		height: 22px;
+	}
+
 	/* Display an alternating layout on tablets and phones */
 	.item-table, .item-row, .item-table > li, .item-table > li > div,
 	.search-results > a, .search-results > a > div {
@@ -2274,6 +2419,8 @@ in src-script.js
 	--scrape-example-help-hover-color: #000;
 	--scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1);
 	--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
+	--sidebar-resizer-hover: hsl(207, 90%, 66%);
+	--sidebar-resizer-active: hsl(207, 90%, 54%);
 }
 /* End theme: light */
 
@@ -2379,6 +2526,8 @@ in src-script.js
 	--scrape-example-help-hover-color: #fff;
 	--scrape-example-code-wrapper-background-start: rgba(53, 53, 53, 1);
 	--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
+	--sidebar-resizer-hover: hsl(207, 30%, 54%);
+	--sidebar-resizer-active: hsl(207, 90%, 54%);
 }
 /* End theme: dark */
 
@@ -2488,6 +2637,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--scrape-example-help-hover-color: #fff;
 	--scrape-example-code-wrapper-background-start: rgba(15, 20, 25, 1);
 	--scrape-example-code-wrapper-background-end: rgba(15, 20, 25, 0);
+	--sidebar-resizer-hover: hsl(34, 50%, 33%);
+	--sidebar-resizer-active: hsl(34, 100%, 66%);
 }
 
 :root[data-theme="ayu"] h1,
@@ -2519,6 +2670,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 }
 
 :root[data-theme="ayu"] .sidebar .current,
+:root[data-theme="ayu"] .sidebar .current a,
 :root[data-theme="ayu"] .sidebar a:hover,
 :root[data-theme="ayu"] #src-sidebar div.files > a:hover,
 :root[data-theme="ayu"] details.dir-entry summary:hover,
@@ -2569,7 +2721,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	border-bottom: 1px solid rgba(242, 151, 24, 0.3);
 }
 
-:root[data-theme="ayu"] #settings-menu > a img {
+:root[data-theme="ayu"] #settings-menu > a img,
+:root[data-theme="ayu"] #sidebar-button > a:before {
 	filter: invert(100);
 }
 /* End theme: ayu */
diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js
index 2338931a18f..93709e4e830 100644
--- a/src/librustdoc/html/static/js/externs.js
+++ b/src/librustdoc/html/static/js/externs.js
@@ -14,7 +14,7 @@ function initSearch(searchIndex){}
  *     pathWithoutLast: Array<string>,
  *     pathLast: string,
  *     generics: Array<QueryElement>,
- *     bindings: Map<(string|integer), Array<QueryElement>>,
+ *     bindings: Map<integer, Array<QueryElement>>,
  * }}
  */
 let QueryElement;
@@ -42,6 +42,7 @@ let ParserState;
  *     totalElems: number,
  *     literalSearch: boolean,
  *     corrections: Array<{from: string, to: integer}>,
+ *     typeFingerprint: Uint32Array,
  * }}
  */
 let ParsedQuery;
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index d613997cd7f..63ab56053af 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -1,5 +1,5 @@
 // Local js definitions:
-/* global addClass, getSettingValue, hasClass, searchState */
+/* global addClass, getSettingValue, hasClass, searchState, updateLocalStorage */
 /* global onEach, onEachLazy, removeClass, getVar */
 
 "use strict";
@@ -495,7 +495,7 @@ function preLoadCss(cssUrl) {
                 }
                 const link = document.createElement("a");
                 link.href = path;
-                if (link.href === current_page) {
+                if (path === current_page) {
                     link.className = "current";
                 }
                 link.textContent = name;
@@ -857,12 +857,12 @@ function preLoadCss(cssUrl) {
         for (const crate of window.ALL_CRATES) {
             const link = document.createElement("a");
             link.href = window.rootPath + crate + "/index.html";
-            if (window.rootPath !== "./" && crate === window.currentCrate) {
-                link.className = "current";
-            }
             link.textContent = crate;
 
             const li = document.createElement("li");
+            if (window.rootPath !== "./" && crate === window.currentCrate) {
+                li.className = "current";
+            }
             li.appendChild(link);
             ul.appendChild(li);
         }
@@ -1473,6 +1473,264 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
     searchState.setup();
 }());
 
+// Hide, show, and resize the sidebar
+//
+// The body class and CSS variable are initially set up in storage.js,
+// but in this file, we implement:
+//
+//   * the show sidebar button, which appears if the sidebar is hidden
+//     and, by clicking on it, will bring it back
+//   * the sidebar resize handle, which appears only on large viewports
+//     with a [fine precision pointer] to allow the user to change
+//     the size of the sidebar
+//
+// [fine precision pointer]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
+(function() {
+    // 100 is the size of the logo
+    // don't let the sidebar get smaller than that, or it'll get squished
+    const SIDEBAR_MIN = 100;
+    // Don't let the sidebar get bigger than this
+    const SIDEBAR_MAX = 500;
+    // Don't let the body (including the gutter) get smaller than this
+    //
+    // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
+    // Acceptable values for BODY_MIN are constrained by the mobile breakpoint
+    // (which is the minimum size of the whole page where the sidebar exists)
+    // and the default sidebar width:
+    //
+    //     BODY_MIN <= RUSTDOC_MOBILE_BREAKPOINT - DEFAULT_SIDEBAR_WIDTH
+    //
+    // At the time of this writing, the DEFAULT_SIDEBAR_WIDTH on src pages is
+    // 300px, and the RUSTDOC_MOBILE_BREAKPOINT is 700px, so BODY_MIN must be
+    // at most 400px. Otherwise, it would start out at the default size, then
+    // grabbing the resize handle would suddenly cause it to jank to
+    // its contraint-generated maximum.
+    const RUSTDOC_MOBILE_BREAKPOINT = 700;
+    const BODY_MIN = 400;
+    // At half-way past the minimum size, vanish the sidebar entirely
+    const SIDEBAR_VANISH_THRESHOLD = SIDEBAR_MIN / 2;
+
+    // Toolbar button to show the sidebar.
+    //
+    // On small, "mobile-sized" viewports, it's not persistent and it
+    // can only be activated by going into Settings and hiding the nav bar.
+    // On larger, "desktop-sized" viewports (though that includes many
+    // tablets), it's fixed-position, appears in the left side margin,
+    // and it can be activated by resizing the sidebar into nothing.
+    const sidebarButton = document.getElementById("sidebar-button");
+    if (sidebarButton) {
+        sidebarButton.addEventListener("click", e => {
+            removeClass(document.documentElement, "hide-sidebar");
+            updateLocalStorage("hide-sidebar", "false");
+            e.preventDefault();
+        });
+    }
+
+    // Pointer capture.
+    //
+    // Resizing is a single-pointer gesture. Any secondary pointer is ignored
+    let currentPointerId = null;
+
+    // "Desired" sidebar size.
+    //
+    // This is stashed here for window resizing. If the sidebar gets
+    // shrunk to maintain BODY_MIN, and then the user grows the window again,
+    // it gets the sidebar to restore its size.
+    let desiredSidebarSize = null;
+
+    // Sidebar resize debouncer.
+    //
+    // The sidebar itself is resized instantly, but the body HTML can be too
+    // big for that, causing reflow jank. To reduce this, we queue up a separate
+    // animation frame and throttle it.
+    let pendingSidebarResizingFrame = false;
+
+    // If this page has no sidebar at all, bail out.
+    const resizer = document.querySelector(".sidebar-resizer");
+    const sidebar = document.querySelector(".sidebar");
+    if (!resizer || !sidebar) {
+        return;
+    }
+
+    // src page and docs page use different variables, because the contents of
+    // the sidebar are so different that it's reasonable to thing the user
+    // would want them to have different sizes
+    const isSrcPage = hasClass(document.body, "src");
+
+    // Call this function to hide the sidebar when using the resize handle
+    //
+    // This function also nulls out the sidebar width CSS variable and setting,
+    // causing it to return to its default. This does not happen if you do it
+    // from settings.js, which uses a separate function. It's done here because
+    // the minimum sidebar size is rather uncomfortable, and it must pass
+    // through that size when using the shrink-to-nothing gesture.
+    function hideSidebar() {
+        if (isSrcPage) {
+            window.rustdocCloseSourceSidebar();
+            updateLocalStorage("src-sidebar-width", null);
+            // [RUSTDOCIMPL] CSS variable fast path
+            //
+            // The sidebar width variable is attached to the <html> element by
+            // storage.js, because the sidebar and resizer don't exist yet.
+            // But the resize code, in `resize()`, sets the property on the
+            // sidebar and resizer elements (which are the only elements that
+            // use the variable) to avoid recalculating CSS on the entire
+            // document on every frame.
+            //
+            // So, to clear it, we need to clear all three.
+            document.documentElement.style.removeProperty("--src-sidebar-width");
+            sidebar.style.removeProperty("--src-sidebar-width");
+            resizer.style.removeProperty("--src-sidebar-width");
+        } else {
+            addClass(document.documentElement, "hide-sidebar");
+            updateLocalStorage("hide-sidebar", "true");
+            updateLocalStorage("desktop-sidebar-width", null);
+            document.documentElement.style.removeProperty("--desktop-sidebar-width");
+            sidebar.style.removeProperty("--desktop-sidebar-width");
+            resizer.style.removeProperty("--desktop-sidebar-width");
+        }
+    }
+
+    // Call this function to show the sidebar from the resize handle.
+    // On docs pages, this can only happen if the user has grabbed the resize
+    // handle, shrunk the sidebar down to nothing, and then pulls back into
+    // the visible range without releasing it. You can, however, grab the
+    // resize handle on a source page with the sidebar closed, because it
+    // remains visible all the time on there.
+    function showSidebar() {
+        if (isSrcPage) {
+            window.rustdocShowSourceSidebar();
+        } else {
+            removeClass(document.documentElement, "hide-sidebar");
+            updateLocalStorage("hide-sidebar", "false");
+        }
+    }
+
+    /**
+     * Call this to set the correct CSS variable and setting.
+     * This function doesn't enforce size constraints. Do that before calling it!
+     *
+     * @param {number} size - CSS px width of the sidebar.
+     */
+    function changeSidebarSize(size) {
+        if (isSrcPage) {
+            updateLocalStorage("src-sidebar-width", size);
+            // [RUSTDOCIMPL] CSS variable fast path
+            //
+            // While this property is set on the HTML element at load time,
+            // because the sidebar isn't actually loaded yet,
+            // we scope this update to the sidebar to avoid hitting a slow
+            // path in WebKit.
+            sidebar.style.setProperty("--src-sidebar-width", size + "px");
+            resizer.style.setProperty("--src-sidebar-width", size + "px");
+        } else {
+            updateLocalStorage("desktop-sidebar-width", size);
+            sidebar.style.setProperty("--desktop-sidebar-width", size + "px");
+            resizer.style.setProperty("--desktop-sidebar-width", size + "px");
+        }
+    }
+
+    // Check if the sidebar is hidden. Since src pages and doc pages have
+    // different settings, this function has to check that.
+    function isSidebarHidden() {
+        return isSrcPage ?
+            !hasClass(document.documentElement, "src-sidebar-expanded") :
+            hasClass(document.documentElement, "hide-sidebar");
+    }
+
+    // Respond to the resize handle event.
+    // This function enforces size constraints, and implements the
+    // shrink-to-nothing gesture based on thresholds defined above.
+    function resize(e) {
+        if (currentPointerId === null || currentPointerId !== e.pointerId) {
+            return;
+        }
+        e.preventDefault();
+        const pos = e.clientX - sidebar.offsetLeft - 3;
+        if (pos < SIDEBAR_VANISH_THRESHOLD) {
+            hideSidebar();
+        } else if (pos >= SIDEBAR_MIN) {
+            if (isSidebarHidden()) {
+                showSidebar();
+            }
+            // don't let the sidebar get wider than SIDEBAR_MAX, or the body narrower
+            // than BODY_MIN
+            const constrainedPos = Math.min(pos, window.innerWidth - BODY_MIN, SIDEBAR_MAX);
+            changeSidebarSize(constrainedPos);
+            desiredSidebarSize = constrainedPos;
+            if (pendingSidebarResizingFrame !== false) {
+                clearTimeout(pendingSidebarResizingFrame);
+            }
+            pendingSidebarResizingFrame = setTimeout(() => {
+                if (currentPointerId === null || pendingSidebarResizingFrame === false) {
+                    return;
+                }
+                pendingSidebarResizingFrame = false;
+                document.documentElement.style.setProperty(
+                    "--resizing-sidebar-width",
+                    desiredSidebarSize + "px"
+                );
+            }, 100);
+        }
+    }
+    // Respond to the window resize event.
+    window.addEventListener("resize", () => {
+        if (window.innerWidth < RUSTDOC_MOBILE_BREAKPOINT) {
+            return;
+        }
+        stopResize();
+        if (desiredSidebarSize >= (window.innerWidth - BODY_MIN)) {
+            changeSidebarSize(window.innerWidth - BODY_MIN);
+        } else if (desiredSidebarSize !== null && desiredSidebarSize > SIDEBAR_MIN) {
+            changeSidebarSize(desiredSidebarSize);
+        }
+    });
+    function stopResize(e) {
+        if (currentPointerId === null) {
+            return;
+        }
+        if (e) {
+            e.preventDefault();
+        }
+        desiredSidebarSize = sidebar.getBoundingClientRect().width;
+        removeClass(resizer, "active");
+        window.removeEventListener("pointermove", resize, false);
+        window.removeEventListener("pointerup", stopResize, false);
+        removeClass(document.documentElement, "sidebar-resizing");
+        document.documentElement.style.removeProperty( "--resizing-sidebar-width");
+        if (resizer.releasePointerCapture) {
+            resizer.releasePointerCapture(currentPointerId);
+            currentPointerId = null;
+        }
+    }
+    function initResize(e) {
+        if (currentPointerId !== null || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
+            return;
+        }
+        if (resizer.setPointerCapture) {
+            resizer.setPointerCapture(e.pointerId);
+            if (!resizer.hasPointerCapture(e.pointerId)) {
+                // unable to capture pointer; something else has it
+                // on iOS, this usually means you long-clicked a link instead
+                resizer.releasePointerCapture(e.pointerId);
+                return;
+            }
+            currentPointerId = e.pointerId;
+        }
+        e.preventDefault();
+        window.addEventListener("pointermove", resize, false);
+        window.addEventListener("pointercancel", stopResize, false);
+        window.addEventListener("pointerup", stopResize, false);
+        addClass(resizer, "active");
+        addClass(document.documentElement, "sidebar-resizing");
+        const pos = e.clientX - sidebar.offsetLeft - 3;
+        document.documentElement.style.setProperty( "--resizing-sidebar-width", pos + "px");
+        desiredSidebarSize = null;
+    }
+    resizer.addEventListener("pointerdown", initResize, false);
+}());
+
+// This section handles the copy button that appears next to the path breadcrumbs
 (function() {
     let reset_button_timeout = null;
 
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index f2875b7f01e..ccb54e14a5c 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -80,10 +80,6 @@ const longItemTypes = [
 const TY_GENERIC = itemTypes.indexOf("generic");
 const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
 
-function hasOwnPropertyRustdoc(obj, property) {
-    return Object.prototype.hasOwnProperty.call(obj, property);
-}
-
 // In the search display, allows to switch between tabs.
 function printTab(nb) {
     let iter = 0;
@@ -238,6 +234,10 @@ function initSearch(rawSearchIndex) {
      *  @type {Array<Row>}
      */
     let searchIndex;
+    /**
+     *  @type {Uint32Array}
+     */
+    let functionTypeFingerprint;
     let currentResults;
     /**
      * Map from normalized type names to integers. Used to make type search
@@ -1038,6 +1038,8 @@ function initSearch(rawSearchIndex) {
             correction: null,
             proposeCorrectionFrom: null,
             proposeCorrectionTo: null,
+            // bloom filter build from type ids
+            typeFingerprint: new Uint32Array(4),
         };
     }
 
@@ -1068,7 +1070,7 @@ function initSearch(rawSearchIndex) {
 
         if (elem &&
             elem.value !== "all crates" &&
-            hasOwnPropertyRustdoc(rawSearchIndex, elem.value)
+            rawSearchIndex.has(elem.value)
         ) {
             return elem.value;
         }
@@ -1133,7 +1135,6 @@ function initSearch(rawSearchIndex) {
             query.error = err;
             return query;
         }
-
         if (!query.literalSearch) {
             // If there is more than one element in the query, we switch to literalSearch in any
             // case.
@@ -1329,25 +1330,6 @@ function initSearch(rawSearchIndex) {
                 return 0;
             });
 
-            let nameSplit = null;
-            if (parsedQuery.elems.length === 1) {
-                const hasPath = typeof parsedQuery.elems[0].path === "undefined";
-                nameSplit = hasPath ? null : parsedQuery.elems[0].path;
-            }
-
-            for (const result of result_list) {
-                // this validation does not make sense when searching by types
-                if (result.dontValidate) {
-                    continue;
-                }
-                const name = result.item.name.toLowerCase(),
-                    path = result.item.path.toLowerCase(),
-                    parent = result.item.parent;
-
-                if (!isType && !validateResult(name, path, nameSplit, parent)) {
-                    result.id = -1;
-                }
-            }
             return transformResults(result_list);
         }
 
@@ -1960,8 +1942,7 @@ function initSearch(rawSearchIndex) {
          * @param {integer} path_dist
          */
         function addIntoResults(results, fullId, id, index, dist, path_dist, maxEditDistance) {
-            const inBounds = dist <= maxEditDistance || index !== -1;
-            if (dist === 0 || (!parsedQuery.literalSearch && inBounds)) {
+            if (dist <= maxEditDistance || index !== -1) {
                 if (results.has(fullId)) {
                     const result = results.get(fullId);
                     if (result.dontValidate || result.dist <= dist) {
@@ -2009,17 +1990,31 @@ function initSearch(rawSearchIndex) {
             const fullId = row.id;
             const searchWord = searchWords[pos];
 
-            const in_args = row.type && row.type.inputs
-                && checkIfInList(row.type.inputs, elem, row.type.where_clause);
-            if (in_args) {
-                // path_dist is 0 because no parent path information is currently stored
-                // in the search index
-                addIntoResults(results_in_args, fullId, pos, -1, 0, 0, maxEditDistance);
-            }
-            const returned = row.type && row.type.output
-                && checkIfInList(row.type.output, elem, row.type.where_clause);
-            if (returned) {
-                addIntoResults(results_returned, fullId, pos, -1, 0, 0, maxEditDistance);
+            // fpDist is a minimum possible type distance, where "type distance" is the number of
+            // atoms in the function not present in the query
+            const tfpDist = compareTypeFingerprints(
+                fullId,
+                parsedQuery.typeFingerprint
+            );
+            if (tfpDist !== null) {
+                const in_args = row.type && row.type.inputs
+                    && checkIfInList(row.type.inputs, elem, row.type.where_clause);
+                const returned = row.type && row.type.output
+                    && checkIfInList(row.type.output, elem, row.type.where_clause);
+                if (in_args) {
+                    results_in_args.max_dist = Math.max(results_in_args.max_dist || 0, tfpDist);
+                    const maxDist = results_in_args.size < MAX_RESULTS ?
+                        (tfpDist + 1) :
+                        results_in_args.max_dist;
+                    addIntoResults(results_in_args, fullId, pos, -1, tfpDist, 0, maxDist);
+                }
+                if (returned) {
+                    results_returned.max_dist = Math.max(results_returned.max_dist || 0, tfpDist);
+                    const maxDist = results_returned.size < MAX_RESULTS ?
+                        (tfpDist + 1) :
+                        results_returned.max_dist;
+                    addIntoResults(results_returned, fullId, pos, -1, tfpDist, 0, maxDist);
+                }
             }
 
             if (!typePassesFilter(elem.typeFilter, row.ty)) {
@@ -2078,6 +2073,17 @@ function initSearch(rawSearchIndex) {
                 return;
             }
 
+            const tfpDist = compareTypeFingerprints(
+                row.id,
+                parsedQuery.typeFingerprint
+            );
+            if (tfpDist === null) {
+                return;
+            }
+            if (results.size >= MAX_RESULTS && tfpDist > results.max_dist) {
+                return;
+            }
+
             // If the result is too "bad", we return false and it ends this search.
             if (!unifyFunctionTypes(
                 row.type.inputs,
@@ -2096,12 +2102,11 @@ function initSearch(rawSearchIndex) {
                 return;
             }
 
-            addIntoResults(results, row.id, pos, 0, 0, 0, Number.MAX_VALUE);
+            results.max_dist = Math.max(results.max_dist || 0, tfpDist);
+            addIntoResults(results, row.id, pos, 0, tfpDist, 0, Number.MAX_VALUE);
         }
 
         function innerRunQuery() {
-            let elem, i, nSearchWords, in_returned, row;
-
             let queryLen = 0;
             for (const elem of parsedQuery.elems) {
                 queryLen += elem.name.length;
@@ -2218,17 +2223,20 @@ function initSearch(rawSearchIndex) {
                 );
             }
 
+            const fps = new Set();
             for (const elem of parsedQuery.elems) {
                 convertNameToId(elem);
+                buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint, fps);
             }
             for (const elem of parsedQuery.returned) {
                 convertNameToId(elem);
+                buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint, fps);
             }
 
-            if (parsedQuery.foundElems === 1) {
+            if (parsedQuery.foundElems === 1 && parsedQuery.returned.length === 0) {
                 if (parsedQuery.elems.length === 1) {
-                    elem = parsedQuery.elems[0];
-                    for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
+                    const elem = parsedQuery.elems[0];
+                    for (let i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
                         // It means we want to check for this element everywhere (in names, args and
                         // returned).
                         handleSingleArg(
@@ -2241,30 +2249,25 @@ function initSearch(rawSearchIndex) {
                             maxEditDistance
                         );
                     }
-                } else if (parsedQuery.returned.length === 1) {
-                    // We received one returned argument to check, so looking into returned values.
-                    elem = parsedQuery.returned[0];
-                    for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
-                        row = searchIndex[i];
-                        in_returned = row.type && unifyFunctionTypes(
-                            row.type.output,
-                            parsedQuery.returned,
-                            row.type.where_clause
-                        );
-                        if (in_returned) {
-                            addIntoResults(
-                                results_others,
-                                row.id,
-                                i,
-                                -1,
-                                0,
-                                Number.MAX_VALUE
-                            );
-                        }
-                    }
                 }
             } else if (parsedQuery.foundElems > 0) {
-                for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
+                // Sort input and output so that generic type variables go first and
+                // types with generic parameters go last.
+                // That's because of the way unification is structured: it eats off
+                // the end, and hits a fast path if the last item is a simple atom.
+                const sortQ = (a, b) => {
+                    const ag = a.generics.length === 0 && a.bindings.size === 0;
+                    const bg = b.generics.length === 0 && b.bindings.size === 0;
+                    if (ag !== bg) {
+                        return ag - bg;
+                    }
+                    const ai = a.id > 0;
+                    const bi = b.id > 0;
+                    return ai - bi;
+                };
+                parsedQuery.elems.sort(sortQ);
+                parsedQuery.returned.sort(sortQ);
+                for (let i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
                     handleArgs(searchIndex[i], i, results_others);
                 }
             }
@@ -2287,44 +2290,6 @@ function initSearch(rawSearchIndex) {
         return ret;
     }
 
-    /**
-     * Validate performs the following boolean logic. For example:
-     * "File::open" will give IF A PARENT EXISTS => ("file" && "open")
-     * exists in (name || path || parent) OR => ("file" && "open") exists in
-     * (name || path )
-     *
-     * This could be written functionally, but I wanted to minimise
-     * functions on stack.
-     *
-     * @param  {string} name   - The name of the result
-     * @param  {string} path   - The path of the result
-     * @param  {string} keys   - The keys to be used (["file", "open"])
-     * @param  {Object} parent - The parent of the result
-     *
-     * @return {boolean}       - Whether the result is valid or not
-     */
-    function validateResult(name, path, keys, parent, maxEditDistance) {
-        if (!keys || !keys.length) {
-            return true;
-        }
-        for (const key of keys) {
-            // each check is for validation so we negate the conditions and invalidate
-            if (!(
-                // check for an exact name match
-                name.indexOf(key) > -1 ||
-                // then an exact path match
-                path.indexOf(key) > -1 ||
-                // next if there is a parent, check for exact parent match
-                (parent !== undefined && parent.name !== undefined &&
-                    parent.name.toLowerCase().indexOf(key) > -1) ||
-                // lastly check to see if the name was an editDistance match
-                editDistance(name, key, maxEditDistance) <= maxEditDistance)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     function nextTab(direction) {
         const next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length;
         searchState.focusedByTab[searchState.currentTab] = document.activeElement;
@@ -2420,7 +2385,6 @@ function initSearch(rawSearchIndex) {
         const extraClass = display ? " active" : "";
 
         const output = document.createElement("div");
-        let length = 0;
         if (array.length > 0) {
             output.className = "search-results " + extraClass;
 
@@ -2430,8 +2394,6 @@ function initSearch(rawSearchIndex) {
                 const longType = longItemTypes[item.ty];
                 const typeName = longType.length !== 0 ? `${longType}` : "?";
 
-                length += 1;
-
                 const link = document.createElement("a");
                 link.className = "result-" + type;
                 link.href = item.href;
@@ -2479,7 +2441,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 "href=\"https://docs.rs\">Docs.rs</a> for documentation of crates released on" +
                 " <a href=\"https://crates.io/\">crates.io</a>.</li></ul>";
         }
-        return [output, length];
+        return [output, array.length];
     }
 
     function makeTabHeader(tabNb, text, nbElems) {
@@ -2558,11 +2520,10 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         }
 
         let crates = "";
-        const crates_list = Object.keys(rawSearchIndex);
-        if (crates_list.length > 1) {
+        if (rawSearchIndex.size > 1) {
             crates = " in&nbsp;<div id=\"crate-search-div\"><select id=\"crate-search\">" +
                 "<option value=\"all crates\">all crates</option>";
-            for (const c of crates_list) {
+            for (const c of rawSearchIndex.keys()) {
                 crates += `<option value="${c}" ${c === filterCrates && "selected"}>${c}</option>`;
             }
             crates += "</select></div>";
@@ -2846,6 +2807,117 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         };
     }
 
+    /**
+     * Type fingerprints allow fast, approximate matching of types.
+     *
+     * This algo creates a compact representation of the type set using a Bloom filter.
+     * This fingerprint is used three ways:
+     *
+     * - It accelerates the matching algorithm by checking the function fingerprint against the
+     *   query fingerprint. If any bits are set in the query but not in the function, it can't
+     *   match.
+     *
+     * - The fourth section has the number of distinct items in the set.
+     *   This is the distance function, used for filtering and for sorting.
+     *
+     * [^1]: Distance is the relatively naive metric of counting the number of distinct items in
+     * the function that are not present in the query.
+     *
+     * @param {FunctionType|QueryElement} type - a single type
+     * @param {Uint32Array} output - write the fingerprint to this data structure: uses 128 bits
+     * @param {Set<number>} fps - Set of distinct items
+     */
+    function buildFunctionTypeFingerprint(type, output, fps) {
+        let input = type.id;
+        // All forms of `[]` get collapsed down to one thing in the bloom filter.
+        // Differentiating between arrays and slices, if the user asks for it, is
+        // still done in the matching algorithm.
+        if (input === typeNameIdOfArray || input === typeNameIdOfSlice) {
+            input = typeNameIdOfArrayOrSlice;
+        }
+        // http://burtleburtle.net/bob/hash/integer.html
+        // ~~ is toInt32. It's used before adding, so
+        // the number stays in safe integer range.
+        const hashint1 = k => {
+            k = (~~k + 0x7ed55d16) + (k << 12);
+            k = (k ^ 0xc761c23c) ^ (k >>> 19);
+            k = (~~k + 0x165667b1) + (k << 5);
+            k = (~~k + 0xd3a2646c) ^ (k << 9);
+            k = (~~k + 0xfd7046c5) + (k << 3);
+            return (k ^ 0xb55a4f09) ^ (k >>> 16);
+        };
+        const hashint2 = k => {
+            k = ~k + (k << 15);
+            k ^= k >>> 12;
+            k += k << 2;
+            k ^= k >>> 4;
+            k = Math.imul(k, 2057);
+            return k ^ (k >> 16);
+        };
+        if (input !== null) {
+            const h0a = hashint1(input);
+            const h0b = hashint2(input);
+            // Less Hashing, Same Performance: Building a Better Bloom Filter
+            // doi=10.1.1.72.2442
+            const h1a = ~~(h0a + Math.imul(h0b, 2));
+            const h1b = ~~(h0a + Math.imul(h0b, 3));
+            const h2a = ~~(h0a + Math.imul(h0b, 4));
+            const h2b = ~~(h0a + Math.imul(h0b, 5));
+            output[0] |= (1 << (h0a % 32)) | (1 << (h1b % 32));
+            output[1] |= (1 << (h1a % 32)) | (1 << (h2b % 32));
+            output[2] |= (1 << (h2a % 32)) | (1 << (h0b % 32));
+            fps.add(input);
+        }
+        for (const g of type.generics) {
+            buildFunctionTypeFingerprint(g, output, fps);
+        }
+        const fb = {
+            id: null,
+            ty: 0,
+            generics: [],
+            bindings: new Map(),
+        };
+        for (const [k, v] of type.bindings.entries()) {
+            fb.id = k;
+            fb.generics = v;
+            buildFunctionTypeFingerprint(fb, output, fps);
+        }
+        output[3] = fps.size;
+    }
+
+    /**
+     * Compare the query fingerprint with the function fingerprint.
+     *
+     * @param {{number}} fullId - The function
+     * @param {{Uint32Array}} queryFingerprint - The query
+     * @returns {number|null} - Null if non-match, number if distance
+     *                          This function might return 0!
+     */
+    function compareTypeFingerprints(fullId, queryFingerprint) {
+        const fh0 = functionTypeFingerprint[fullId * 4];
+        const fh1 = functionTypeFingerprint[(fullId * 4) + 1];
+        const fh2 = functionTypeFingerprint[(fullId * 4) + 2];
+        const [qh0, qh1, qh2] = queryFingerprint;
+        // Approximate set intersection with bloom filters.
+        // This can be larger than reality, not smaller, because hashes have
+        // the property that if they've got the same value, they hash to the
+        // same thing. False positives exist, but not false negatives.
+        const [in0, in1, in2] = [fh0 & qh0, fh1 & qh1, fh2 & qh2];
+        // Approximate the set of items in the query but not the function.
+        // This might be smaller than reality, but cannot be bigger.
+        //
+        // | in_ | qh_ | XOR | Meaning                                          |
+        // | --- | --- | --- | ------------------------------------------------ |
+        // |  0  |  0  |  0  | Not present                                      |
+        // |  1  |  0  |  1  | IMPOSSIBLE because `in_` is `fh_ & qh_`          |
+        // |  1  |  1  |  0  | If one or both is false positive, false negative |
+        // |  0  |  1  |  1  | Since in_ has no false negatives, must be real   |
+        if ((in0 ^ qh0) || (in1 ^ qh1) || (in2 ^ qh2)) {
+            return null;
+        }
+        return functionTypeFingerprint[(fullId * 4) + 3];
+    }
+
     function buildIndex(rawSearchIndex) {
         searchIndex = [];
         /**
@@ -2865,68 +2937,73 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         typeNameIdOfSlice = buildTypeMapIndex("slice");
         typeNameIdOfArrayOrSlice = buildTypeMapIndex("[]");
 
-        for (const crate in rawSearchIndex) {
-            if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) {
-                continue;
-            }
-
-            let crateSize = 0;
-
-            /**
-             * The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f`
-             * are arrays with the same length. `q`, `a`, and `c` use a sparse
-             * representation for compactness.
-             *
-             * `n[i]` contains the name of an item.
-             *
-             * `t[i]` contains the type of that item
-             * (as a string of characters that represent an offset in `itemTypes`).
-             *
-             * `d[i]` contains the description of that item.
-             *
-             * `q` contains the full paths of the items. For compactness, it is a set of
-             * (index, path) pairs used to create a map. If a given index `i` is
-             * not present, this indicates "same as the last index present".
-             *
-             * `i[i]` contains an item's parent, usually a module. For compactness,
-             * it is a set of indexes into the `p` array.
-             *
-             * `f[i]` contains function signatures, or `0` if the item isn't a function.
-             * Functions are themselves encoded as arrays. The first item is a list of
-             * types representing the function's inputs, and the second list item is a list
-             * of types representing the function's output. Tuples are flattened.
-             * Types are also represented as arrays; the first item is an index into the `p`
-             * array, while the second is a list of types representing any generic parameters.
-             *
-             * b[i] contains an item's impl disambiguator. This is only present if an item
-             * is defined in an impl block and, the impl block's type has more than one associated
-             * item with the same name.
-             *
-             * `a` defines aliases with an Array of pairs: [name, offset], where `offset`
-             * points into the n/t/d/q/i/f arrays.
-             *
-             * `doc` contains the description of the crate.
-             *
-             * `p` is a list of path/type pairs. It is used for parents and function parameters.
-             *
-             * `c` is an array of item indices that are deprecated.
-             *
-             * @type {{
-             *   doc: string,
-             *   a: Object,
-             *   n: Array<string>,
-             *   t: String,
-             *   d: Array<string>,
-             *   q: Array<[Number, string]>,
-             *   i: Array<Number>,
-             *   f: Array<RawFunctionSearchType>,
-             *   p: Array<Object>,
-             *   b: Array<[Number, String]>,
-             *   c: Array<Number>
-             * }}
-             */
-            const crateCorpus = rawSearchIndex[crate];
+        // Function type fingerprints are 128-bit bloom filters that are used to
+        // estimate the distance between function and query.
+        // This loop counts the number of items to allocate a fingerprint for.
+        for (const crate of rawSearchIndex.values()) {
+            // Each item gets an entry in the fingerprint array, and the crate
+            // does, too
+            id += crate.t.length + 1;
+        }
+        functionTypeFingerprint = new Uint32Array((id + 1) * 4);
 
+        // This loop actually generates the search item indexes, including
+        // normalized names, type signature objects and fingerprints, and aliases.
+        id = 0;
+        /**
+         * The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f`
+         * are arrays with the same length. `q`, `a`, and `c` use a sparse
+         * representation for compactness.
+         *
+         * `n[i]` contains the name of an item.
+         *
+         * `t[i]` contains the type of that item
+         * (as a string of characters that represent an offset in `itemTypes`).
+         *
+         * `d[i]` contains the description of that item.
+         *
+         * `q` contains the full paths of the items. For compactness, it is a set of
+         * (index, path) pairs used to create a map. If a given index `i` is
+         * not present, this indicates "same as the last index present".
+         *
+         * `i[i]` contains an item's parent, usually a module. For compactness,
+         * it is a set of indexes into the `p` array.
+         *
+         * `f[i]` contains function signatures, or `0` if the item isn't a function.
+         * Functions are themselves encoded as arrays. The first item is a list of
+         * types representing the function's inputs, and the second list item is a list
+         * of types representing the function's output. Tuples are flattened.
+         * Types are also represented as arrays; the first item is an index into the `p`
+         * array, while the second is a list of types representing any generic parameters.
+         *
+         * b[i] contains an item's impl disambiguator. This is only present if an item
+         * is defined in an impl block and, the impl block's type has more than one associated
+         * item with the same name.
+         *
+         * `a` defines aliases with an Array of pairs: [name, offset], where `offset`
+         * points into the n/t/d/q/i/f arrays.
+         *
+         * `doc` contains the description of the crate.
+         *
+         * `p` is a list of path/type pairs. It is used for parents and function parameters.
+         *
+         * `c` is an array of item indices that are deprecated.
+         *
+         * @type {{
+         *   doc: string,
+         *   a: Object,
+         *   n: Array<string>,
+         *   t: String,
+         *   d: Array<string>,
+         *   q: Array<[Number, string]>,
+         *   i: Array<Number>,
+         *   f: Array<RawFunctionSearchType>,
+         *   p: Array<Object>,
+         *   b: Array<[Number, String]>,
+         *   c: Array<Number>
+         * }}
+         */
+        for (const [crate, crateCorpus] of rawSearchIndex) {
             searchWords.push(crate);
             // This object should have exactly the same set of fields as the "row"
             // object defined below. Your JavaScript runtime will thank you.
@@ -3014,6 +3091,28 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 }
                 searchWords.push(word);
                 const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath;
+                let type = null;
+                if (itemFunctionSearchTypes[i] !== 0) {
+                    type = buildFunctionSearchType(
+                        itemFunctionSearchTypes[i],
+                        lowercasePaths
+                    );
+                    if (type) {
+                        const fp = functionTypeFingerprint.subarray(id * 4, (id + 1) * 4);
+                        const fps = new Set();
+                        for (const t of type.inputs) {
+                            buildFunctionTypeFingerprint(t, fp, fps);
+                        }
+                        for (const t of type.output) {
+                            buildFunctionTypeFingerprint(t, fp, fps);
+                        }
+                        for (const w of type.where_clause) {
+                            for (const t of w) {
+                                buildFunctionTypeFingerprint(t, fp, fps);
+                            }
+                        }
+                    }
+                }
                 const row = {
                     crate: crate,
                     ty: itemTypes.charCodeAt(i) - charA,
@@ -3021,10 +3120,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                     path: path,
                     desc: itemDescs[i],
                     parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined,
-                    type: buildFunctionSearchType(
-                        itemFunctionSearchTypes[i],
-                        lowercasePaths
-                    ),
+                    type,
                     id: id,
                     normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""),
                     deprecated: deprecatedItems.has(i),
@@ -3033,14 +3129,13 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 id += 1;
                 searchIndex.push(row);
                 lastPath = row.path;
-                crateSize += 1;
             }
 
             if (aliases) {
                 const currentCrateAliases = new Map();
                 ALIASES.set(crate, currentCrateAliases);
                 for (const alias_name in aliases) {
-                    if (!hasOwnPropertyRustdoc(aliases, alias_name)) {
+                    if (!Object.prototype.hasOwnProperty.call(aliases, alias_name)) {
                         continue;
                     }
 
@@ -3056,7 +3151,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                     }
                 }
             }
-            currentIndex += crateSize;
+            currentIndex += itemTypes.length;
         }
         return searchWords;
     }
@@ -3265,7 +3360,7 @@ if (typeof window !== "undefined") {
 } else {
     // Running in Node, not a browser. Run initSearch just to produce the
     // exports.
-    initSearch({});
+    initSearch(new Map());
 }
 
 
diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js
index 70a2825265e..2b42fbebb80 100644
--- a/src/librustdoc/html/static/js/settings.js
+++ b/src/librustdoc/html/static/js/settings.js
@@ -29,6 +29,13 @@
                     window.rustdoc_remove_line_numbers_from_examples();
                 }
                 break;
+            case "hide-sidebar":
+                if (value === true) {
+                    addClass(document.documentElement, "hide-sidebar");
+                } else {
+                    removeClass(document.documentElement, "hide-sidebar");
+                }
+                break;
         }
     }
 
@@ -187,6 +194,11 @@
                 "default": false,
             },
             {
+                "name": "Hide persistent navigation bar",
+                "js_name": "hide-sidebar",
+                "default": false,
+            },
+            {
                 "name": "Disable keyboard shortcuts",
                 "js_name": "disable-shortcuts",
                 "default": false,
@@ -216,6 +228,13 @@
 
     function displaySettings() {
         settingsMenu.style.display = "";
+        onEachLazy(settingsMenu.querySelectorAll("input[type='checkbox']"), el => {
+            const val = getSettingValue(el.id);
+            const checked = val === "true";
+            if (checked !== el.checked && val !== null) {
+                el.checked = checked;
+            }
+        });
     }
 
     function settingsBlurHandler(event) {
diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js
index 679c2341f02..fc1d2d37845 100644
--- a/src/librustdoc/html/static/js/src-script.js
+++ b/src/librustdoc/html/static/js/src-script.js
@@ -71,16 +71,31 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
     return hasFoundFile;
 }
 
+let toggleLabel;
+
+function getToggleLabel() {
+    toggleLabel = toggleLabel || document.querySelector("#src-sidebar-toggle button");
+    return toggleLabel;
+}
+
+window.rustdocCloseSourceSidebar = () => {
+    removeClass(document.documentElement, "src-sidebar-expanded");
+    getToggleLabel().innerText = ">";
+    updateLocalStorage("source-sidebar-show", "false");
+};
+
+window.rustdocShowSourceSidebar = () => {
+    addClass(document.documentElement, "src-sidebar-expanded");
+    getToggleLabel().innerText = "<";
+    updateLocalStorage("source-sidebar-show", "true");
+};
+
 function toggleSidebar() {
     const child = this.parentNode.children[0];
     if (child.innerText === ">") {
-        addClass(document.documentElement, "src-sidebar-expanded");
-        child.innerText = "<";
-        updateLocalStorage("source-sidebar-show", "true");
+        window.rustdocShowSourceSidebar();
     } else {
-        removeClass(document.documentElement, "src-sidebar-expanded");
-        child.innerText = ">";
-        updateLocalStorage("source-sidebar-show", "false");
+        window.rustdocCloseSourceSidebar();
     }
 }
 
@@ -118,10 +133,10 @@ function createSrcSidebar() {
     title.className = "title";
     title.innerText = "Files";
     sidebar.appendChild(title);
-    Object.keys(srcIndex).forEach(key => {
-        srcIndex[key][NAME_OFFSET] = key;
-        hasFoundFile = createDirEntry(srcIndex[key], sidebar, "", hasFoundFile);
-    });
+    for (const [key, source] of srcIndex) {
+        source[NAME_OFFSET] = key;
+        hasFoundFile = createDirEntry(source, sidebar, "", hasFoundFile);
+    }
 
     container.appendChild(sidebar);
     // Focus on the current file in the source files sidebar.
@@ -131,12 +146,8 @@ function createSrcSidebar() {
     }
 }
 
-const lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/;
-
-function highlightSrcLines(match) {
-    if (typeof match === "undefined") {
-        match = window.location.hash.match(lineNumbersRegex);
-    }
+function highlightSrcLines() {
+    const match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
     if (!match) {
         return;
     }
@@ -218,12 +229,7 @@ const handleSrcHighlight = (function() {
     };
 }());
 
-window.addEventListener("hashchange", () => {
-    const match = window.location.hash.match(lineNumbersRegex);
-    if (match) {
-        return highlightSrcLines(match);
-    }
-});
+window.addEventListener("hashchange", highlightSrcLines);
 
 onEachLazy(document.getElementsByClassName("src-line-numbers"), el => {
     el.addEventListener("click", handleSrcHighlight);
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 37250ba5a1f..ac9c6f377b8 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -183,11 +183,38 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
 
 updateTheme();
 
+// Hide, show, and resize the sidebar at page load time
+//
+// This needs to be done here because this JS is render-blocking,
+// so that the sidebar doesn't "jump" after appearing on screen.
+// The user interaction to change this is set up in main.js.
 if (getSettingValue("source-sidebar-show") === "true") {
     // At this point in page load, `document.body` is not available yet.
     // Set a class on the `<html>` element instead.
     addClass(document.documentElement, "src-sidebar-expanded");
 }
+if (getSettingValue("hide-sidebar") === "true") {
+    // At this point in page load, `document.body` is not available yet.
+    // Set a class on the `<html>` element instead.
+    addClass(document.documentElement, "hide-sidebar");
+}
+function updateSidebarWidth() {
+    const desktopSidebarWidth = getSettingValue("desktop-sidebar-width");
+    if (desktopSidebarWidth && desktopSidebarWidth !== "null") {
+        document.documentElement.style.setProperty(
+            "--desktop-sidebar-width",
+            desktopSidebarWidth + "px"
+        );
+    }
+    const srcSidebarWidth = getSettingValue("src-sidebar-width");
+    if (srcSidebarWidth && srcSidebarWidth !== "null") {
+        document.documentElement.style.setProperty(
+            "--src-sidebar-width",
+            srcSidebarWidth + "px"
+        );
+    }
+}
+updateSidebarWidth();
 
 // If we navigate away (for example to a settings page), and then use the back or
 // forward button to get back to a page, the theme may have changed in the meantime.
@@ -201,5 +228,6 @@ if (getSettingValue("source-sidebar-show") === "true") {
 window.addEventListener("pageshow", ev => {
     if (ev.persisted) {
         setTimeout(updateTheme, 0);
+        setTimeout(updateSidebarWidth, 0);
     }
 });
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 3f6147bb916..60ca5660c02 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -114,6 +114,7 @@
         {% endif %}
         {{ sidebar|safe }}
     </nav> {# #}
+    <div class="sidebar-resizer"></div>
     <main> {# #}
         {% if page.css_class != "src" %}<div class="width-limiter">{% endif %}
             <nav class="sub"> {# #}
@@ -128,6 +129,11 @@
                 {% endif %}
                 <form class="search-form"> {# #}
                     <span></span> {# This empty span is a hacky fix for Safari - See #93184 #}
+                    {% if page.css_class != "src" %}
+                    <div id="sidebar-button" tabindex="-1"> {# #}
+                        <a href="{{page.root_path|safe}}{{layout.krate|safe}}/all.html" title="show sidebar"></a> {# #}
+                    </div> {# #}
+                    {% endif %}
                     <input {#+ #}
                         class="search-input" {#+ #}
                         name="search" {#+ #}
@@ -136,8 +142,8 @@
                         spellcheck="false" {#+ #}
                         placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {#+ #}
                         type="search"> {# #}
-                    <div id="help-button" title="help" tabindex="-1"> {# #}
-                        <a href="{{page.root_path|safe}}help.html">?</a> {# #}
+                    <div id="help-button" tabindex="-1"> {# #}
+                        <a href="{{page.root_path|safe}}help.html" title="help">?</a> {# #}
                     </div> {# #}
                     <div id="settings-menu" tabindex="-1"> {# #}
                         <a href="{{page.root_path|safe}}settings.html" title="settings"> {# #}
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index d45040e348a..267f1cb0b72 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -33,7 +33,7 @@ where
     let lints = || {
         lint::builtin::HardwiredLints::get_lints()
             .into_iter()
-            .chain(rustc_lint::SoftLints::get_lints().into_iter())
+            .chain(rustc_lint::SoftLints::get_lints())
     };
 
     let lint_opts = lints()
@@ -46,7 +46,7 @@ where
                 filter_call(lint)
             }
         })
-        .chain(lint_opts.into_iter())
+        .chain(lint_opts)
         .collect::<Vec<_>>();
 
     let lint_caps = lints()
diff --git a/src/librustdoc/passes/check_custom_code_classes.rs b/src/librustdoc/passes/check_custom_code_classes.rs
index 6266d3ff51d..f246e2962fe 100644
--- a/src/librustdoc/passes/check_custom_code_classes.rs
+++ b/src/librustdoc/passes/check_custom_code_classes.rs
@@ -48,7 +48,7 @@ struct TestsWithCustomClasses {
 
 impl crate::doctest::Tester for TestsWithCustomClasses {
     fn add_test(&mut self, _: String, config: LangString, _: usize) {
-        self.custom_classes_found.extend(config.added_classes.into_iter());
+        self.custom_classes_found.extend(config.added_classes);
     }
 }
 
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 21a31b9df93..a931e8804d9 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -80,7 +80,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
 
     // check if parent is trait impl
     if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id)
-        && let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id)
+        && let Some(parent_node) = cx.tcx.opt_hir_node_by_def_id(parent_def_id)
         && matches!(
             parent_node,
             hir::Node::Item(hir::Item {
@@ -131,7 +131,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
                 hir_id,
                 sp,
                 "missing code example in this documentation",
-                |lint| lint,
+                |_| {},
             );
         }
     } else if tests.found_tests > 0
@@ -142,7 +142,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
             hir_id,
             item.attr_span(cx.tcx),
             "documentation test in private item",
-            |lint| lint,
+            |_| {},
         );
     }
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 6b536e97c43..ee185ab9892 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1755,8 +1755,6 @@ fn report_diagnostic(
         }
 
         decorate(lint, span, link_range);
-
-        lint
     });
 }
 
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index 0c5cfffe1be..bffa17da3b4 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -31,7 +31,7 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                             "use an automatic link instead",
                             format!("<{url}>"),
                             Applicability::MachineApplicable,
-                        )
+                        );
                 });
             };
 
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index e9b9e36a530..b5583ae4520 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -131,8 +131,6 @@ fn check_rust_syntax(
         for message in buffer.messages.iter() {
             lint.note(message.clone());
         }
-
-        lint
     });
 }
 
diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs
index 4a80c22ed08..90874c01102 100644
--- a/src/librustdoc/passes/lint/html_tags.rs
+++ b/src/librustdoc/passes/lint/html_tags.rs
@@ -89,7 +89,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                     if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
                         || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
                     {
-                        return lint;
+                        return;
                     }
                     // multipart form is chosen here because ``Vec<i32>`` would be confusing.
                     lint.multipart_suggestion(
@@ -101,8 +101,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                         Applicability::MaybeIncorrect,
                     );
                 }
-
-                lint
             });
         };
 
diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs
index 472781e7d22..4491d20b478 100644
--- a/src/librustdoc/passes/lint/redundant_explicit_links.rs
+++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs
@@ -181,8 +181,6 @@ fn check_inline_or_reference_unknown_redundancy(
                 .span_label(display_span, "because label contains path that resolves to same destination")
                 .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links")
                 .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways);
-
-            lint
         });
     }
 
@@ -234,8 +232,6 @@ fn check_reference_redundancy(
                 .span_note(def_span, "referenced explicit link target defined here")
                 .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links")
                 .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways);
-
-            lint
         });
     }
 
diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs
index 8b7fdd6ab1f..0893cd0b40b 100644
--- a/src/librustdoc/passes/lint/unescaped_backticks.rs
+++ b/src/librustdoc/passes/lint/unescaped_backticks.rs
@@ -111,8 +111,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                     }
 
                     suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it");
-
-                    lint
                 });
             }
             Event::Code(_) => {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index bef151745d8..42ff1210f23 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -168,10 +168,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     })
                     .collect::<Vec<_>>()
             })
-            .chain(
-                [Cfg::Cfg(sym::test, None), Cfg::Cfg(sym::doc, None), Cfg::Cfg(sym::doctest, None)]
-                    .into_iter(),
-            )
+            .chain([
+                Cfg::Cfg(sym::test, None),
+                Cfg::Cfg(sym::doc, None),
+                Cfg::Cfg(sym::doctest, None),
+            ])
             .collect();
 
         self.cx.cache.exact_paths = self.exact_paths;
@@ -275,7 +276,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         };
 
         let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
-        let item = tcx.hir().get_by_def_id(res_did);
+        let item = tcx.hir_node_by_def_id(res_did);
 
         if !please_inline {
             let inherits_hidden = !document_hidden && inherits_doc_hidden(tcx, res_did, None);
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 7738295178045041669876bf32b0543ec8319a5
+Subproject 2c4de6c2492d5530de3f19f41d8f88ba984c2fe
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 9787229614b27854cf73d57ffae430d7c1e6caa
+Subproject 1aa9df1a5be205cce621f0bc0ea6062a5e22a98
diff --git a/src/tools/clippy/clippy_lints/src/absolute_paths.rs b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
index 83d15c0c425..3822b83b4bc 100644
--- a/src/tools/clippy/clippy_lints/src/absolute_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
@@ -62,7 +62,7 @@ impl LateLintPass<'_> for AbsolutePaths {
         } = self;
 
         if !path.span.from_expansion()
-            && let Some(node) = cx.tcx.hir().find(hir_id)
+            && let Some(node) = cx.tcx.opt_hir_node(hir_id)
             && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(_, _)))
             && let [first, rest @ ..] = path.segments
             // Handle `::std`
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
index 55294f5f386..b55cd8833b7 100644
--- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
@@ -10,8 +10,8 @@ use super::AS_PTR_CAST_MUT;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {
     if let ty::RawPtr(
-        ptrty @ TypeAndMut {
-            mutbl: Mutability::Mut, ..
+        TypeAndMut {
+            mutbl: Mutability::Mut, ty: ptrty,
         },
     ) = cast_to.kind()
         && let ty::RawPtr(TypeAndMut {
@@ -34,7 +34,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
             cx,
             AS_PTR_CAST_MUT,
             expr.span,
-            &format!("casting the result of `as_ptr` to *{ptrty}"),
+            &format!("casting the result of `as_ptr` to *mut {ptrty}"),
             "replace with",
             format!("{recv}.as_mut_ptr()"),
             applicability,
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
index 2a9f7fec172..91bad8256ec 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -69,7 +69,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv
 fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     let map = cx.tcx.hir();
     if let Some(parent_id) = map.opt_parent_id(expr.hir_id)
-        && let Some(parent) = map.find(parent_id)
+        && let Some(parent) = cx.tcx.opt_hir_node(parent_id)
     {
         let expr = match parent {
             Node::Block(block) => {
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 854324f845b..aaef163ad55 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1090,7 +1090,7 @@ fn report<'tcx>(
                 if parent_id == data.first_expr.hir_id {
                     return;
                 }
-                (cx.tcx.hir().get(parent_id).expect_expr().span, true)
+                (cx.tcx.hir_node(parent_id).expect_expr().span, true)
             } else {
                 (expr.span, false)
             };
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 53ef6d7e387..6b0423200d7 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -195,7 +195,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
             && let Some(def_id) = trait_ref.trait_def_id()
             && cx.tcx.is_diagnostic_item(sym::Default, def_id)
             && let impl_item_hir = child.id.hir_id()
-            && let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir)
+            && let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
             && let ImplItemKind::Fn(_, b) = &impl_item.kind
             && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
             && let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs
index e97030cc8b6..1d2b907b948 100644
--- a/src/tools/clippy/clippy_lints/src/empty_drop.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs
@@ -42,7 +42,7 @@ impl LateLintPass<'_> for EmptyDrop {
         }) = item.kind
             && trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait()
             && let impl_item_hir = child.id.hir_id()
-            && let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir)
+            && let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
             && let ImplItemKind::Fn(_, b) = &impl_item.kind
             && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
             && let func_expr = peel_blocks(func_expr)
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 3452f98c5aa..b7776263060 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -5,7 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::{self, TraitRef, Ty};
+use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
@@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
             .hir()
             .get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id))
             .def_id;
-        let parent_node = cx.tcx.hir().find_by_def_id(parent_id);
+        let parent_node = cx.tcx.opt_hir_node_by_def_id(parent_id);
 
         let mut trait_self_ty = None;
         if let Some(Node::Item(item)) = parent_node {
@@ -122,8 +122,8 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
 }
 
 // TODO: Replace with Map::is_argument(..) when it's fixed
-fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool {
-    match map.find(id) {
+fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {
+    match tcx.opt_hir_node(id) {
         Some(Node::Pat(Pat {
             kind: PatKind::Binding(..),
             ..
@@ -131,7 +131,7 @@ fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool {
         _ => return false,
     }
 
-    matches!(map.find_parent(id), Some(Node::Param(_)))
+    matches!(tcx.hir().find_parent(id), Some(Node::Param(_)))
 }
 
 impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
@@ -154,7 +154,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
     fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {
         if cmt.place.projections.is_empty() {
             let map = &self.cx.tcx.hir();
-            if is_argument(*map, cmt.hir_id) {
+            if is_argument(self.cx.tcx, cmt.hir_id) {
                 // Skip closure arguments
                 let parent_id = map.parent_id(cmt.hir_id);
                 if let Some(Node::Expr(..)) = map.find_parent(parent_id) {
diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs
index a974c10bc7d..6603512c73c 100644
--- a/src/tools/clippy/clippy_lints/src/exit.rs
+++ b/src/tools/clippy/clippy_lints/src/exit.rs
@@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit {
             && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id()
             && cx.tcx.is_diagnostic_item(sym::process_exit, def_id)
             && let parent = cx.tcx.hir().get_parent_item(e.hir_id).def_id
-            && let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.hir().find_by_def_id(parent)
+            && let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.opt_hir_node_by_def_id(parent)
             // If the next item up is a function we check if it is an entry point
             // and only then emit a linter warning
             && !is_entrypoint_fn(cx, parent.to_def_id())
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 4e2e1d1724a..f1366c434f4 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -111,7 +111,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
         // Find id of the local that expr_end_of_block resolves to
         && let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind
         && let Res::Local(expr_res) = expr_path.res
-        && let Some(Node::Pat(res_pat)) = cx.tcx.hir().find(expr_res)
+        && let Some(Node::Pat(res_pat)) = cx.tcx.opt_hir_node(expr_res)
 
         // Find id of the local we found in the block
         && let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
index 5e90fcd72eb..f1200c2edc1 100644
--- a/src/tools/clippy/clippy_lints/src/functions/result.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -92,7 +92,7 @@ fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty
             .expect("already checked this is adt")
             .did()
             .as_local()
-        && let Some(hir::Node::Item(item)) = cx.tcx.hir().find_by_def_id(local_def_id)
+        && let Some(hir::Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(local_def_id)
         && let hir::ItemKind::Enum(ref def, _) = item.kind
     {
         let variants_size = AdtVariantInfo::new(cx, *adt, subst);
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index b6f9d8b81f8..5417c13d079 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -248,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
 
                 // Checking for slice indexing
                 && let parent_id = map.parent_id(expr.hir_id)
-                && let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id)
+                && let Some(hir::Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id)
                 && let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind
                 && let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr)
                 && let Ok(index_value) = index_value.try_into()
@@ -256,7 +256,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
 
                 // Make sure that this slice index is read only
                 && let maybe_addrof_id = map.parent_id(parent_id)
-                && let Some(hir::Node::Expr(maybe_addrof_expr)) = map.find(maybe_addrof_id)
+                && let Some(hir::Node::Expr(maybe_addrof_expr)) = cx.tcx.opt_hir_node(maybe_addrof_id)
                 && let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind
             {
                 use_info.index_use.push((index_value, map.span(parent_expr.hir_id)));
diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs
index 5c926133c42..e4781752e75 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs
@@ -122,7 +122,7 @@ fn get_impl_span(cx: &LateContext<'_>, id: LocalDefId) -> Option<Span> {
         kind: ItemKind::Impl(impl_item),
         span,
         ..
-    }) = cx.tcx.hir().get(id)
+    }) = cx.tcx.hir_node(id)
     {
         (!span.from_expansion()
             && impl_item.generics.params.is_empty()
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index e121da776b2..8c032b17023 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -8,8 +8,8 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::{
     AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind,
-    ImplicitSelfKind, Item, ItemKind, LangItem, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef,
-    TyKind, TypeBindingKind,
+    ImplicitSelfKind, Item, ItemKind, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef,
+    TyKind, TypeBindingKind, OpaqueTyOrigin,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
@@ -147,7 +147,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
             && let Some(output) =
                 parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder())
         {
-            let (name, kind) = match cx.tcx.hir().find(ty_hir_id) {
+            let (name, kind) = match cx.tcx.opt_hir_node(ty_hir_id) {
                 Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
                 Some(Node::Item(x)) => match x.kind {
                     ItemKind::Struct(..) => (x.ident.name, "struct"),
@@ -289,8 +289,10 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
             kind: ItemKind::OpaqueTy(opaque),
             ..
         } = item
-        && opaque.bounds.len() == 1
-        && let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0]
+        && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin
+        && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
+        && let Some(segment) = trait_ref.trait_ref.path.segments.last()
+        && let Some(generic_args) = segment.args
         && generic_args.bindings.len() == 1
         && let TypeBindingKind::Equality {
             term:
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 17ca48683b3..ffef84d1fad 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -195,7 +195,7 @@ fn check_fn_inner<'tcx>(
             .iter()
             // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
             // `Node::GenericParam`.
-            .filter_map(|&def_id| cx.tcx.hir().get_by_def_id(def_id).ident())
+            .filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())
             .map(|ident| ident.to_string())
             .collect::<Vec<_>>()
             .join(", ");
diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
index 227096251a5..c4e60e98ad4 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
@@ -40,7 +40,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option<Span>) {
 
 fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId> {
     if let Some(hir_id) = path_to_local(bound)
-        && let Node::Pat(pat) = cx.tcx.hir().get(hir_id)
+        && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
         && let PatKind::Binding(BindingAnnotation::MUT, ..) = pat.kind
     {
         return Some(hir_id);
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index f4eaf649f77..c245eaf1ab4 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -58,12 +58,12 @@ pub(super) fn check<'tcx>(
                 match cx.qpath_res(qpath, pushed_item.hir_id) {
                     // immutable bindings that are initialized with literal or constant
                     Res::Local(hir_id) => {
-                        let node = cx.tcx.hir().get(hir_id);
+                        let node = cx.tcx.hir_node(hir_id);
                         if let Node::Pat(pat) = node
                             && let PatKind::Binding(bind_ann, ..) = pat.kind
                             && !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut))
                             && let parent_node = cx.tcx.hir().parent_id(hir_id)
-                            && let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node)
+                            && let Some(Node::Local(parent_let_expr)) = cx.tcx.opt_hir_node(parent_node)
                             && let Some(init) = parent_let_expr.init
                         {
                             match init.kind {
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index ee053ffe4ec..eaaaea0be9f 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
             && block.stmts.is_empty()
             && let Some(closure_body) = desugared_async_block(cx, block)
             && let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) =
-                cx.tcx.hir().get_by_def_id(def_id)
+                cx.tcx.hir_node_by_def_id(def_id)
         {
             let header_span = span.with_hi(ret_ty.span.hi());
 
diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
index e006df7d666..71a83a68db9 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
             // Also ensures the const is nonzero since zero can't be a divisor
             && const1 == const2 && const2 == const3
             && let Some(hir_id) = path_to_local(expr3)
-            && let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id)
+            && let Some(Node::Pat(_)) = cx.tcx.opt_hir_node(hir_id)
         {
             // Apply only to params or locals with annotated types
             match cx.tcx.hir().find_parent(hir_id) {
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
index ac7bc9bcca4..9251130a305 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
@@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
             // add note if not multi-line
             span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| {
                 let (applicability, pat) = if let Some(id) = path_to_local(recv)
-                    && let Some(hir::Node::Pat(pat)) = cx.tcx.hir().find(id)
+                    && let Some(hir::Node::Pat(pat)) = cx.tcx.opt_hir_node(id)
                     && let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind
                 {
                     (Applicability::Unspecified, Some((pat.span, ident)))
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs
index fbe20dfe54e..d1215290dad 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs
@@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
             "called `skip(..).next()` on an iterator",
             |diag| {
                 if let Some(id) = path_to_local(recv)
-                    && let Node::Pat(pat) = cx.tcx.hir().get(id)
+                    && let Node::Pat(pat) = cx.tcx.hir_node(id)
                     && let PatKind::Binding(ann, _, _, _) = pat.kind
                     && ann != BindingAnnotation::MUT
                 {
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index 826c3de1db5..63e64a5b35d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
 
     fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {
         if let Res::Local(local_id) = path.res
-            && let Some(Node::Pat(pat)) = self.cx.tcx.hir().find(local_id)
+            && let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
             && let PatKind::Binding(_, local_id, ..) = pat.kind
         {
             self.identifiers.insert(local_id);
@@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
                 && let ExprKind::Path(ref path) = expr.kind
                 && let QPath::Resolved(_, path) = path
                 && let Res::Local(local_id) = path.res
-                && let Some(Node::Pat(pat)) = self.cx.tcx.hir().find(local_id)
+                && let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
                 && let PatKind::Binding(_, local_id, ..) = pat.kind
                 && self.identifiers.contains(&local_id)
             {
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index f5b749c7f80..34b8e0dbe6a 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -91,7 +91,7 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
         let node = if hir_id.local_id == ItemLocalId::from_u32(0) {
             // In this case, we can just use `find`, `Owner`'s `node` field is private anyway so we can't
             // reimplement it even if we wanted to
-            cx.tcx.hir().find(hir_id)
+            cx.tcx.opt_hir_node(hir_id)
         } else {
             let Some(owner) = cx.tcx.hir_owner_nodes(hir_id.owner).as_owner() else {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 5f736898159..acaa6be3009 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
         {
             let parent = cx.tcx.hir().get_parent_item(hir_id).def_id;
             if parent != CRATE_DEF_ID {
-                if let hir::Node::Item(item) = cx.tcx.hir().get_by_def_id(parent) {
+                if let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent) {
                     if let hir::ItemKind::Trait(..) = &item.kind {
                         return;
                     }
diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
index 8be45b8c2f3..88b331ddefd 100644
--- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
@@ -220,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
             && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs()
             && let Some(self_adt) = self_ty.ty_adt_def()
             && let Some(self_def_id) = self_adt.did().as_local()
-            && let Some(Node::Item(self_item)) = cx.tcx.hir().find_by_def_id(self_def_id)
+            && let Some(Node::Item(self_item)) = cx.tcx.opt_hir_node_by_def_id(self_def_id)
             // NB: can't call cx.typeck_results() as we are not in a body
             && let typeck_results = cx.tcx.typeck_body(*body_id)
             && should_lint(cx, typeck_results, block)
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index cd180754113..34119c6911c 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -213,7 +213,7 @@ fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) {
         if parent_id == cur_id {
             break;
         }
-        let Some(parent_node) = map.find(parent_id) else { break };
+        let Some(parent_node) = vis.cx.tcx.opt_hir_node(parent_id) else { break };
 
         let stop_early = match parent_node {
             Node::Expr(expr) => check_expr(vis, expr),
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 13b736cd9ad..64ef709e2fa 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -113,8 +113,9 @@ fn check_closures<'tcx>(
         }
         ctx.prev_bind = None;
         ctx.prev_move_to_closure.clear();
-        if let Some(body) = hir
-            .find_by_def_id(closure)
+        if let Some(body) = cx
+            .tcx
+            .opt_hir_node_by_def_id(closure)
             .and_then(associated_body)
             .map(|(_, body_id)| hir.body(body_id))
         {
@@ -412,7 +413,7 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
                         ],
                     ),
                 ..
-            }) = self.tcx.hir().get(cmt.hir_id)
+            }) = self.tcx.hir_node(cmt.hir_id)
             {
                 self.async_closures.insert(*def_id);
             }
@@ -521,7 +522,7 @@ impl<'tcx> Visitor<'tcx> for FnNeedsMutVisitor<'_, 'tcx> {
         let Self { cx, used_fn_def_ids } = self;
 
         // #11182; do not lint if mutability is required elsewhere
-        if let Node::Expr(expr) = cx.tcx.hir().get(hir_id)
+        if let Node::Expr(expr) = cx.tcx.hir_node(hir_id)
             && let Some(parent) = get_parent_node(cx.tcx, expr.hir_id)
             && let ty::FnDef(def_id, _) = cx
                 .tcx
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 4f8922aea17..4013cb34561 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -454,7 +454,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                 if parent_id == cur_expr.hir_id {
                     break;
                 }
-                if let Some(Node::Expr(parent_expr)) = cx.tcx.hir().find(parent_id) {
+                if let Some(Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id) {
                     match &parent_expr.kind {
                         ExprKind::AddrOf(..) => {
                             // `&e` => `e` must be referenced.
diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
index 352540d70b5..793a3a9545c 100644
--- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -94,7 +94,6 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
         {
             let mut non_send_fields = Vec::new();
 
-            let hir_map = cx.tcx.hir();
             for variant in adt_def.variants() {
                 for field in &variant.fields {
                     if let Some(field_hir_id) = field
@@ -104,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
                         && !is_lint_allowed(cx, NON_SEND_FIELDS_IN_SEND_TY, field_hir_id)
                         && let field_ty = field.ty(cx.tcx, impl_trait_args)
                         && !ty_allowed_in_send(cx, field_ty, send_trait)
-                        && let Node::Field(field_def) = hir_map.get(field_hir_id)
+                        && let Node::Field(field_def) = cx.tcx.hir_node(field_hir_id)
                     {
                         non_send_fields.push(NonSendField {
                             def: field_def,
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 8c374d7d6db..2c511ee0bc0 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
             && last_segment.ident == ident
             // resolve the path to its defining binding pattern
             && let Res::Local(binding_id) = cx.qpath_res(&qpath, expr.hir_id)
-            && let Node::Pat(binding_pat) = cx.tcx.hir().get(binding_id)
+            && let Node::Pat(binding_pat) = cx.tcx.hir_node(binding_id)
             // the previous binding has the same mutability
             && find_binding(binding_pat, ident).is_some_and(|bind| bind.1 == mutability)
             // the local does not change the effect of assignments to the binding. see #11290
diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs
index 74193e0199f..1316343e0c2 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                     Some(trait_ref) => {
                         let mut methods_in_trait: BTreeSet<Symbol> = if let Some(Node::TraitRef(TraitRef {
                             path, ..
-                        })) = cx.tcx.hir().find(trait_ref.hir_ref_id)
+                        })) = cx.tcx.opt_hir_node(trait_ref.hir_ref_id)
                             && let Res::Def(DefKind::Trait, did) = path.res
                         {
                             // FIXME: if
diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
index 935dd4a3630..98f3235af10 100644
--- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
+++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
@@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
         if let Some(self_def) = self_ty.ty_adt_def()
             && let Some(self_local_did) = self_def.did().as_local()
             && let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)
-            && let Some(Node::Item(x)) = cx.tcx.hir().find(self_id)
+            && let Some(Node::Item(x)) = cx.tcx.opt_hir_node(self_id)
             && let type_name = x.ident.name.as_str().to_lowercase()
             && (impl_item.ident.name.as_str() == type_name
                 || impl_item.ident.name.as_str().replace('_', "") == type_name)
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
index 268c0c1b2df..8eab3f5874e 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
             // Check for more than one binary operation in the implemented function
             // Linting when multiple operations are involved can result in false positives
             && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id
-            && let hir::Node::ImplItem(impl_item) = cx.tcx.hir().get_by_def_id(parent_fn)
+            && let hir::Node::ImplItem(impl_item) = cx.tcx.hir_node_by_def_id(parent_fn)
             && let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind
             && let body = cx.tcx.hir().body(body_id)
             && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 8e890b4df88..81efec65343 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -321,7 +321,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
         _: Span,
         def_id: LocalDefId,
     ) {
-        let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx.tcx.hir().find_by_def_id(
+        let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(
             cx.tcx
                 .hir()
                 .get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id))
@@ -368,8 +368,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
             ImplItemKind::Const(ty, _) => {
                 let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx
                     .tcx
-                    .hir()
-                    .find_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id)
+                    .opt_hir_node_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id)
                 {
                     matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
                 } else {
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs b/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs
index ed4d87ef8f8..333ea0c82df 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs
@@ -82,7 +82,7 @@ impl LateLintPass<'_> for UnnecessaryStruct {
 
 fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     if let Some(hir_id) = path_to_local(expr)
-        && let Node::Pat(pat) = cx.tcx.hir().get(hir_id)
+        && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
     {
         matches!(pat.kind, PatKind::Binding(BindingAnnotation::MUT, ..))
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 2ab24f70ae0..2e0a0f6cb3e 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -281,7 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                     }
 
                     if let Some(id) = path_to_local(recv)
-                        && let Node::Pat(pat) = cx.tcx.hir().get(id)
+                        && let Node::Pat(pat) = cx.tcx.hir_node(id)
                         && let PatKind::Binding(ann, ..) = pat.kind
                         && ann != BindingAnnotation::MUT
                     {
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 70ca1b206b4..31a81a52497 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -218,7 +218,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
         ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
             Res::Local(hir_id) => {
                 let parent_id = cx.tcx.hir().parent_id(hir_id);
-                if let Some(Node::Local(Local { init: Some(init), .. })) = cx.tcx.hir().find(parent_id) {
+                if let Some(Node::Local(Local { init: Some(init), .. })) = cx.tcx.hir_node(parent_id) {
                     path_to_matched_type(cx, init)
                 } else {
                     None
diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
index fba3808261a..b36c4ef91dc 100644
--- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
+++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
@@ -74,7 +74,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues {
 fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool {
     let parent_id = cx.tcx.hir().get_parent_item(hir_id);
     let second_parent_id = cx.tcx.hir().get_parent_item(parent_id.into()).def_id;
-    if let Some(Node::Item(item)) = cx.tcx.hir().find_by_def_id(second_parent_id) {
+    if let Some(Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(second_parent_id) {
         if let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind {
             return true;
         }
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 3bac0626f88..3f68b6d75b5 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -269,7 +269,7 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI
         FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")),
         FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, body.value).1),
     };
-    let start_pat = match tcx.hir().get(hir_id) {
+    let start_pat = match tcx.hir_node(hir_id) {
         Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => {
             if vis_span.is_empty() {
                 start_pat
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 35a8a7920a9..727f93c8327 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -531,7 +531,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                         kind: ExprKind::Lit(_),
                         span,
                         ..
-                    }) = self.lcx.tcx.hir().get(body_id.hir_id)
+                    }) = self.lcx.tcx.hir_node(body_id.hir_id)
                     && is_direct_expn_of(*span, "cfg").is_some()
                 {
                     return None;
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index fa56e5b0ba2..7562961538e 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -49,7 +49,6 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
     #[expect(clippy::disallowed_methods)]
     cx.struct_span_lint(lint, sp, msg.to_string(), |diag| {
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -90,7 +89,6 @@ pub fn span_lint_and_help<T: LintContext>(
             diag.help(help.to_string());
         }
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -134,7 +132,6 @@ pub fn span_lint_and_note<T: LintContext>(
             diag.note(note);
         }
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -152,7 +149,6 @@ where
     cx.struct_span_lint(lint, sp, msg.to_string(), |diag| {
         f(diag);
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -160,7 +156,6 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s
     #[expect(clippy::disallowed_methods)]
     cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| {
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -176,7 +171,6 @@ pub fn span_lint_hir_and_then(
     cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| {
         f(diag);
         docs_link(diag, lint);
-        diag
     });
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index f3b63f1cdcf..70a3c6f82c1 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -176,10 +176,10 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
 /// canonical binding `HirId`.
 pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
     let hir = cx.tcx.hir();
-    if let Some(Node::Pat(pat)) = hir.find(hir_id)
+    if let Some(Node::Pat(pat)) = cx.tcx.opt_hir_node(hir_id)
         && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..))
         && let parent = hir.parent_id(hir_id)
-        && let Some(Node::Local(local)) = hir.find(parent)
+        && let Some(Node::Local(local)) = cx.tcx.opt_hir_node(parent)
     {
         return local.init;
     }
@@ -563,7 +563,7 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb
     let hir = tcx.hir();
 
     let root_mod;
-    let item_kind = match hir.find_by_def_id(local_id) {
+    let item_kind = match tcx.opt_hir_node_by_def_id(local_id) {
         Some(Node::Crate(r#mod)) => {
             root_mod = ItemKind::Mod(r#mod);
             &root_mod
@@ -712,7 +712,7 @@ pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, def_id: LocalDefId) ->
     let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
     let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
     if parent_impl != hir::CRATE_OWNER_ID
-        && let hir::Node::Item(item) = cx.tcx.hir().get_by_def_id(parent_impl.def_id)
+        && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id)
         && let hir::ItemKind::Impl(impl_) = &item.kind
     {
         return impl_.of_trait.as_ref();
@@ -1242,7 +1242,7 @@ pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
 /// Gets the name of the item the expression is in, if available.
 pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
     let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id).def_id;
-    match cx.tcx.hir().find_by_def_id(parent_id) {
+    match cx.tcx.opt_hir_node_by_def_id(parent_id) {
         Some(
             Node::Item(Item { ident, .. })
             | Node::TraitItem(TraitItem { ident, .. })
@@ -1319,7 +1319,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
     let map = &cx.tcx.hir();
     let enclosing_node = map
         .get_enclosing_scope(hir_id)
-        .and_then(|enclosing_id| map.find(enclosing_id));
+        .and_then(|enclosing_id| cx.tcx.opt_hir_node(enclosing_id));
     enclosing_node.and_then(|node| match node {
         Node::Block(block) => Some(block),
         Node::Item(&Item {
@@ -2691,7 +2691,7 @@ impl<'tcx> ExprUseNode<'tcx> {
                 if let Some(Node::Expr(Expr {
                     kind: ExprKind::Closure(c),
                     ..
-                })) = cx.tcx.hir().find(hir_id)
+                })) = cx.tcx.opt_hir_node(hir_id)
                 {
                     match c.fn_decl.output {
                         FnRetTy::DefaultReturn(_) => None,
@@ -2757,7 +2757,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Optio
     walk_to_expr_usage(cx, e, &mut |parent, child_id| {
         // LocalTableInContext returns the wrong lifetime, so go use `expr_adjustments` instead.
         if adjustments.is_empty()
-            && let Node::Expr(e) = cx.tcx.hir().get(child_id)
+            && let Node::Expr(e) = cx.tcx.hir_node(child_id)
         {
             adjustments = cx.typeck_results().expr_adjustments(e);
         }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 055671afd14..5d53a4d28f2 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2543,10 +2543,10 @@ impl<'test> TestCx<'test> {
                 rustc.args(&["-Zpolonius"]);
             }
             Some(CompareMode::NextSolver) => {
-                rustc.args(&["-Ztrait-solver=next"]);
+                rustc.args(&["-Znext-solver"]);
             }
             Some(CompareMode::NextSolverCoherence) => {
-                rustc.args(&["-Ztrait-solver=next-coherence"]);
+                rustc.args(&["-Znext-solver=coherence"]);
             }
             Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => {
                 rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]);
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 504b6bd140e..8390309889d 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -144,7 +144,7 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
                             // Otherwise it may cause unexpected behaviours and ICEs
                             // (https://github.com/rust-lang/rust/issues/86261).
                             let is_reachable_non_generic = matches!(
-                                tcx.hir().get(tcx.local_def_id_to_hir_id(local_def_id)),
+                                tcx.hir_node_by_def_id(local_def_id),
                                 Node::Item(&hir::Item {
                                     kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..),
                                     ..
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index ef394b16310..e0f59144975 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -512,7 +512,7 @@ pub fn report_msg<'tcx>(
         }
     }
 
-    handler.emit_diagnostic(&mut err);
+    handler.emit_diagnostic(err);
 }
 
 impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.rs b/src/tools/miri/tests/fail/extern-type-field-offset.rs
new file mode 100644
index 00000000000..139405fc374
--- /dev/null
+++ b/src/tools/miri/tests/fail/extern-type-field-offset.rs
@@ -0,0 +1,29 @@
+#![feature(extern_types)]
+
+extern "C" {
+    type Opaque;
+}
+
+struct Newtype(Opaque);
+
+struct S {
+    i: i32,
+    j: i32,
+    a: Newtype,
+}
+
+fn main() {
+    let buf = [0i32; 4];
+
+    let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) };
+    // Projecting to the newtype works, because it is always at offset 0.
+    let _field = &x.0;
+
+    let x: &S = unsafe { &*(&buf as *const _ as *const S) };
+    // Accessing sized fields is perfectly fine, even at non-zero offsets.
+    let _field = &x.i;
+    let _field = &x.j;
+    // This needs to compute the field offset, but we don't know the type's alignment,
+    // so this panics.
+    let _field = &x.a; //~ERROR: does not have a known offset
+}
diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.stderr b/src/tools/miri/tests/fail/extern-type-field-offset.stderr
new file mode 100644
index 00000000000..cbbf1b38361
--- /dev/null
+++ b/src/tools/miri/tests/fail/extern-type-field-offset.stderr
@@ -0,0 +1,14 @@
+error: unsupported operation: `extern type` does not have a known offset
+  --> $DIR/extern-type-field-offset.rs:LL:CC
+   |
+LL |     let _field = &x.a;
+   |                  ^^^^ `extern type` does not have a known offset
+   |
+   = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/extern-type-field-offset.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs b/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs
new file mode 100644
index 00000000000..bb73c26c18a
--- /dev/null
+++ b/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs
@@ -0,0 +1,21 @@
+// run-pass
+use std::ptr::addr_of;
+
+// When the unsized tail is a `dyn Trait`, its alignments is only dynamically known. This means the
+// packed(2) needs to be applied at runtime: the actual alignment of the field is `min(2,
+// usual_alignment)`. Here we check that we do this right by comparing size, alignment, and field
+// offset before and after unsizing.
+fn main() {
+    #[repr(C, packed(2))]
+    struct Packed<T: ?Sized>(u8, core::mem::ManuallyDrop<T>);
+
+    let p = Packed(0, core::mem::ManuallyDrop::new(1));
+    let p: &Packed<usize> = &p;
+    let sized = (core::mem::size_of_val(p), core::mem::align_of_val(p));
+    let sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) };
+    let p: &Packed<dyn Send> = p;
+    let un_sized = (core::mem::size_of_val(p), core::mem::align_of_val(p));
+    let un_sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) };
+    assert_eq!(sized, un_sized);
+    assert_eq!(sized_offset, un_sized_offset);
+}
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 0573df9de2f..06f9c4c6243 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -284,10 +284,8 @@ impl ParseSess {
 // Methods that should be restricted within the parse module.
 impl ParseSess {
     pub(super) fn emit_diagnostics(&self, diagnostics: Vec<Diagnostic>) {
-        for mut diagnostic in diagnostics {
-            self.parse_sess
-                .span_diagnostic
-                .emit_diagnostic(&mut diagnostic);
+        for diagnostic in diagnostics {
+            self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic);
         }
     }
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index b38d5436477..3bfe811b58e 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -211,7 +211,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "crossbeam-epoch",
     "crossbeam-utils",
     "crypto-common",
-    "cstr",
     "darling",
     "darling_core",
     "darling_macro",
@@ -255,7 +254,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "icu_provider_macros",
     "ident_case",
     "indexmap",
-    "instant",
     "intl-memoizer",
     "intl_pluralrules",
     "is-terminal",
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 40149f8f1c3..dfa386b49de 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 const ISSUES_ENTRY_LIMIT: usize = 1852;
-const ROOT_ENTRY_LIMIT: usize = 866;
+const ROOT_ENTRY_LIMIT: usize = 867;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/assembly/x86-stack-probes.rs b/tests/assembly/stack-probes.rs
index 64a4efc0e18..6466df3ff7d 100644
--- a/tests/assembly/x86-stack-probes.rs
+++ b/tests/assembly/stack-probes.rs
@@ -1,10 +1,12 @@
-// revisions: x86_64 i686
+// revisions: x86_64 i686 aarch64
 // assembly-output: emit-asm
-//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
 //[x86_64] needs-llvm-components: x86
-//[i686] compile-flags: --target i686-unknown-linux-gnu
+//[i686] compile-flags: --target i686-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
 //[i686] needs-llvm-components: x86
-// compile-flags: -C llvm-args=-x86-asm-syntax=intel
+//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64] needs-llvm-components: aarch64
+//[aarch64] min-llvm-version: 18
 
 #![feature(no_core, lang_items)]
 #![crate_type = "lib"]
@@ -28,6 +30,7 @@ pub fn small_stack_probe(x: u8, f: fn(&mut [u8; 8192])) {
     // CHECK-NOT: __rust_probestack
     // x86_64: sub rsp, 4096
     // i686: sub esp, 4096
+    // aarch64: sub sp, sp, #1, lsl #12
     f(&mut [x; 8192]);
 }
 
@@ -37,5 +40,6 @@ pub fn big_stack_probe(x: u8, f: fn(&[u8; 65536])) {
     // CHECK-NOT: __rust_probestack
     // x86_64: sub rsp, 4096
     // i686: sub esp, 4096
+    // aarch64: sub sp, sp, #1, lsl #12
     f(&mut [x; 65536]);
 }
diff --git a/tests/codegen/debug-accessibility/crate-enum.rs b/tests/codegen/debug-accessibility/crate-enum.rs
new file mode 100644
index 00000000000..eeea18dd815
--- /dev/null
+++ b/tests/codegen/debug-accessibility/crate-enum.rs
@@ -0,0 +1,26 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for crate-visibility enums.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(crate) enum CrateFooEnum {
+        A,
+        B(u32),
+        C { x: u32 },
+    }
+
+    // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooEnum"{{.*}}flags: DIFlagProtected{{.*}})
+    // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<crate_enum::module::CrateFooEnum>"{{.*}}flags: DIFlagProtected{{.*}})
+    pub fn use_everything() {
+        black_box(CrateFooEnum::A);
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/crate-struct.rs b/tests/codegen/debug-accessibility/crate-struct.rs
new file mode 100644
index 00000000000..68d126a3478
--- /dev/null
+++ b/tests/codegen/debug-accessibility/crate-struct.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for crate-visibility structs.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(crate) struct CrateFooStruct {
+        x: u32,
+    }
+
+    // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooStruct"{{.*}}flags: DIFlagProtected{{.*}})
+
+    pub fn use_everything() {
+        black_box(CrateFooStruct { x: 2 });
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/private-enum.rs b/tests/codegen/debug-accessibility/private-enum.rs
new file mode 100644
index 00000000000..7f81026ddec
--- /dev/null
+++ b/tests/codegen/debug-accessibility/private-enum.rs
@@ -0,0 +1,21 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for private enums.
+
+use std::hint::black_box;
+
+enum PrivateFooEnum {
+    A,
+    B(u32),
+    C { x: u32 },
+}
+
+// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooEnum"{{.*}}flags: DIFlagPrivate{{.*}})
+// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<private_enum::PrivateFooEnum>"{{.*}}flags: DIFlagPrivate{{.*}})
+
+fn main() {
+    black_box(PrivateFooEnum::A);
+}
diff --git a/tests/codegen/debug-accessibility/private-struct.rs b/tests/codegen/debug-accessibility/private-struct.rs
new file mode 100644
index 00000000000..43b260f9024
--- /dev/null
+++ b/tests/codegen/debug-accessibility/private-struct.rs
@@ -0,0 +1,17 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for private structs.
+
+use std::hint::black_box;
+
+struct PrivateFooStruct {
+    x: u32,
+}
+
+// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooStruct"{{.*}}flags: DIFlagPrivate{{.*}})
+
+fn main() {
+    black_box(PrivateFooStruct { x: 1 });
+}
diff --git a/tests/codegen/debug-accessibility/public-enum.rs b/tests/codegen/debug-accessibility/public-enum.rs
new file mode 100644
index 00000000000..29ae5fd6421
--- /dev/null
+++ b/tests/codegen/debug-accessibility/public-enum.rs
@@ -0,0 +1,21 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for types and their fields.
+
+use std::hint::black_box;
+
+pub enum PublicFooEnum {
+    A,
+    B(u32),
+    C { x: u32 },
+}
+
+// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooEnum"{{.*}}flags: DIFlagPublic{{.*}})
+// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<public_enum::PublicFooEnum>"{{.*}}flags: DIFlagPublic{{.*}})
+
+fn main() {
+    black_box(PublicFooEnum::A);
+}
diff --git a/tests/codegen/debug-accessibility/public-struct.rs b/tests/codegen/debug-accessibility/public-struct.rs
new file mode 100644
index 00000000000..e7cd9b40d09
--- /dev/null
+++ b/tests/codegen/debug-accessibility/public-struct.rs
@@ -0,0 +1,17 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for public structs.
+
+use std::hint::black_box;
+
+pub struct PublicFooStruct {
+    x: u32,
+}
+
+// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooStruct"{{.*}}flags: DIFlagPublic{{.*}})
+
+fn main() {
+    black_box(PublicFooStruct { x: 4 });
+}
diff --git a/tests/codegen/debug-accessibility/struct-fields.rs b/tests/codegen/debug-accessibility/struct-fields.rs
new file mode 100644
index 00000000000..76831bdc6c6
--- /dev/null
+++ b/tests/codegen/debug-accessibility/struct-fields.rs
@@ -0,0 +1,30 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for struct fields.
+
+mod module {
+    use std::hint::black_box;
+
+    struct StructFields {
+        a: u32,
+        pub(crate) b: u32,
+        pub(super) c: u32,
+        pub d: u32,
+    }
+
+    // CHECK: [[StructFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "StructFields"{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: [[StructFields]]{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: [[StructFields]]{{.*}}flags: DIFlagPublic{{.*}})
+
+    pub fn use_everything() {
+        black_box(StructFields { a: 1, b: 2, c: 3, d: 4 });
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/super-enum.rs b/tests/codegen/debug-accessibility/super-enum.rs
new file mode 100644
index 00000000000..9d83fb45bd0
--- /dev/null
+++ b/tests/codegen/debug-accessibility/super-enum.rs
@@ -0,0 +1,27 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for super-visibility enums.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(super) enum SuperFooEnum {
+        A,
+        B(u32),
+        C { x: u32 },
+    }
+
+    // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooEnum"{{.*}}flags: DIFlagProtected{{.*}})
+    // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<super_enum::module::SuperFooEnum>"{{.*}}flags: DIFlagProtected{{.*}})
+
+    pub fn use_everything() {
+        black_box(SuperFooEnum::A);
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/super-struct.rs b/tests/codegen/debug-accessibility/super-struct.rs
new file mode 100644
index 00000000000..481006c3965
--- /dev/null
+++ b/tests/codegen/debug-accessibility/super-struct.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for super-visibility structs.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(super) struct SuperFooStruct {
+        x: u32,
+    }
+
+    // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooStruct"{{.*}}flags: DIFlagProtected{{.*}})
+
+    pub fn use_everything() {
+        black_box(SuperFooStruct { x: 3 });
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/tuple-fields.rs b/tests/codegen/debug-accessibility/tuple-fields.rs
new file mode 100644
index 00000000000..1163ba2c7c3
--- /dev/null
+++ b/tests/codegen/debug-accessibility/tuple-fields.rs
@@ -0,0 +1,24 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for tuple struct fields.
+
+mod module {
+    use std::hint::black_box;
+
+    struct TupleFields(u32, pub(crate) u32, pub(super) u32, pub u32);
+
+    // CHECK: [[TupleFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TupleFields"{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: [[TupleFields]]{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__2", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__3", scope: [[TupleFields]]{{.*}}flags: DIFlagPublic{{.*}})
+    pub fn use_everything() {
+        black_box(TupleFields(1, 2, 3, 4));
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/default-hidden-visibility.rs b/tests/codegen/default-hidden-visibility.rs
new file mode 100644
index 00000000000..9e5e545f0d9
--- /dev/null
+++ b/tests/codegen/default-hidden-visibility.rs
@@ -0,0 +1,31 @@
+// Verifies that `Session::default_hidden_visibility` is affected when using the related cmdline
+// flag.  This is a regression test for https://github.com/rust-lang/compiler-team/issues/656.  See
+// also https://github.com/rust-lang/rust/issues/73295 and
+// https://github.com/rust-lang/rust/issues/37530.
+
+// revisions:DEFAULT YES NO
+//[YES] compile-flags: -Zdefault-hidden-visibility=yes
+//[NO]  compile-flags: -Zdefault-hidden-visibility=no
+
+// The test scenario is specifically about visibility of symbols exported out of dynamically linked
+// libraries.
+#![crate_type = "dylib"]
+
+// The test scenario needs to use a Rust-public, but non-explicitly-exported symbol
+// (e.g. the test doesn't use `#[no_mangle]`, because currently it implies that
+// the symbol should be exported;  we don't want that - we want to test the *default*
+// export setting instead).
+#[used]
+pub static tested_symbol: [u8; 6] = *b"foobar";
+
+// Exact LLVM IR differs depending on the target triple (e.g. `hidden constant`
+// vs `internal constant` vs `constant`).  Because of this, we only apply the
+// specific test expectations below to one specific target triple.  If needed,
+// additional targets can be covered by adding copies of this test file with
+// a different `only-X` directive.
+//
+//     only-x86_64-unknown-linux-gnu
+
+// DEFAULT: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant
+// YES:     @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = hidden constant
+// NO:      @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
index 7b1fb320894..e573b7d21bd 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
@@ -21,7 +21,7 @@ extern "platform-intrinsic" {
 #[no_mangle]
 pub unsafe fn load_f32x2(mask: Vec2<i32>, pointer: *const f32,
                          values: Vec2<f32>) -> Vec2<f32> {
-    // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x float> {{.*}})
+    // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> {{.*}}, <2 x float> {{.*}})
     simd_masked_load(mask, pointer, values)
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
index d8a37020f23..91656622216 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
@@ -20,7 +20,7 @@ extern "platform-intrinsic" {
 // CHECK-LABEL: @store_f32x2
 #[no_mangle]
 pub unsafe fn store_f32x2(mask: Vec2<i32>, pointer: *mut f32, values: Vec2<f32>) {
-    // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 {{.*}}, <2 x i1> {{.*}})
+    // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> {{.*}})
     simd_masked_store(mask, pointer, values)
 }
 
diff --git a/tests/codegen/stack-probes-inline.rs b/tests/codegen/stack-probes-inline.rs
index 058c363969f..34027e91850 100644
--- a/tests/codegen/stack-probes-inline.rs
+++ b/tests/codegen/stack-probes-inline.rs
@@ -2,7 +2,9 @@
 // or `StackProbeType::InlineOrCall` when running on newer LLVM.
 
 // compile-flags: -C no-prepopulate-passes
-// revisions: powerpc powerpc64 powerpc64le s390x i686 x86_64
+// revisions: aarch64 powerpc powerpc64 powerpc64le s390x i686 x86_64
+//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64] needs-llvm-components: aarch64
 //[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
 //[powerpc] needs-llvm-components: powerpc
 //[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map
index e4354a1af87..6bdcca40ed6 100644
--- a/tests/coverage/async.cov-map
+++ b/tests/coverage/async.cov-map
@@ -1,20 +1,20 @@
 Function name: async::c
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 05, 01, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 19]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 25)
 
 Function name: async::c::{closure#0}
-Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 05, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02]
+Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 07, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 5, 25) to (start + 1, 14)
+- Code(Counter(0)) at (prev + 7, 25) to (start + 1, 14)
 - Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c0 - c1)
@@ -22,136 +22,84 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: async::d
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 14]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 20)
 
 Function name: async::d::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 14, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 14, 00, 19]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 13, 20) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 15, 20) to (start + 0, 25)
 
 Function name: async::e (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 01, 00, 14]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 15, 1) to (start + 0, 20)
+- Code(Zero) at (prev + 17, 1) to (start + 0, 20)
 
 Function name: async::e::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 14, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 14, 00, 19]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 15, 20) to (start + 0, 25)
-
-Function name: async::executor::block_on::<core::pin::Pin<&mut async::i::{closure#0}>>
-Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 6e, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 3
-- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 110, 5) to (start + 10, 54)
-- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35)
-    = ((c0 + c1) - c1)
-- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73)
-    = (c0 + c1)
-- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26)
-    = ((c0 + c1) - c1)
-- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
-    = ((c0 + c1) - c1)
-
-Function name: async::executor::block_on::VTABLE::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 72, 11, 00, 31]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 114, 17) to (start + 0, 49)
-
-Function name: async::executor::block_on::VTABLE::{closure#1}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 73, 11, 00, 31]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 115, 17) to (start + 0, 49)
-
-Function name: async::executor::block_on::VTABLE::{closure#2}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 74, 11, 00, 31]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 116, 17) to (start + 0, 49)
-
-Function name: async::executor::block_on::VTABLE::{closure#3}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 75, 11, 00, 13]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 117, 17) to (start + 0, 19)
+- Code(Zero) at (prev + 17, 20) to (start + 0, 25)
 
 Function name: async::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20)
 
 Function name: async::f::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 14, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 20) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25)
 
 Function name: async::foo (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 01, 00, 1e]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 19, 1) to (start + 0, 30)
+- Code(Zero) at (prev + 21, 1) to (start + 0, 30)
 
 Function name: async::foo::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 1e, 00, 2d]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 1e, 00, 2d]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 19, 30) to (start + 0, 45)
+- Code(Zero) at (prev + 21, 30) to (start + 0, 45)
 
 Function name: async::g
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 17]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 23)
 
 Function name: async::g::{closure#0} (unused)
-Raw bytes (69): 0x[01, 01, 00, 0d, 00, 15, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (69): 0x[01, 01, 00, 0d, 00, 17, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 13
-- Code(Zero) at (prev + 21, 23) to (start + 1, 12)
+- Code(Zero) at (prev + 23, 23) to (start + 1, 12)
 - Code(Zero) at (prev + 2, 9) to (start + 0, 10)
 - Code(Zero) at (prev + 0, 14) to (start + 0, 17)
 - Code(Zero) at (prev + 0, 18) to (start + 0, 23)
@@ -166,20 +114,20 @@ Number of file 0 mappings: 13
 - Code(Zero) at (prev + 2, 1) to (start + 0, 2)
 
 Function name: async::h
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 00, 16]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 00, 16]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 22)
 
 Function name: async::h::{closure#0} (unused)
-Raw bytes (44): 0x[01, 01, 00, 08, 00, 1d, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 00, 1f, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 8
-- Code(Zero) at (prev + 29, 22) to (start + 3, 12)
+- Code(Zero) at (prev + 31, 22) to (start + 3, 12)
 - Code(Zero) at (prev + 4, 9) to (start + 0, 10)
 - Code(Zero) at (prev + 0, 14) to (start + 0, 19)
 - Code(Zero) at (prev + 0, 20) to (start + 0, 25)
@@ -189,22 +137,22 @@ Number of file 0 mappings: 8
 - Code(Zero) at (prev + 2, 1) to (start + 0, 2)
 
 Function name: async::i
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 01, 00, 13]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 28, 01, 00, 13]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 38, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 19)
 
 Function name: async::i::{closure#0}
-Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
+Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 28, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(8)
 - expression 1 operands: lhs = Counter(6), rhs = Counter(7)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 38, 19) to (start + 4, 12)
+- Code(Counter(0)) at (prev + 40, 19) to (start + 4, 12)
 - Code(Counter(3)) at (prev + 5, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24)
@@ -221,14 +169,14 @@ Number of file 0 mappings: 14
     = ((c6 + c7) + c8)
 
 Function name: async::j
-Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
+Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 33, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 49, 1) to (start + 19, 12)
+- Code(Counter(0)) at (prev + 51, 1) to (start + 19, 12)
 - Code(Counter(1)) at (prev + 20, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27)
 - Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39)
@@ -240,14 +188,14 @@ Number of file 0 mappings: 9
     = ((c1 + c2) + c3)
 
 Function name: async::j::c
-Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 33, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06]
+Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 35, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 51, 5) to (start + 1, 18)
+- Code(Counter(0)) at (prev + 53, 5) to (start + 1, 18)
 - Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14)
 - Code(Expression(0, Sub)) at (prev + 10, 13) to (start + 0, 14)
     = (c0 - c1)
@@ -255,35 +203,35 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: async::j::d
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 42, 05, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 44, 05, 00, 17]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 66, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 68, 5) to (start + 0, 23)
 
 Function name: async::j::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 43, 05, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 45, 05, 00, 17]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 67, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 69, 5) to (start + 0, 23)
 
 Function name: async::k (unused)
-Raw bytes (29): 0x[01, 01, 00, 05, 00, 4b, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 4d, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 5
-- Code(Zero) at (prev + 75, 1) to (start + 1, 12)
+- Code(Zero) at (prev + 77, 1) to (start + 1, 12)
 - Code(Zero) at (prev + 2, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 2, 1) to (start + 0, 2)
 
 Function name: async::l
-Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 53, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
+Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 55, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -292,7 +240,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Expression(3, Add), rhs = Expression(0, Sub)
 - expression 3 operands: lhs = Counter(2), rhs = Counter(1)
 Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 12)
+- Code(Counter(0)) at (prev + 85, 1) to (start + 1, 12)
 - Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16)
     = (c0 - (c1 + c2))
 - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16)
@@ -301,26 +249,26 @@ Number of file 0 mappings: 5
     = ((c2 + c1) + (c0 - (c1 + c2)))
 
 Function name: async::m
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 00, 19]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 91, 1) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 93, 1) to (start + 0, 25)
 
 Function name: async::m::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 5b, 19, 00, 22]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 5d, 19, 00, 22]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 91, 25) to (start + 0, 34)
+- Code(Zero) at (prev + 93, 25) to (start + 0, 34)
 
 Function name: async::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 08, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 5f, 01, 08, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 93, 1) to (start + 8, 2)
+- Code(Counter(0)) at (prev + 95, 1) to (start + 8, 2)
 
diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage
index 07bc16c2d92..015e03d5165 100644
--- a/tests/coverage/async.coverage
+++ b/tests/coverage/async.coverage
@@ -1,6 +1,8 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |#![feature(noop_waker)]
    LL|       |#![allow(unused_assignments, dead_code)]
-   LL|       |
-   LL|       |// compile-flags: --edition=2018 -C opt-level=1
+   LL|       |// edition: 2018
+   LL|       |// compile-flags: -Copt-level=1
    LL|       |
    LL|      1|async fn c(x: u8) -> u8 {
    LL|      1|    if x == 8 {
@@ -108,32 +110,21 @@
    LL|      1|}
    LL|       |
    LL|       |mod executor {
-   LL|       |    use core::{
-   LL|       |        future::Future,
-   LL|       |        pin::Pin,
-   LL|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-   LL|       |    };
-   LL|       |
-   LL|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-   LL|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-   LL|      1|        use std::hint::unreachable_unchecked;
-   LL|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-   LL|      1|            |_| unsafe { unreachable_unchecked() }, // clone
-                              ^0
-   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake
-                              ^0
-   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-                              ^0
-   LL|      1|            |_| (),
-   LL|      1|        );
-   LL|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-   LL|      1|        let mut context = Context::from_waker(&waker);
+   LL|       |    use core::future::Future;
+   LL|       |    use core::pin::pin;
+   LL|       |    use core::task::{Context, Poll, Waker};
+   LL|       |
+   LL|       |    #[coverage(off)]
+   LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   LL|       |        let mut future = pin!(future);
+   LL|       |        let waker = Waker::noop();
+   LL|       |        let mut context = Context::from_waker(&waker);
    LL|       |
    LL|       |        loop {
-   LL|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-   LL|      1|                break val;
-   LL|      0|            }
+   LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   LL|       |                break val;
+   LL|       |            }
    LL|       |        }
-   LL|      1|    }
+   LL|       |    }
    LL|       |}
 
diff --git a/tests/coverage/async.rs b/tests/coverage/async.rs
index efd9e62d64e..abc9e5f7f64 100644
--- a/tests/coverage/async.rs
+++ b/tests/coverage/async.rs
@@ -1,6 +1,8 @@
+#![feature(coverage_attribute)]
+#![feature(noop_waker)]
 #![allow(unused_assignments, dead_code)]
-
-// compile-flags: --edition=2018 -C opt-level=1
+// edition: 2018
+// compile-flags: -Copt-level=1
 
 async fn c(x: u8) -> u8 {
     if x == 8 {
@@ -101,22 +103,14 @@ fn main() {
 }
 
 mod executor {
-    use core::{
-        future::Future,
-        pin::Pin,
-        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-    };
+    use core::future::Future;
+    use core::pin::pin;
+    use core::task::{Context, Poll, Waker};
 
+    #[coverage(off)]
     pub fn block_on<F: Future>(mut future: F) -> F::Output {
-        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-        use std::hint::unreachable_unchecked;
-        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-            |_| unsafe { unreachable_unchecked() }, // clone
-            |_| unsafe { unreachable_unchecked() }, // wake
-            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-            |_| (),
-        );
-        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut future = pin!(future);
+        let waker = Waker::noop();
         let mut context = Context::from_waker(&waker);
 
         loop {
diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map
index 23f26ee4e5f..b120e28c464 100644
--- a/tests/coverage/async2.cov-map
+++ b/tests/coverage/async2.cov-map
@@ -1,20 +1,20 @@
 Function name: async2::async_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 01, 00, 17]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 23)
 
 Function name: async2::async_func::{closure#0}
-Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 0b, 17, 03, 09, 05, 03, 0a, 02, 06, 02, 02, 06, 00, 07, 07, 01, 01, 00, 02]
+Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 0d, 17, 03, 09, 05, 03, 0a, 02, 06, 02, 02, 06, 00, 07, 07, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 11, 23) to (start + 3, 9)
+- Code(Counter(0)) at (prev + 13, 23) to (start + 3, 9)
 - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
     = (c0 - c1)
@@ -22,109 +22,37 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: async2::async_func_just_println
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 24]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 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 + 19, 1) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 36)
 
 Function name: async2::async_func_just_println::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 24, 02, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 24, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 36) to (start + 2, 2)
-
-Function name: async2::executor::block_on::<async2::async_func::{closure#0}>
-Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 3
-- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54)
-- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35)
-    = ((c0 + c1) - c1)
-- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73)
-    = (c0 + c1)
-- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26)
-    = ((c0 + c1) - c1)
-- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
-    = ((c0 + c1) - c1)
-
-Function name: async2::executor::block_on::<async2::async_func_just_println::{closure#0}>
-Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 3
-- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54)
-- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35)
-    = ((c0 + c1) - c1)
-- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73)
-    = (c0 + c1)
-- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26)
-    = ((c0 + c1) - c1)
-- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
-    = ((c0 + c1) - c1)
-
-Function name: async2::executor::block_on::VTABLE::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2b, 11, 00, 31]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 43, 17) to (start + 0, 49)
-
-Function name: async2::executor::block_on::VTABLE::{closure#1}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 11, 00, 31]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 44, 17) to (start + 0, 49)
-
-Function name: async2::executor::block_on::VTABLE::{closure#2}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2d, 11, 00, 31]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 45, 17) to (start + 0, 49)
-
-Function name: async2::executor::block_on::VTABLE::{closure#3}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2e, 11, 00, 13]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 46, 17) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 21, 36) to (start + 2, 2)
 
 Function name: async2::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 07, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 19, 01, 07, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 1) to (start + 7, 2)
+- Code(Counter(0)) at (prev + 25, 1) to (start + 7, 2)
 
 Function name: async2::non_async_func
-Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 03, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 05, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Zero
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 3, 1) to (start + 3, 9)
+- Code(Counter(0)) at (prev + 5, 1) to (start + 3, 9)
 - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
 - Code(Expression(0, Add)) at (prev + 1, 1) to (start + 0, 2)
diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage
index fcb0a3aed64..acd83de9493 100644
--- a/tests/coverage/async2.coverage
+++ b/tests/coverage/async2.coverage
@@ -1,4 +1,6 @@
-   LL|       |// compile-flags: --edition=2018
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |#![feature(noop_waker)]
+   LL|       |// edition: 2018
    LL|       |
    LL|      1|fn non_async_func() {
    LL|      1|    println!("non_async_func was covered");
@@ -32,73 +34,21 @@
    LL|      1|}
    LL|       |
    LL|       |mod executor {
-   LL|       |    use core::{
-   LL|       |        future::Future,
-   LL|       |        pin::Pin,
-   LL|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-   LL|       |    };
+   LL|       |    use core::future::Future;
+   LL|       |    use core::pin::pin;
+   LL|       |    use core::task::{Context, Poll, Waker};
    LL|       |
-   LL|      2|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-   LL|      2|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-   LL|      2|        use std::hint::unreachable_unchecked;
-   LL|      2|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-   LL|      2|            |_| unsafe { unreachable_unchecked() }, // clone
-                              ^0
-   LL|      2|            |_| unsafe { unreachable_unchecked() }, // wake
-                              ^0
-   LL|      2|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-                              ^0
-   LL|      2|            |_| (),
-   LL|      2|        );
-   LL|      2|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-   LL|      2|        let mut context = Context::from_waker(&waker);
+   LL|       |    #[coverage(off)]
+   LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   LL|       |        let mut future = pin!(future);
+   LL|       |        let waker = Waker::noop();
+   LL|       |        let mut context = Context::from_waker(&waker);
    LL|       |
    LL|       |        loop {
-   LL|      2|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-   LL|      2|                break val;
-   LL|      0|            }
+   LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   LL|       |                break val;
+   LL|       |            }
    LL|       |        }
-   LL|      2|    }
-  ------------------
-  | async2::executor::block_on::<async2::async_func::{closure#0}>:
-  |   LL|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-  |   LL|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-  |   LL|      1|        use std::hint::unreachable_unchecked;
-  |   LL|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // clone
-  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake
-  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-  |   LL|      1|            |_| (),
-  |   LL|      1|        );
-  |   LL|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-  |   LL|      1|        let mut context = Context::from_waker(&waker);
-  |   LL|       |
-  |   LL|       |        loop {
-  |   LL|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-  |   LL|      1|                break val;
-  |   LL|      0|            }
-  |   LL|       |        }
-  |   LL|      1|    }
-  ------------------
-  | async2::executor::block_on::<async2::async_func_just_println::{closure#0}>:
-  |   LL|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-  |   LL|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-  |   LL|      1|        use std::hint::unreachable_unchecked;
-  |   LL|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // clone
-  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake
-  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-  |   LL|      1|            |_| (),
-  |   LL|      1|        );
-  |   LL|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-  |   LL|      1|        let mut context = Context::from_waker(&waker);
-  |   LL|       |
-  |   LL|       |        loop {
-  |   LL|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-  |   LL|      1|                break val;
-  |   LL|      0|            }
-  |   LL|       |        }
-  |   LL|      1|    }
-  ------------------
+   LL|       |    }
    LL|       |}
 
diff --git a/tests/coverage/async2.rs b/tests/coverage/async2.rs
index 2884ff297af..393573f7dc9 100644
--- a/tests/coverage/async2.rs
+++ b/tests/coverage/async2.rs
@@ -1,4 +1,6 @@
-// compile-flags: --edition=2018
+#![feature(coverage_attribute)]
+#![feature(noop_waker)]
+// edition: 2018
 
 fn non_async_func() {
     println!("non_async_func was covered");
@@ -30,22 +32,14 @@ fn main() {
 }
 
 mod executor {
-    use core::{
-        future::Future,
-        pin::Pin,
-        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-    };
+    use core::future::Future;
+    use core::pin::pin;
+    use core::task::{Context, Poll, Waker};
 
+    #[coverage(off)]
     pub fn block_on<F: Future>(mut future: F) -> F::Output {
-        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-        use std::hint::unreachable_unchecked;
-        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-            |_| unsafe { unreachable_unchecked() }, // clone
-            |_| unsafe { unreachable_unchecked() }, // wake
-            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-            |_| (),
-        );
-        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut future = pin!(future);
+        let waker = Waker::noop();
         let mut context = Context::from_waker(&waker);
 
         loop {
diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map
index 7f8666948d9..14b1525ca0e 100644
--- a/tests/coverage/closure_macro_async.cov-map
+++ b/tests/coverage/closure_macro_async.cov-map
@@ -1,28 +1,28 @@
 Function name: closure_macro_async::load_configuration_files
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2)
+- Code(Counter(0)) at (prev + 30, 1) to (start + 2, 2)
 
 Function name: closure_macro_async::test
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 00, 2b]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 22, 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 + 33, 1) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 43)
 
 Function name: closure_macro_async::test::{closure#0}
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 21, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02]
+Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 22, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 33, 43) to (start + 1, 33)
+- Code(Counter(0)) at (prev + 34, 43) to (start + 1, 33)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
@@ -35,10 +35,10 @@ Number of file 0 mappings: 7
     = (c1 + (c0 - c1))
 
 Function name: closure_macro_async::test::{closure#0}::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 12, 00, 54]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 12, 00, 54]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 35, 18) to (start + 0, 84)
+- Code(Counter(0)) at (prev + 36, 18) to (start + 0, 84)
 
diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage
index 74247f1bc6f..2c9bd4ac97a 100644
--- a/tests/coverage/closure_macro_async.coverage
+++ b/tests/coverage/closure_macro_async.coverage
@@ -1,5 +1,6 @@
-   LL|       |// compile-flags: --edition=2018
    LL|       |#![feature(coverage_attribute)]
+   LL|       |#![feature(noop_waker)]
+   LL|       |// edition: 2018
    LL|       |
    LL|       |macro_rules! bail {
    LL|       |    ($msg:literal $(,)?) => {
@@ -46,27 +47,14 @@
    LL|       |}
    LL|       |
    LL|       |mod executor {
-   LL|       |    use core::{
-   LL|       |        future::Future,
-   LL|       |        pin::Pin,
-   LL|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-   LL|       |    };
+   LL|       |    use core::future::Future;
+   LL|       |    use core::pin::pin;
+   LL|       |    use core::task::{Context, Poll, Waker};
    LL|       |
    LL|       |    #[coverage(off)]
    LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-   LL|       |        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-   LL|       |        use std::hint::unreachable_unchecked;
-   LL|       |        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-   LL|       |            #[coverage(off)]
-   LL|       |            |_| unsafe { unreachable_unchecked() }, // clone
-   LL|       |            #[coverage(off)]
-   LL|       |            |_| unsafe { unreachable_unchecked() }, // wake
-   LL|       |            #[coverage(off)]
-   LL|       |            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-   LL|       |            #[coverage(off)]
-   LL|       |            |_| (),
-   LL|       |        );
-   LL|       |        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+   LL|       |        let mut future = pin!(future);
+   LL|       |        let waker = Waker::noop();
    LL|       |        let mut context = Context::from_waker(&waker);
    LL|       |
    LL|       |        loop {
diff --git a/tests/coverage/closure_macro_async.rs b/tests/coverage/closure_macro_async.rs
index b4275599e59..a7f0cabb4c2 100644
--- a/tests/coverage/closure_macro_async.rs
+++ b/tests/coverage/closure_macro_async.rs
@@ -1,5 +1,6 @@
-// compile-flags: --edition=2018
 #![feature(coverage_attribute)]
+#![feature(noop_waker)]
+// edition: 2018
 
 macro_rules! bail {
     ($msg:literal $(,)?) => {
@@ -45,27 +46,14 @@ fn main() {
 }
 
 mod executor {
-    use core::{
-        future::Future,
-        pin::Pin,
-        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-    };
+    use core::future::Future;
+    use core::pin::pin;
+    use core::task::{Context, Poll, Waker};
 
     #[coverage(off)]
     pub fn block_on<F: Future>(mut future: F) -> F::Output {
-        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-        use std::hint::unreachable_unchecked;
-        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-            #[coverage(off)]
-            |_| unsafe { unreachable_unchecked() }, // clone
-            #[coverage(off)]
-            |_| unsafe { unreachable_unchecked() }, // wake
-            #[coverage(off)]
-            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-            #[coverage(off)]
-            |_| (),
-        );
-        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut future = pin!(future);
+        let waker = Waker::noop();
         let mut context = Context::from_waker(&waker);
 
         loop {
diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml
new file mode 100644
index 00000000000..53f96ff086e
--- /dev/null
+++ b/tests/rustdoc-gui/globals.goml
@@ -0,0 +1,24 @@
+// Make sure search stores its data in `window`
+// It needs to use a global to avoid racing on search-index.js and search.js
+// https://github.com/rust-lang/rust/pull/118961
+
+// URL query
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa'%3Bda'%3Bds"
+wait-for: "#search-tabs"
+assert-window-property-false: {"searchIndex": null}
+assert-window-property: {"srcIndex": null}
+
+// Form input
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+write: (".search-input", "Foo")
+press-key: 'Enter'
+wait-for: "#search-tabs"
+assert-window-property-false: {"searchIndex": null}
+assert-window-property: {"srcIndex": null}
+
+// source sidebar
+go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
+click: "#src-sidebar-toggle"
+wait-for: "#src-sidebar details"
+assert-window-property-false: {"srcIndex": null}
+assert-window-property: {"searchIndex": null}
diff --git a/tests/rustdoc-gui/hide-mobile-topbar.goml b/tests/rustdoc-gui/hide-mobile-topbar.goml
new file mode 100644
index 00000000000..46eb8acfe8c
--- /dev/null
+++ b/tests/rustdoc-gui/hide-mobile-topbar.goml
@@ -0,0 +1,20 @@
+// Checks sidebar resizing stays synced with the setting
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+set-window-size: (400, 600)
+
+// Verify that the "hide" option is unchecked
+click: "#settings-menu"
+wait-for: "#settings"
+assert-css: ("#settings", {"display": "block"})
+assert-property: ("#hide-sidebar", {"checked": "false"})
+assert-css: (".mobile-topbar", {"display": "flex"})
+
+// Toggle it
+click: "#hide-sidebar"
+assert-property: ("#hide-sidebar", {"checked": "true"})
+assert-css: (".mobile-topbar", {"display": "none"})
+
+// Toggle it again
+click: "#hide-sidebar"
+assert-property: ("#hide-sidebar", {"checked": "false"})
+assert-css: (".mobile-topbar", {"display": "flex"})
diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml
index 0789d785f58..d88ebfb40d7 100644
--- a/tests/rustdoc-gui/links-color.goml
+++ b/tests/rustdoc-gui/links-color.goml
@@ -26,12 +26,12 @@ define-function: (
         assert-css: (".item-table .keyword", {"color": |keyword|}, ALL)
         // Checking sidebar elements.
         assert-css: (
-            ".sidebar-elems a:not(.current)",
+            ".sidebar-elems li:not(.current) a",
             {"color": |sidebar|, "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"},
             ALL,
         )
         assert-css: (
-            ".sidebar-elems a.current",
+            ".sidebar-elems li.current a",
             {
                 "color": |sidebar_current|,
                 "background-color": |sidebar_current_background|,
diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml
index 079d582a567..774fbcac1e2 100644
--- a/tests/rustdoc-gui/sidebar-links-color.goml
+++ b/tests/rustdoc-gui/sidebar-links-color.goml
@@ -17,10 +17,10 @@ define-function: (
         reload:
         // Struct
         assert-css: (
-            ".sidebar .block.struct a:not(.current)",
+            ".sidebar .block.struct li:not(.current) a",
             {"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"},
         )
-        move-cursor-to: ".sidebar .block.struct a:not(.current)"
+        move-cursor-to: ".sidebar .block.struct li:not(.current) a"
         assert-css: (
             ".sidebar .block.struct a:hover",
             {"color": |struct_hover|, "background-color": |struct_hover_background|},
diff --git a/tests/rustdoc-gui/sidebar-resize-setting.goml b/tests/rustdoc-gui/sidebar-resize-setting.goml
new file mode 100644
index 00000000000..2fdb2faa864
--- /dev/null
+++ b/tests/rustdoc-gui/sidebar-resize-setting.goml
@@ -0,0 +1,23 @@
+// Checks sidebar resizing stays synced with the setting
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+assert-property: (".sidebar", {"clientWidth": "200"})
+show-text: true
+
+// Verify that the "hide" option is unchecked
+click: "#settings-menu"
+wait-for: "#settings"
+assert-css: ("#settings", {"display": "block"})
+assert-property: ("#hide-sidebar", {"checked": "false"})
+press-key: "Escape"
+wait-for-css: ("#settings", {"display": "none"})
+
+drag-and-drop: ((205, 100), (5, 100))
+assert-css: (".sidebar", {"display": "none"})
+
+// Verify that the "hide" option is checked
+focus: "#settings-menu a"
+press-key: "Enter"
+wait-for-css: ("#settings", {"display": "block"})
+assert-property: ("#hide-sidebar", {"checked": "true"})
+click: "#hide-sidebar"
+wait-for-css: (".sidebar", {"display": "block"})
diff --git a/tests/rustdoc-gui/sidebar-resize-window.goml b/tests/rustdoc-gui/sidebar-resize-window.goml
new file mode 100644
index 00000000000..fb6baafda71
--- /dev/null
+++ b/tests/rustdoc-gui/sidebar-resize-window.goml
@@ -0,0 +1,37 @@
+// Checks sidebar resizing
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+set-window-size: (1280, 600)
+wait-for-property: (".sidebar", {"clientWidth": 200}, [NEAR])
+
+// resize past maximum (don't grow past 500)
+drag-and-drop: ((205, 100), (600, 100))
+wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR])
+
+// make the window small enough that the sidebar has to shrink
+set-window-size: (750, 600)
+wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR])
+
+// grow the window again to make the sidebar bigger
+set-window-size: (1280, 600)
+wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR])
+
+// make the window small enough that the sidebar has to shrink
+set-window-size: (750, 600)
+wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR])
+assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"}
+set-window-size: (400, 600)
+wait-for-css: (".sidebar", {"display": "block", "left": "-1000px"})
+assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"}
+
+// grow the window again to make the sidebar bigger
+set-window-size: (1280, 600)
+wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR])
+
+// shrink back down again, then reload the page
+// the "desired size" is a bit of remembered implicit state,
+// and rustdoc tries to minimize things like this
+set-window-size: (800, 600)
+wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR])
+reload:
+set-window-size: (1280, 600)
+wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR])
diff --git a/tests/rustdoc-gui/sidebar-resize.goml b/tests/rustdoc-gui/sidebar-resize.goml
new file mode 100644
index 00000000000..543d5d390c7
--- /dev/null
+++ b/tests/rustdoc-gui/sidebar-resize.goml
@@ -0,0 +1,28 @@
+// Checks sidebar resizing
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+assert-property: (".sidebar", {"clientWidth": "200"})
+show-text: true
+// normal resizing
+drag-and-drop: ((205, 100), (185, 100))
+assert-property: (".sidebar", {"clientWidth": "182"})
+// resize past maximum (don't grow past 500)
+drag-and-drop: ((185, 100), (600, 100))
+assert-property: (".sidebar", {"clientWidth": "500"})
+// resize past minimum (hide sidebar)
+drag-and-drop: ((501, 100), (5, 100))
+assert-property: (".sidebar", {"clientWidth": "0"})
+assert-css: (".sidebar", {"display": "none"})
+assert-local-storage: {"rustdoc-hide-sidebar": "true"}
+set-local-storage: {"rustdoc-hide-sidebar": "false"}
+
+// Now same thing, but for source code
+go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
+assert-property: (".sidebar", {"clientWidth": "49"})
+drag-and-drop: ((52, 100), (185, 100))
+assert-property: (".sidebar", {"clientWidth": "181"})
+drag-and-drop: ((185, 100), (600, 100))
+assert-property: (".sidebar", {"clientWidth": "499"})
+drag-and-drop: ((500, 100), (5, 100))
+// instead of hiding the sidebar entirely, this
+// will switch to the toggle mode
+assert-property: (".sidebar", {"clientWidth": "49"})
diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml
index 0d72e670cf4..9fc1409e86f 100644
--- a/tests/rustdoc-gui/sidebar-source-code.goml
+++ b/tests/rustdoc-gui/sidebar-source-code.goml
@@ -48,6 +48,7 @@ call-function: (
 
 // Next, desktop mode layout.
 set-window-size: (1100, 800)
+wait-for: "#src-sidebar-toggle"
 // We check that the sidebar isn't expanded and has the expected width.
 assert-css: ("nav.sidebar", {"width": "50px"})
 // We now click on the button to expand the sidebar.
@@ -58,7 +59,7 @@ assert-css: (".src-sidebar-expanded nav.sidebar a", {"font-size": "14px"})
 // We collapse the sidebar.
 click: (10, 10)
 // We ensure that the class has been removed.
-wait-for: "html:not(.expanded)"
+wait-for: "html:not(.src-sidebar-expanded)"
 assert: "nav.sidebar"
 
 // Checking that only the path to the current file is "open".
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index eff66d803d2..82b4f2e9429 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -57,7 +57,7 @@ assert-count: (".sidebar h2", 1)
 assert-text: ("#all-types", "All Items")
 assert-css: ("#all-types", {"color": "#356da4"})
 // We check that we have the crates list and that the "current" on is "test_docs".
-assert-text: (".sidebar-elems ul.crate > li > a.current", "test_docs")
+assert-text: (".sidebar-elems ul.crate > li.current > a", "test_docs")
 // And we're also supposed to have the list of items in the current module.
 assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Re-exports")
 assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Modules")
@@ -98,7 +98,7 @@ assert-property: (".sidebar", {"clientWidth": "200"})
 assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
 assert-count: (".sidebar .location", 0)
 // We check that we have the crates list and that the "current" on is now "lib2".
-assert-text: (".sidebar-elems ul.crate > li > a.current", "lib2")
+assert-text: (".sidebar-elems ul.crate > li.current > a", "lib2")
 // We now go to the "foobar" function page.
 assert-text: (".sidebar-elems > section ul.block > li:nth-child(1)", "Modules")
 assert-text: (".sidebar-elems > section ul.block > li:nth-child(2)", "Structs")
diff --git a/tests/rustdoc-gui/src/theme_css/custom-theme.css b/tests/rustdoc-gui/src/theme_css/custom-theme.css
index 260ef87f6ea..49227d9ea11 100644
--- a/tests/rustdoc-gui/src/theme_css/custom-theme.css
+++ b/tests/rustdoc-gui/src/theme_css/custom-theme.css
@@ -96,4 +96,6 @@
 	--scrape-example-help-hover-color: #000;
 	--scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1);
 	--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
+	--sidebar-resizer-hover: hsl(207, 90%, 66%);
+	--sidebar-resizer-active: hsl(207, 90%, 54%);
 }
diff --git a/tests/rustdoc-js/assoc-type.js b/tests/rustdoc-js/assoc-type.js
index 47776656e32..eec4e7a8258 100644
--- a/tests/rustdoc-js/assoc-type.js
+++ b/tests/rustdoc-js/assoc-type.js
@@ -7,16 +7,16 @@ const EXPECTED = [
         'query': 'iterator<something> -> u32',
         'correction': null,
         'others': [
-            { 'path': 'assoc_type', 'name': 'my_fn' },
             { 'path': 'assoc_type::my', 'name': 'other_fn' },
+            { 'path': 'assoc_type', 'name': 'my_fn' },
         ],
     },
     {
         'query': 'iterator<something>',
         'correction': null,
         'in_args': [
-            { 'path': 'assoc_type', 'name': 'my_fn' },
             { 'path': 'assoc_type::my', 'name': 'other_fn' },
+            { 'path': 'assoc_type', 'name': 'my_fn' },
         ],
     },
     {
@@ -26,8 +26,8 @@ const EXPECTED = [
             { 'path': 'assoc_type', 'name': 'Something' },
         ],
         'in_args': [
-            { 'path': 'assoc_type', 'name': 'my_fn' },
             { 'path': 'assoc_type::my', 'name': 'other_fn' },
+            { 'path': 'assoc_type', 'name': 'my_fn' },
         ],
     },
     // if I write an explicit binding, only it shows up
diff --git a/tests/rustdoc-js/big-result.js b/tests/rustdoc-js/big-result.js
new file mode 100644
index 00000000000..07961d196f4
--- /dev/null
+++ b/tests/rustdoc-js/big-result.js
@@ -0,0 +1,39 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'First',
+        'in_args': (function() {
+            // Generate the list of 200 items that should match.
+            const results = [];
+            function generate(lx, ly) {
+                for (const x of lx) {
+                    for (const y of ly) {
+                        results.push({
+                            'path': `big_result::${y}`,
+                            'name': x,
+                        });
+                    }
+                }
+            }
+            // Fewest parameters that still match go on top.
+            generate(
+                ['u', 'v', 'w', 'x', 'y'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            generate(
+                ['p', 'q', 'r', 's', 't'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            generate(
+                ['k', 'l', 'm', 'n', 'o'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            generate(
+                ['f', 'g', 'h', 'i', 'j'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            return results;
+        })(),
+    },
+];
diff --git a/tests/rustdoc-js/big-result.rs b/tests/rustdoc-js/big-result.rs
new file mode 100644
index 00000000000..4dfecd6aaad
--- /dev/null
+++ b/tests/rustdoc-js/big-result.rs
@@ -0,0 +1,61 @@
+#![feature(concat_idents)]
+#![allow(nonstandard_style)]
+/// Generate 250 items that all match the query, starting with the longest.
+/// Those long items should be dropped from the result set, and the short ones
+/// should be shown instead.
+macro_rules! generate {
+    ([$($x:ident),+], $y:tt, $z:tt) => {
+        $(
+            generate!(@ $x, $y, $z);
+        )+
+    };
+    (@ $x:ident , [$($y:ident),+], $z:tt) => {
+        pub struct $x;
+        $(
+            generate!(@@ $x, $y, $z);
+        )+
+    };
+    (@@ $x:ident , $y:ident, [$($z:ident: $zt:ident),+]) => {
+        impl $y {
+            pub fn $x($($z: $zt,)+) {}
+        }
+    }
+}
+
+pub struct First;
+pub struct Second;
+pub struct Third;
+pub struct Fourth;
+pub struct Fifth;
+
+generate!(
+    [a, b, c, d, e],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second, c: Third, d: Fourth, e: Fifth]
+);
+
+generate!(
+    [f, g, h, i, j],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second, c: Third, d: Fourth]
+);
+
+generate!(
+    [k, l, m, n, o],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second, c: Third]
+);
+
+generate!(
+    // reverse it, just to make sure they're alphabetized
+    // in the result set when all else is equal
+    [t, s, r, q, p],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second]
+);
+
+generate!(
+    [u, v, w, x, y],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First]
+);
diff --git a/tests/rustdoc-js/full-path-function.js b/tests/rustdoc-js/full-path-function.js
index 48be51b156f..0464f792217 100644
--- a/tests/rustdoc-js/full-path-function.js
+++ b/tests/rustdoc-js/full-path-function.js
@@ -4,16 +4,16 @@ const EXPECTED = [
     {
         'query': 'sac -> usize',
         'others': [
-            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
             { 'path': 'full_path_function::b::Sac', 'name': 'len' },
             { 'path': 'full_path_function::sac::Sac', 'name': 'len' },
+            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
         ],
     },
     {
         'query': 'b::sac -> usize',
         'others': [
-            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
             { 'path': 'full_path_function::b::Sac', 'name': 'len' },
+            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
         ],
     },
     {
diff --git a/tests/rustdoc-js/generics.js b/tests/rustdoc-js/generics.js
index ebc92ccfc05..b3ca0af3056 100644
--- a/tests/rustdoc-js/generics.js
+++ b/tests/rustdoc-js/generics.js
@@ -1,4 +1,5 @@
 // exact-check
+// ignore-order
 
 const EXPECTED = [
     {
diff --git a/tests/rustdoc-js/impl-trait.js b/tests/rustdoc-js/impl-trait.js
index 00d67d639bd..8bb3f2d3e99 100644
--- a/tests/rustdoc-js/impl-trait.js
+++ b/tests/rustdoc-js/impl-trait.js
@@ -39,8 +39,8 @@ const EXPECTED = [
             { 'path': 'impl_trait', 'name': 'Aaaaaaa' },
         ],
         'in_args': [
-            { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
             { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
+            { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
         ],
         'returned': [
             { 'path': 'impl_trait', 'name': 'bbbbbbb' },
diff --git a/tests/rustdoc-js/type-parameters.js b/tests/rustdoc-js/type-parameters.js
index e695f189bb6..e045409e507 100644
--- a/tests/rustdoc-js/type-parameters.js
+++ b/tests/rustdoc-js/type-parameters.js
@@ -1,20 +1,19 @@
 // exact-check
-// ignore-order
 
 const EXPECTED = [
     {
         query: '-> trait:Some',
         others: [
-            { path: 'foo', name: 'alef' },
             { path: 'foo', name: 'alpha' },
+            { path: 'foo', name: 'alef' },
         ],
     },
     {
         query: '-> generic:T',
         others: [
+            { path: 'foo', name: 'beta' },
             { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'alef' },
-            { path: 'foo', name: 'beta' },
         ],
     },
     {
@@ -44,38 +43,40 @@ const EXPECTED = [
     {
         query: 'Other, Other',
         others: [
-            { path: 'foo', name: 'other' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'generic:T',
         in_args: [
-            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'beta' },
-            { path: 'foo', name: 'other' },
+            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'generic:Other',
         in_args: [
-            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'beta' },
-            { path: 'foo', name: 'other' },
+            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'trait:Other',
         in_args: [
-            { path: 'foo', name: 'other' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'Other',
         in_args: [
+            // because function is called "other", it's sorted first
+            // even though it has higher type distance
             { path: 'foo', name: 'other' },
             { path: 'foo', name: 'alternate' },
         ],
diff --git a/tests/rustdoc-ui/check-cfg/check-cfg.stderr b/tests/rustdoc-ui/check-cfg/check-cfg.stderr
index d010c1f7ec6..3bca5dd0834 100644
--- a/tests/rustdoc-ui/check-cfg/check-cfg.stderr
+++ b/tests/rustdoc-ui/check-cfg/check-cfg.stderr
@@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `uniz`
 LL | #[cfg(uniz)]
    |       ^^^^ help: there is a config with a similar name: `unix`
    |
+   = help: to expect this configuration use `--check-cfg=cfg(uniz)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/rustdoc-ui/doctest/check-attr-test.stderr b/tests/rustdoc-ui/doctest/check-attr-test.stderr
index 01beba1ffc4..10f763a6f9d 100644
--- a/tests/rustdoc-ui/doctest/check-attr-test.stderr
+++ b/tests/rustdoc-ui/doctest/check-attr-test.stderr
@@ -1,4 +1,4 @@
-error: unknown attribute `compile-fail`. Did you mean `compile_fail`?
+error: unknown attribute `compile-fail`
  --> $DIR/check-attr-test.rs:5:1
   |
 5 | / /// foo
@@ -8,6 +8,7 @@ error: unknown attribute `compile-fail`. Did you mean `compile_fail`?
 9 | | /// ```
   | |_______^
   |
+  = help: there is an attribute with a similar name: `compile_fail`
   = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 note: the lint level is defined here
  --> $DIR/check-attr-test.rs:3:9
@@ -15,7 +16,7 @@ note: the lint level is defined here
 3 | #![deny(rustdoc::invalid_codeblock_attributes)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: unknown attribute `compilefail`. Did you mean `compile_fail`?
+error: unknown attribute `compilefail`
  --> $DIR/check-attr-test.rs:5:1
   |
 5 | / /// foo
@@ -25,9 +26,10 @@ error: unknown attribute `compilefail`. Did you mean `compile_fail`?
 9 | | /// ```
   | |_______^
   |
+  = help: there is an attribute with a similar name: `compile_fail`
   = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
-error: unknown attribute `comPile_fail`. Did you mean `compile_fail`?
+error: unknown attribute `comPile_fail`
  --> $DIR/check-attr-test.rs:5:1
   |
 5 | / /// foo
@@ -37,9 +39,10 @@ error: unknown attribute `comPile_fail`. Did you mean `compile_fail`?
 9 | | /// ```
   | |_______^
   |
+  = help: there is an attribute with a similar name: `compile_fail`
   = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
-error: unknown attribute `should-panic`. Did you mean `should_panic`?
+error: unknown attribute `should-panic`
   --> $DIR/check-attr-test.rs:12:1
    |
 12 | / /// bar
@@ -49,9 +52,10 @@ error: unknown attribute `should-panic`. Did you mean `should_panic`?
 16 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `should_panic`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
 
-error: unknown attribute `shouldpanic`. Did you mean `should_panic`?
+error: unknown attribute `shouldpanic`
   --> $DIR/check-attr-test.rs:12:1
    |
 12 | / /// bar
@@ -61,9 +65,10 @@ error: unknown attribute `shouldpanic`. Did you mean `should_panic`?
 16 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `should_panic`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
 
-error: unknown attribute `shOuld_panic`. Did you mean `should_panic`?
+error: unknown attribute `shOuld_panic`
   --> $DIR/check-attr-test.rs:12:1
    |
 12 | / /// bar
@@ -73,9 +78,10 @@ error: unknown attribute `shOuld_panic`. Did you mean `should_panic`?
 16 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `should_panic`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
 
-error: unknown attribute `no-run`. Did you mean `no_run`?
+error: unknown attribute `no-run`
   --> $DIR/check-attr-test.rs:19:1
    |
 19 | / /// foobar
@@ -85,9 +91,10 @@ error: unknown attribute `no-run`. Did you mean `no_run`?
 23 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `no_run`
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `norun`. Did you mean `no_run`?
+error: unknown attribute `norun`
   --> $DIR/check-attr-test.rs:19:1
    |
 19 | / /// foobar
@@ -97,9 +104,10 @@ error: unknown attribute `norun`. Did you mean `no_run`?
 23 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `no_run`
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `nO_run`. Did you mean `no_run`?
+error: unknown attribute `nO_run`
   --> $DIR/check-attr-test.rs:19:1
    |
 19 | / /// foobar
@@ -109,9 +117,10 @@ error: unknown attribute `nO_run`. Did you mean `no_run`?
 23 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `no_run`
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `test-harness`. Did you mean `test_harness`?
+error: unknown attribute `test-harness`
   --> $DIR/check-attr-test.rs:26:1
    |
 26 | / /// b
@@ -121,9 +130,10 @@ error: unknown attribute `test-harness`. Did you mean `test_harness`?
 30 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: unknown attribute `testharness`. Did you mean `test_harness`?
+error: unknown attribute `testharness`
   --> $DIR/check-attr-test.rs:26:1
    |
 26 | / /// b
@@ -133,9 +143,10 @@ error: unknown attribute `testharness`. Did you mean `test_harness`?
 30 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: unknown attribute `tesT_harness`. Did you mean `test_harness`?
+error: unknown attribute `tesT_harness`
   --> $DIR/check-attr-test.rs:26:1
    |
 26 | / /// b
@@ -145,6 +156,7 @@ error: unknown attribute `tesT_harness`. Did you mean `test_harness`?
 30 | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
 error: aborting due to 12 previous errors
diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.stderr b/tests/rustdoc-ui/doctest/check-cfg-test.stderr
index 0bfd569e381..5524f582d56 100644
--- a/tests/rustdoc-ui/doctest/check-cfg-test.stderr
+++ b/tests/rustdoc-ui/doctest/check-cfg-test.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(feature = "invalid")]
    |       ^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `test`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("invalid"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/rustdoc-ui/lints/check-attr.rs b/tests/rustdoc-ui/lints/check-attr.rs
index 0b3f7bedda5..3c06e6c076b 100644
--- a/tests/rustdoc-ui/lints/check-attr.rs
+++ b/tests/rustdoc-ui/lints/check-attr.rs
@@ -39,3 +39,20 @@ pub fn foobar() {}
 /// boo
 /// ```
 pub fn b() {}
+
+/// b
+//~^ ERROR
+///
+/// ```rust2018
+/// boo
+/// ```
+pub fn c() {}
+
+/// b
+//~^ ERROR
+//~| ERROR
+///
+/// ```rust2018 shouldpanic
+/// boo
+/// ```
+pub fn d() {}
diff --git a/tests/rustdoc-ui/lints/check-attr.stderr b/tests/rustdoc-ui/lints/check-attr.stderr
index f66e63ab727..d640125ab51 100644
--- a/tests/rustdoc-ui/lints/check-attr.stderr
+++ b/tests/rustdoc-ui/lints/check-attr.stderr
@@ -1,4 +1,4 @@
-error: unknown attribute `compile-fail`. Did you mean `compile_fail`?
+error: unknown attribute `compile-fail`
   --> $DIR/check-attr.rs:3:1
    |
 LL | / /// foo
@@ -10,6 +10,7 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `compile_fail`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 note: the lint level is defined here
   --> $DIR/check-attr.rs:1:9
@@ -17,7 +18,7 @@ note: the lint level is defined here
 LL | #![deny(rustdoc::invalid_codeblock_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: unknown attribute `compilefail`. Did you mean `compile_fail`?
+error: unknown attribute `compilefail`
   --> $DIR/check-attr.rs:3:1
    |
 LL | / /// foo
@@ -29,9 +30,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `compile_fail`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
-error: unknown attribute `comPile_fail`. Did you mean `compile_fail`?
+error: unknown attribute `comPile_fail`
   --> $DIR/check-attr.rs:3:1
    |
 LL | / /// foo
@@ -43,9 +45,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `compile_fail`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
-error: unknown attribute `should-panic`. Did you mean `should_panic`?
+error: unknown attribute `should-panic`
   --> $DIR/check-attr.rs:13:1
    |
 LL | / /// bar
@@ -57,9 +60,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `should_panic`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
 
-error: unknown attribute `shouldpanic`. Did you mean `should_panic`?
+error: unknown attribute `shouldpanic`
   --> $DIR/check-attr.rs:13:1
    |
 LL | / /// bar
@@ -71,9 +75,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `should_panic`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
 
-error: unknown attribute `sHould_panic`. Did you mean `should_panic`?
+error: unknown attribute `sHould_panic`
   --> $DIR/check-attr.rs:13:1
    |
 LL | / /// bar
@@ -85,9 +90,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `should_panic`
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
 
-error: unknown attribute `no-run`. Did you mean `no_run`?
+error: unknown attribute `no-run`
   --> $DIR/check-attr.rs:23:1
    |
 LL | / /// foobar
@@ -99,9 +105,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `no_run`
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `norun`. Did you mean `no_run`?
+error: unknown attribute `norun`
   --> $DIR/check-attr.rs:23:1
    |
 LL | / /// foobar
@@ -113,9 +120,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `no_run`
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `no_Run`. Did you mean `no_run`?
+error: unknown attribute `no_Run`
   --> $DIR/check-attr.rs:23:1
    |
 LL | / /// foobar
@@ -127,9 +135,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `no_run`
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `test-harness`. Did you mean `test_harness`?
+error: unknown attribute `test-harness`
   --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
@@ -141,9 +150,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: unknown attribute `testharness`. Did you mean `test_harness`?
+error: unknown attribute `testharness`
   --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
@@ -155,9 +165,10 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: unknown attribute `teSt_harness`. Did you mean `test_harness`?
+error: unknown attribute `teSt_harness`
   --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
@@ -169,7 +180,50 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: aborting due to 12 previous errors
+error: unknown attribute `rust2018`
+  --> $DIR/check-attr.rs:43:1
+   |
+LL | / /// b
+LL | |
+LL | | ///
+LL | | /// ```rust2018
+LL | | /// boo
+LL | | /// ```
+   | |_______^
+   |
+   = help: there is an attribute with a similar name: `edition2018`
+
+error: unknown attribute `rust2018`
+  --> $DIR/check-attr.rs:51:1
+   |
+LL | / /// b
+LL | |
+LL | |
+LL | | ///
+LL | | /// ```rust2018 shouldpanic
+LL | | /// boo
+LL | | /// ```
+   | |_______^
+   |
+   = help: there is an attribute with a similar name: `edition2018`
+
+error: unknown attribute `shouldpanic`
+  --> $DIR/check-attr.rs:51:1
+   |
+LL | / /// b
+LL | |
+LL | |
+LL | | ///
+LL | | /// ```rust2018 shouldpanic
+LL | | /// boo
+LL | | /// ```
+   | |_______^
+   |
+   = help: there is an attribute with a similar name: `should_panic`
+   = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
+
+error: aborting due to 15 previous errors
 
diff --git a/tests/rustdoc-ui/lints/check-fail.stderr b/tests/rustdoc-ui/lints/check-fail.stderr
index f05e457af64..99b01bac598 100644
--- a/tests/rustdoc-ui/lints/check-fail.stderr
+++ b/tests/rustdoc-ui/lints/check-fail.stderr
@@ -22,7 +22,7 @@ note: the lint level is defined here
 LL | #![deny(rustdoc::missing_doc_code_examples)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: unknown attribute `testharness`. Did you mean `test_harness`?
+error: unknown attribute `testharness`
   --> $DIR/check-fail.rs:8:1
    |
 LL | / //! ```rust,testharness
@@ -31,6 +31,7 @@ LL | | //! let x = 12;
 LL | | //! ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 note: the lint level is defined here
   --> $DIR/check-fail.rs:6:9
@@ -39,7 +40,7 @@ LL | #![deny(rustdoc::all)]
    |         ^^^^^^^^^^^^
    = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]`
 
-error: unknown attribute `testharness`. Did you mean `test_harness`?
+error: unknown attribute `testharness`
   --> $DIR/check-fail.rs:17:1
    |
 LL | / /// hello
@@ -50,6 +51,7 @@ LL | | /// let x = 12;
 LL | | /// ```
    | |_______^
    |
+   = help: there is an attribute with a similar name: `test_harness`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
 error: aborting due to 4 previous errors
diff --git a/tests/rustdoc/reexport-cfg.rs b/tests/rustdoc/reexport-cfg.rs
new file mode 100644
index 00000000000..a6179fad873
--- /dev/null
+++ b/tests/rustdoc/reexport-cfg.rs
@@ -0,0 +1,30 @@
+// This test ensures that only the re-export `cfg` will be displayed and that it won't
+// include `cfg`s from the previous chained items.
+
+#![crate_name = "foo"]
+#![feature(doc_auto_cfg, doc_cfg)]
+
+mod foo {
+    #[cfg(not(feature = "foo"))]
+    pub struct Bar;
+
+    #[doc(cfg(not(feature = "bar")))]
+    pub struct Bar2;
+}
+
+// @has 'foo/index.html'
+// @has - '//*[@class="item-name"]' 'BabarNon-lie'
+#[cfg(not(feature = "lie"))]
+pub use crate::foo::Bar as Babar;
+
+// @has - '//*[@class="item-name"]' 'Babar2Non-cake'
+#[doc(cfg(not(feature = "cake")))]
+pub use crate::foo::Bar2 as Babar2;
+
+// @has - '//*[@class="item-table"]/li' 'pub use crate::Babar as Elephant;Non-robot'
+#[cfg(not(feature = "robot"))]
+pub use crate::Babar as Elephant;
+
+// @has - '//*[@class="item-table"]/li' 'pub use crate::Babar2 as Elephant2;Non-cat'
+#[doc(cfg(not(feature = "cat")))]
+pub use crate::Babar2 as Elephant2;
diff --git a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs b/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs
index a79d05904e3..c81c654a20e 100644
--- a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs
+++ b/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs
@@ -27,7 +27,7 @@ pub mod mod1 {
 pub mod mod2 {
     // @has - '//code' 'pub use tag::Portability;'
     // @!has - '//span' 'Deprecated'
-    // @has - '//span' 'sync'
+    // @!has - '//span' 'sync'
     pub use tag::Portability;
 }
 
@@ -35,7 +35,7 @@ pub mod mod2 {
 pub mod mod3 {
     // @has - '//code' 'pub use tag::Both;'
     // @has - '//span' 'Deprecated'
-    // @has - '//span' 'sync'
+    // @!has - '//span' 'sync'
     pub use tag::Both;
 }
 
diff --git a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs b/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs
index ff8a910f59f..423838e251b 100644
--- a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs
+++ b/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs
@@ -35,7 +35,7 @@ pub mod mod1 {
 pub mod mod2 {
     // @has - '//code' 'pub use tag::Portability;'
     // @!has - '//span' 'Experimental'
-    // @has - '//span' 'sync'
+    // @!has - '//span' 'sync'
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use tag::Portability;
 }
@@ -45,7 +45,7 @@ pub mod mod2 {
 pub mod mod3 {
     // @has - '//code' 'pub use tag::Both;'
     // @has - '//span' 'Experimental'
-    // @has - '//span' 'sync'
+    // @!has - '//span' 'sync'
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use tag::Both;
 }
diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs
index d311be5982d..ad667511332 100644
--- a/tests/ui-fulldeps/stable-mir/check_defs.rs
+++ b/tests/ui-fulldeps/stable-mir/check_defs.rs
@@ -69,7 +69,7 @@ fn extract_elem_ty(ty: Ty) -> Ty {
 
 /// Check signature and type of `Vec::<u8>::new` and its generic version.
 fn test_vec_new(instance: mir::mono::Instance) {
-    let sig = instance.fn_sig();
+    let sig = instance.ty().kind().fn_sig().unwrap().skip_binder();
     assert_matches!(sig.inputs(), &[]);
     let elem_ty = extract_elem_ty(sig.output());
     assert_matches!(elem_ty.kind(), TyKind::RigidTy(RigidTy::Uint(UintTy::U8)));
diff --git a/tests/ui/abi/stack-probes-lto.rs b/tests/ui/abi/stack-probes-lto.rs
index 7282d09706c..fb478671754 100644
--- a/tests/ui/abi/stack-probes-lto.rs
+++ b/tests/ui/abi/stack-probes-lto.rs
@@ -1,5 +1,7 @@
-// revisions: x32 x64
+// revisions: aarch64 x32 x64
 // run-pass
+//[aarch64] only-aarch64
+//[aarch64] min-llvm-version: 18
 //[x32] only-x86
 //[x64] only-x86_64
 // ignore-sgx no processes
diff --git a/tests/ui/abi/stack-probes.rs b/tests/ui/abi/stack-probes.rs
index 4b8a79a4b68..e5c7a1a6804 100644
--- a/tests/ui/abi/stack-probes.rs
+++ b/tests/ui/abi/stack-probes.rs
@@ -1,5 +1,7 @@
-// revisions: x32 x64
+// revisions: aarch64 x32 x64
 // run-pass
+//[aarch64] only-aarch64
+//[aarch64] min-llvm-version: 18
 //[x32] only-x86
 //[x64] only-x86_64
 // ignore-emscripten no processes
diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs
index 66f879c5a71..054034b4c28 100644
--- a/tests/ui/associated-inherent-types/inference.rs
+++ b/tests/ui/associated-inherent-types/inference.rs
@@ -1,7 +1,7 @@
 // Testing inference capabilities.
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout
index b0447a58261..47b39e5246d 100644
--- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout
+++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout
@@ -52,10 +52,16 @@ print-type-size     variant `Panicked`: 1024 bytes
 print-type-size         upvar `.arg`: 1024 bytes
 print-type-size type: `std::mem::ManuallyDrop<bool>`: 1 bytes, alignment: 1 bytes
 print-type-size     field `.value`: 1 bytes
+print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes
+print-type-size     field `.value`: 1 bytes
 print-type-size type: `std::mem::MaybeUninit<bool>`: 1 bytes, alignment: 1 bytes
 print-type-size     variant `MaybeUninit`: 1 bytes
 print-type-size         field `.uninit`: 0 bytes
 print-type-size         field `.value`: 1 bytes
+print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes
+print-type-size     variant `MaybeUninit`: 1 bytes
+print-type-size         field `.uninit`: 0 bytes
+print-type-size         field `.value`: 1 bytes
 print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes
 print-type-size     discriminant: 1 bytes
 print-type-size     variant `Ready`: 0 bytes
diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
index c8fd2d8f6c2..491dfcc6ae0 100644
--- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
+++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
@@ -1,6 +1,7 @@
 // run-pass
 // edition:2021
 
+#![feature(noop_waker)]
 
 use std::future::Future;
 
@@ -32,33 +33,18 @@ async fn async_main() {
 // ------------------------------------------------------------------------- //
 // Implementation Details Below...
 
-use std::pin::Pin;
+use std::pin::pin;
 use std::task::*;
 
-pub fn noop_waker() -> Waker {
-    let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE);
-
-    // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld
-    unsafe { Waker::from_raw(raw) }
-}
-
-const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
-
-unsafe fn noop_clone(_p: *const ()) -> RawWaker {
-    RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
-}
-
-unsafe fn noop(_p: *const ()) {}
-
 fn main() {
-    let mut fut = async_main();
+    let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = noop_waker();
+    let waker = Waker::noop();
     let ctx = &mut Context::from_waker(&waker);
 
     loop {
-        match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } {
+        match fut.as_mut().poll(ctx) {
             Poll::Pending => {}
             Poll::Ready(()) => break,
         }
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs
index 18b0fa4856d..f21abf012ba 100644
--- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs
+++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs
@@ -2,6 +2,7 @@
 // known-bug: #108309
 
 #![feature(min_specialization)]
+#![feature(noop_waker)]
 
 struct MyStruct;
 
@@ -35,34 +36,18 @@ async fn indirection<T>(x: T) -> &'static str {
 // ------------------------------------------------------------------------- //
 // Implementation Details Below...
 
-use std::future::Future;
-use std::pin::Pin;
+use std::pin::{pin, Pin};
 use std::task::*;
 
-pub fn noop_waker() -> Waker {
-    let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE);
-
-    // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld
-    unsafe { Waker::from_raw(raw) }
-}
-
-const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
-
-unsafe fn noop_clone(_p: *const ()) -> RawWaker {
-    RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
-}
-
-unsafe fn noop(_p: *const ()) {}
-
 fn main() {
-    let mut fut = async_main();
+    let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = noop_waker();
+    let waker = Waker::noop();
     let ctx = &mut Context::from_waker(&waker);
 
     loop {
-        match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } {
+        match fut.as_mut().poll(ctx) {
             Poll::Pending => {}
             Poll::Ready(()) => break,
         }
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
index 5e2be08623b..0560cd9c5fe 100644
--- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
+++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
@@ -1,11 +1,11 @@
 error[E0053]: method `foo` has an incompatible type for trait
-  --> $DIR/dont-project-to-specializable-projection.rs:13:5
+  --> $DIR/dont-project-to-specializable-projection.rs:14:5
    |
 LL |     default async fn foo(_: T) -> &'static str {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found future
    |
 note: type in trait
-  --> $DIR/dont-project-to-specializable-projection.rs:9:5
+  --> $DIR/dont-project-to-specializable-projection.rs:10:5
    |
 LL |     async fn foo(_: T) -> &'static str;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,13 +13,29 @@ LL |     async fn foo(_: T) -> &'static str;
               found signature `fn(_) -> impl Future<Output = &'static str>`
 
 error: async associated function in trait cannot be specialized
-  --> $DIR/dont-project-to-specializable-projection.rs:13:5
+  --> $DIR/dont-project-to-specializable-projection.rs:14:5
    |
 LL |     default async fn foo(_: T) -> &'static str {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: specialization behaves in inconsistent and surprising ways with async functions in traits, and for now is disallowed
 
-error: aborting due to 2 previous errors
+error[E0599]: no method named `poll` found for struct `Pin<&mut impl Future<Output = ()>>` in the current scope
+  --> $DIR/dont-project-to-specializable-projection.rs:50:28
+   |
+LL |         match fut.as_mut().poll(ctx) {
+   |                            ^^^^ method not found in `Pin<&mut impl Future<Output = ()>>`
+  --> $SRC_DIR/core/src/future/future.rs:LL:COL
+   |
+   = note: the method is available for `Pin<&mut impl Future<Output = ()>>` here
+   |
+   = help: items from traits can only be used if the trait is in scope
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL + use std::future::Future;
+   |
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0053`.
+Some errors have detailed explanations: E0053, E0599.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
index 95731b67ccf..8e573b512ad 100644
--- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
+++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
@@ -1,7 +1,9 @@
-error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`
+error[E0391]: cycle detected when computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`
    |
-   = note: ...which requires computing layout of `<<A as First>::Second as Second>::{opaque#0}`...
-   = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`, completing the cycle
+   = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`...
+   = note: ...which requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`...
+   = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<<<A as First>::Second as Second>::{opaque#0}>`...
+   = note: ...which again requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`, completing the cycle
    = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:6:13: 8:6}`
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
diff --git a/tests/ui/async-await/normalize-output-in-signature-deduction.rs b/tests/ui/async-await/normalize-output-in-signature-deduction.rs
index 960065a83a4..e07fe9e98ec 100644
--- a/tests/ui/async-await/normalize-output-in-signature-deduction.rs
+++ b/tests/ui/async-await/normalize-output-in-signature-deduction.rs
@@ -1,6 +1,6 @@
 // edition:2021
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
index e581e5ffda7..6097c7f1073 100644
--- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
+++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
@@ -1,7 +1,7 @@
 // revisions: current next
 //[current] known-bug: #109924
 //[next] check-pass
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // edition:2021
 
 #![feature(return_type_notation)]
diff --git a/tests/ui/auto-traits/issue-23080-2.rs b/tests/ui/auto-traits/issue-23080-2.rs
index 882b8f39384..d63cd9d5dd6 100644
--- a/tests/ui/auto-traits/issue-23080-2.rs
+++ b/tests/ui/auto-traits/issue-23080-2.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(auto_traits)]
 #![feature(negative_impls)]
diff --git a/tests/ui/check-cfg/allow-same-level.stderr b/tests/ui/check-cfg/allow-same-level.stderr
index 652efc3f591..7f0faa0700d 100644
--- a/tests/ui/check-cfg/allow-same-level.stderr
+++ b/tests/ui/check-cfg/allow-same-level.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(FALSE)]
    |       ^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(FALSE)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/cargo-feature.none.stderr b/tests/ui/check-cfg/cargo-feature.none.stderr
new file mode 100644
index 00000000000..44c8f7e3072
--- /dev/null
+++ b/tests/ui/check-cfg/cargo-feature.none.stderr
@@ -0,0 +1,31 @@
+warning: unexpected `cfg` condition name: `feature`
+  --> $DIR/cargo-feature.rs:13:7
+   |
+LL | #[cfg(feature = "serde")]
+   |       ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider defining some features in `Cargo.toml`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name: `tokio_unstable`
+  --> $DIR/cargo-feature.rs:18:7
+   |
+LL | #[cfg(tokio_unstable)]
+   |       ^^^^^^^^^^^^^^
+   |
+   = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(tokio_unstable)");` to the top of a `build.rs`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition name: `CONFIG_NVME`
+  --> $DIR/cargo-feature.rs:22:7
+   |
+LL | #[cfg(CONFIG_NVME = "m")]
+   |       ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of a `build.rs`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/check-cfg/cargo-feature.rs b/tests/ui/check-cfg/cargo-feature.rs
index ea48c6ea201..fe343d0a678 100644
--- a/tests/ui/check-cfg/cargo-feature.rs
+++ b/tests/ui/check-cfg/cargo-feature.rs
@@ -3,12 +3,25 @@
 // list of all the expected names
 //
 // check-pass
+// revisions: some none
 // rustc-env:CARGO=/usr/bin/cargo
 // compile-flags: --check-cfg=cfg() -Z unstable-options
-// error-pattern:Cargo.toml
+// [some]compile-flags: --check-cfg=cfg(feature,values("bitcode"))
+// [some]compile-flags: --check-cfg=cfg(CONFIG_NVME,values("y"))
+// [none]error-pattern:Cargo.toml
 
 #[cfg(feature = "serde")]
-//~^ WARNING unexpected `cfg` condition name
+//[none]~^ WARNING unexpected `cfg` condition name
+//[some]~^^ WARNING unexpected `cfg` condition value
 fn ser() {}
 
+#[cfg(tokio_unstable)]
+//~^ WARNING unexpected `cfg` condition name
+fn tokio() {}
+
+#[cfg(CONFIG_NVME = "m")]
+//[none]~^ WARNING unexpected `cfg` condition name
+//[some]~^^ WARNING unexpected `cfg` condition value
+fn tokio() {}
+
 fn main() {}
diff --git a/tests/ui/check-cfg/cargo-feature.some.stderr b/tests/ui/check-cfg/cargo-feature.some.stderr
new file mode 100644
index 00000000000..92d63d01534
--- /dev/null
+++ b/tests/ui/check-cfg/cargo-feature.some.stderr
@@ -0,0 +1,35 @@
+warning: unexpected `cfg` condition value: `serde`
+  --> $DIR/cargo-feature.rs:13:7
+   |
+LL | #[cfg(feature = "serde")]
+   |       ^^^^^^^^^^^^^^^^^
+   |
+   = note: expected values for `feature` are: `bitcode`
+   = help: consider adding `serde` as a feature in `Cargo.toml`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name: `tokio_unstable`
+  --> $DIR/cargo-feature.rs:18:7
+   |
+LL | #[cfg(tokio_unstable)]
+   |       ^^^^^^^^^^^^^^
+   |
+   = help: expected names are: `CONFIG_NVME`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(tokio_unstable)");` to the top of a `build.rs`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition value: `m`
+  --> $DIR/cargo-feature.rs:22:7
+   |
+LL | #[cfg(CONFIG_NVME = "m")]
+   |       ^^^^^^^^^^^^^^---
+   |                     |
+   |                     help: there is a expected value with a similar name: `"y"`
+   |
+   = note: expected values for `CONFIG_NVME` are: `y`
+   = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of a `build.rs`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/check-cfg/cargo-feature.stderr b/tests/ui/check-cfg/cargo-feature.stderr
deleted file mode 100644
index 619410a28f3..00000000000
--- a/tests/ui/check-cfg/cargo-feature.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: unexpected `cfg` condition name: `feature`
-  --> $DIR/cargo-feature.rs:10:7
-   |
-LL | #[cfg(feature = "serde")]
-   |       ^^^^^^^^^^^^^^^^^
-   |
-   = help: consider defining some features in `Cargo.toml`
-   = note: `#[warn(unexpected_cfgs)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/check-cfg/compact-names.stderr b/tests/ui/check-cfg/compact-names.stderr
index d3bfb9f7100..dfa26f5dde0 100644
--- a/tests/ui/check-cfg/compact-names.stderr
+++ b/tests/ui/check-cfg/compact-names.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(target(os = "linux", architecture = "arm"))]
    |                            ^^^^^^^^^^^^^^^^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(target_architecture, values("arm"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/compact-values.stderr b/tests/ui/check-cfg/compact-values.stderr
index 819b789c3e5..10276af4d8f 100644
--- a/tests/ui/check-cfg/compact-values.stderr
+++ b/tests/ui/check-cfg/compact-values.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(target(os = "linux", pointer_width = "X"))]
    |                            ^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_pointer_width` are: `16`, `32`, `64`
+   = help: to expect this configuration use `--check-cfg=cfg(target_pointer_width, values("X"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/concat-values.stderr b/tests/ui/check-cfg/concat-values.stderr
index da2bd7d6ad9..dec43f5bda3 100644
--- a/tests/ui/check-cfg/concat-values.stderr
+++ b/tests/ui/check-cfg/concat-values.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(my_cfg)]
    |       ^^^^^^
    |
    = note: expected values for `my_cfg` are: `bar`, `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(my_cfg)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `unk`
@@ -14,6 +16,8 @@ LL | #[cfg(my_cfg = "unk")]
    |       ^^^^^^^^^^^^^^
    |
    = note: expected values for `my_cfg` are: `bar`, `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(my_cfg, values("unk"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/check-cfg/diagnotics.cargo.stderr b/tests/ui/check-cfg/diagnotics.cargo.stderr
new file mode 100644
index 00000000000..05c52bf59fa
--- /dev/null
+++ b/tests/ui/check-cfg/diagnotics.cargo.stderr
@@ -0,0 +1,71 @@
+warning: unexpected `cfg` condition name: `featur`
+  --> $DIR/diagnotics.rs:7:7
+   |
+LL | #[cfg(featur)]
+   |       ^^^^^^ help: there is a config with a similar name: `feature`
+   |
+   = help: expected values for `feature` are: `foo`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name: `featur`
+  --> $DIR/diagnotics.rs:11:7
+   |
+LL | #[cfg(featur = "foo")]
+   |       ^^^^^^^^^^^^^^
+   |
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+help: there is a config with a similar name and value
+   |
+LL | #[cfg(feature = "foo")]
+   |       ~~~~~~~
+
+warning: unexpected `cfg` condition name: `featur`
+  --> $DIR/diagnotics.rs:15:7
+   |
+LL | #[cfg(featur = "fo")]
+   |       ^^^^^^^^^^^^^
+   |
+   = help: expected values for `feature` are: `foo`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+help: there is a config with a similar name and different values
+   |
+LL | #[cfg(feature = "foo")]
+   |       ~~~~~~~~~~~~~~~
+
+warning: unexpected `cfg` condition name: `no_value`
+  --> $DIR/diagnotics.rs:22:7
+   |
+LL | #[cfg(no_value)]
+   |       ^^^^^^^^ help: there is a config with a similar name: `no_values`
+   |
+   = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_value)");` to the top of a `build.rs`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition name: `no_value`
+  --> $DIR/diagnotics.rs:26:7
+   |
+LL | #[cfg(no_value = "foo")]
+   |       ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_value, values(\"foo\"))");` to the top of a `build.rs`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+help: there is a config with a similar name and no value
+   |
+LL | #[cfg(no_values)]
+   |       ~~~~~~~~~
+
+warning: unexpected `cfg` condition value: `bar`
+  --> $DIR/diagnotics.rs:30:7
+   |
+LL | #[cfg(no_values = "bar")]
+   |       ^^^^^^^^^--------
+   |                |
+   |                help: remove the value
+   |
+   = note: no expected value for `no_values`
+   = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_values, values(\"bar\"))");` to the top of a `build.rs`
+   = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
+
+warning: 6 warnings emitted
+
diff --git a/tests/ui/check-cfg/diagnotics.rs b/tests/ui/check-cfg/diagnotics.rs
index 45875bddc17..33073f05f69 100644
--- a/tests/ui/check-cfg/diagnotics.rs
+++ b/tests/ui/check-cfg/diagnotics.rs
@@ -1,4 +1,7 @@
 // check-pass
+// revisions: cargo rustc
+// [rustc]unset-rustc-env:CARGO
+// [cargo]rustc-env:CARGO=/usr/bin/cargo
 // compile-flags: --check-cfg=cfg(feature,values("foo")) --check-cfg=cfg(no_values) -Z unstable-options
 
 #[cfg(featur)]
diff --git a/tests/ui/check-cfg/diagnotics.rustc.stderr b/tests/ui/check-cfg/diagnotics.rustc.stderr
new file mode 100644
index 00000000000..2b1129a3920
--- /dev/null
+++ b/tests/ui/check-cfg/diagnotics.rustc.stderr
@@ -0,0 +1,74 @@
+warning: unexpected `cfg` condition name: `featur`
+  --> $DIR/diagnotics.rs:7:7
+   |
+LL | #[cfg(featur)]
+   |       ^^^^^^ help: there is a config with a similar name: `feature`
+   |
+   = help: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(featur)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name: `featur`
+  --> $DIR/diagnotics.rs:11:7
+   |
+LL | #[cfg(featur = "foo")]
+   |       ^^^^^^^^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(featur, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+help: there is a config with a similar name and value
+   |
+LL | #[cfg(feature = "foo")]
+   |       ~~~~~~~
+
+warning: unexpected `cfg` condition name: `featur`
+  --> $DIR/diagnotics.rs:15:7
+   |
+LL | #[cfg(featur = "fo")]
+   |       ^^^^^^^^^^^^^
+   |
+   = help: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(featur, values("fo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+help: there is a config with a similar name and different values
+   |
+LL | #[cfg(feature = "foo")]
+   |       ~~~~~~~~~~~~~~~
+
+warning: unexpected `cfg` condition name: `no_value`
+  --> $DIR/diagnotics.rs:22:7
+   |
+LL | #[cfg(no_value)]
+   |       ^^^^^^^^ help: there is a config with a similar name: `no_values`
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(no_value)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition name: `no_value`
+  --> $DIR/diagnotics.rs:26:7
+   |
+LL | #[cfg(no_value = "foo")]
+   |       ^^^^^^^^^^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(no_value, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+help: there is a config with a similar name and no value
+   |
+LL | #[cfg(no_values)]
+   |       ~~~~~~~~~
+
+warning: unexpected `cfg` condition value: `bar`
+  --> $DIR/diagnotics.rs:30:7
+   |
+LL | #[cfg(no_values = "bar")]
+   |       ^^^^^^^^^--------
+   |                |
+   |                help: remove the value
+   |
+   = note: no expected value for `no_values`
+   = help: to expect this configuration use `--check-cfg=cfg(no_values, values("bar"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+
+warning: 6 warnings emitted
+
diff --git a/tests/ui/check-cfg/diagnotics.stderr b/tests/ui/check-cfg/diagnotics.stderr
deleted file mode 100644
index 31c0db03a7e..00000000000
--- a/tests/ui/check-cfg/diagnotics.stderr
+++ /dev/null
@@ -1,61 +0,0 @@
-warning: unexpected `cfg` condition name: `featur`
-  --> $DIR/diagnotics.rs:4:7
-   |
-LL | #[cfg(featur)]
-   |       ^^^^^^ help: there is a config with a similar name: `feature`
-   |
-   = help: expected values for `feature` are: `foo`
-   = note: `#[warn(unexpected_cfgs)]` on by default
-
-warning: unexpected `cfg` condition name: `featur`
-  --> $DIR/diagnotics.rs:8:7
-   |
-LL | #[cfg(featur = "foo")]
-   |       ^^^^^^^^^^^^^^
-   |
-help: there is a config with a similar name and value
-   |
-LL | #[cfg(feature = "foo")]
-   |       ~~~~~~~
-
-warning: unexpected `cfg` condition name: `featur`
-  --> $DIR/diagnotics.rs:12:7
-   |
-LL | #[cfg(featur = "fo")]
-   |       ^^^^^^^^^^^^^
-   |
-   = help: expected values for `feature` are: `foo`
-help: there is a config with a similar name and different values
-   |
-LL | #[cfg(feature = "foo")]
-   |       ~~~~~~~~~~~~~~~
-
-warning: unexpected `cfg` condition name: `no_value`
-  --> $DIR/diagnotics.rs:19:7
-   |
-LL | #[cfg(no_value)]
-   |       ^^^^^^^^ help: there is a config with a similar name: `no_values`
-
-warning: unexpected `cfg` condition name: `no_value`
-  --> $DIR/diagnotics.rs:23:7
-   |
-LL | #[cfg(no_value = "foo")]
-   |       ^^^^^^^^^^^^^^^^
-   |
-help: there is a config with a similar name and no value
-   |
-LL | #[cfg(no_values)]
-   |       ~~~~~~~~~
-
-warning: unexpected `cfg` condition value: `bar`
-  --> $DIR/diagnotics.rs:27:7
-   |
-LL | #[cfg(no_values = "bar")]
-   |       ^^^^^^^^^--------
-   |                |
-   |                help: remove the value
-   |
-   = note: no expected value for `no_values`
-
-warning: 6 warnings emitted
-
diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
index 9501c134bac..27af8212026 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `value`
@@ -16,18 +18,26 @@ LL | #[cfg(test = "value")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `feature`
   --> $DIR/exhaustive-names-values.rs:18:7
    |
 LL | #[cfg(feature = "unk")]
    |       ^^^^^^^^^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `feature`
   --> $DIR/exhaustive-names-values.rs:25:7
    |
 LL | #[cfg(feature = "std")]
    |       ^^^^^^^^^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("std"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 4 warnings emitted
 
diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr
deleted file mode 100644
index e37a222f52a..00000000000
--- a/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr
+++ /dev/null
@@ -1,33 +0,0 @@
-warning: unexpected `cfg` condition name: `unknown_key`
-  --> $DIR/exhaustive-names-values.rs:11:7
-   |
-LL | #[cfg(unknown_key = "value")]
-   |       ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
-   = note: `#[warn(unexpected_cfgs)]` on by default
-
-warning: unexpected `cfg` condition value: `value`
-  --> $DIR/exhaustive-names-values.rs:15:7
-   |
-LL | #[cfg(test = "value")]
-   |       ^^^^----------
-   |           |
-   |           help: remove the value
-   |
-   = note: no expected value for `test`
-
-warning: unexpected `cfg` condition name: `feature`
-  --> $DIR/exhaustive-names-values.rs:19:7
-   |
-LL | #[cfg(feature = "unk")]
-   |       ^^^^^^^^^^^^^^^
-
-warning: unexpected `cfg` condition name: `feature`
-  --> $DIR/exhaustive-names-values.rs:26:7
-   |
-LL | #[cfg(feature = "std")]
-   |       ^^^^^^^^^^^^^^^
-
-warning: 4 warnings emitted
-
diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
index ea204eaff1b..a5aa80ef8e5 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `value`
@@ -16,6 +18,8 @@ LL | #[cfg(test = "value")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `unk`
   --> $DIR/exhaustive-names-values.rs:18:7
@@ -24,6 +28,8 @@ LL | #[cfg(feature = "unk")]
    |       ^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `std`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 3 warnings emitted
 
diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
index ea204eaff1b..a5aa80ef8e5 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `value`
@@ -16,6 +18,8 @@ LL | #[cfg(test = "value")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `unk`
   --> $DIR/exhaustive-names-values.rs:18:7
@@ -24,6 +28,8 @@ LL | #[cfg(feature = "unk")]
    |       ^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `std`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 3 warnings emitted
 
diff --git a/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr b/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr
deleted file mode 100644
index b5c8cad275f..00000000000
--- a/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: unexpected `cfg` condition name: `unknown_key`
-  --> $DIR/exhaustive-names.rs:8:7
-   |
-LL | #[cfg(unknown_key = "value")]
-   |       ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
-   = note: `#[warn(unexpected_cfgs)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/check-cfg/exhaustive-names.stderr b/tests/ui/check-cfg/exhaustive-names.stderr
index c5f6d537c5e..cfac28cd9b9 100644
--- a/tests/ui/check-cfg/exhaustive-names.stderr
+++ b/tests/ui/check-cfg/exhaustive-names.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr
index 745646bda1c..0a7bd81b8aa 100644
--- a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr
+++ b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr
@@ -7,6 +7,8 @@ LL | #[cfg(test = "value")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/exhaustive-values.without_names.stderr b/tests/ui/check-cfg/exhaustive-values.without_names.stderr
index 745646bda1c..0a7bd81b8aa 100644
--- a/tests/ui/check-cfg/exhaustive-values.without_names.stderr
+++ b/tests/ui/check-cfg/exhaustive-values.without_names.stderr
@@ -7,6 +7,8 @@ LL | #[cfg(test = "value")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/mix.cfg.stderr b/tests/ui/check-cfg/mix.cfg.stderr
deleted file mode 100644
index 046d40f36b0..00000000000
--- a/tests/ui/check-cfg/mix.cfg.stderr
+++ /dev/null
@@ -1,184 +0,0 @@
-warning: unexpected `cfg` condition name: `widnows`
-  --> $DIR/mix.rs:15:7
-   |
-LL | #[cfg(widnows)]
-   |       ^^^^^^^ help: there is a config with a similar name: `windows`
-   |
-   = note: `#[warn(unexpected_cfgs)]` on by default
-
-warning: unexpected `cfg` condition value: (none)
-  --> $DIR/mix.rs:19:7
-   |
-LL | #[cfg(feature)]
-   |       ^^^^^^^- help: specify a config value: `= "foo"`
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition value: `bar`
-  --> $DIR/mix.rs:26:7
-   |
-LL | #[cfg(feature = "bar")]
-   |       ^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition value: `zebra`
-  --> $DIR/mix.rs:30:7
-   |
-LL | #[cfg(feature = "zebra")]
-   |       ^^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition name: `uu`
-  --> $DIR/mix.rs:34:12
-   |
-LL | #[cfg_attr(uu, test)]
-   |            ^^
-   |
-   = help: expected names are: `cfg`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `names_values`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
-
-warning: unexpected `cfg` condition name: `widnows`
-  --> $DIR/mix.rs:43:10
-   |
-LL |     cfg!(widnows);
-   |          ^^^^^^^ help: there is a config with a similar name: `windows`
-
-warning: unexpected `cfg` condition value: `bar`
-  --> $DIR/mix.rs:46:10
-   |
-LL |     cfg!(feature = "bar");
-   |          ^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition value: `zebra`
-  --> $DIR/mix.rs:48:10
-   |
-LL |     cfg!(feature = "zebra");
-   |          ^^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:50:10
-   |
-LL |     cfg!(xxx = "foo");
-   |          ^^^^^^^^^^^
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:52:10
-   |
-LL |     cfg!(xxx);
-   |          ^^^
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:54:14
-   |
-LL |     cfg!(any(xxx, windows));
-   |              ^^^
-
-warning: unexpected `cfg` condition value: `bad`
-  --> $DIR/mix.rs:56:14
-   |
-LL |     cfg!(any(feature = "bad", windows));
-   |              ^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:58:23
-   |
-LL |     cfg!(any(windows, xxx));
-   |                       ^^^
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:60:20
-   |
-LL |     cfg!(all(unix, xxx));
-   |                    ^^^
-
-warning: unexpected `cfg` condition name: `aa`
-  --> $DIR/mix.rs:62:14
-   |
-LL |     cfg!(all(aa, bb));
-   |              ^^
-
-warning: unexpected `cfg` condition name: `bb`
-  --> $DIR/mix.rs:62:18
-   |
-LL |     cfg!(all(aa, bb));
-   |                  ^^
-
-warning: unexpected `cfg` condition name: `aa`
-  --> $DIR/mix.rs:65:14
-   |
-LL |     cfg!(any(aa, bb));
-   |              ^^
-
-warning: unexpected `cfg` condition name: `bb`
-  --> $DIR/mix.rs:65:18
-   |
-LL |     cfg!(any(aa, bb));
-   |                  ^^
-
-warning: unexpected `cfg` condition value: `zebra`
-  --> $DIR/mix.rs:68:20
-   |
-LL |     cfg!(any(unix, feature = "zebra"));
-   |                    ^^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:70:14
-   |
-LL |     cfg!(any(xxx, feature = "zebra"));
-   |              ^^^
-
-warning: unexpected `cfg` condition value: `zebra`
-  --> $DIR/mix.rs:70:19
-   |
-LL |     cfg!(any(xxx, feature = "zebra"));
-   |                   ^^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:73:14
-   |
-LL |     cfg!(any(xxx, unix, xxx));
-   |              ^^^
-
-warning: unexpected `cfg` condition name: `xxx`
-  --> $DIR/mix.rs:73:25
-   |
-LL |     cfg!(any(xxx, unix, xxx));
-   |                         ^^^
-
-warning: unexpected `cfg` condition value: `zebra`
-  --> $DIR/mix.rs:76:14
-   |
-LL |     cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
-   |              ^^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition value: `zebra`
-  --> $DIR/mix.rs:76:33
-   |
-LL |     cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
-   |                                 ^^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: unexpected `cfg` condition value: `zebra`
-  --> $DIR/mix.rs:76:52
-   |
-LL |     cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
-   |                                                    ^^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `foo`
-
-warning: 26 warnings emitted
-
diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr
index 25b8f95ae2f..39660a2fd6e 100644
--- a/tests/ui/check-cfg/mix.stderr
+++ b/tests/ui/check-cfg/mix.stderr
@@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `widnows`
 LL | #[cfg(widnows)]
    |       ^^^^^^^ help: there is a config with a similar name: `windows`
    |
+   = help: to expect this configuration use `--check-cfg=cfg(widnows)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: (none)
@@ -13,6 +15,8 @@ LL | #[cfg(feature)]
    |       ^^^^^^^- help: specify a config value: `= "foo"`
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `bar`
   --> $DIR/mix.rs:23:7
@@ -21,6 +25,8 @@ LL | #[cfg(feature = "bar")]
    |       ^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `zebra`
   --> $DIR/mix.rs:27:7
@@ -29,6 +35,8 @@ LL | #[cfg(feature = "zebra")]
    |       ^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `uu`
   --> $DIR/mix.rs:31:12
@@ -37,12 +45,17 @@ LL | #[cfg_attr(uu, test)]
    |            ^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(uu)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `widnows`
   --> $DIR/mix.rs:40:10
    |
 LL |     cfg!(widnows);
    |          ^^^^^^^ help: there is a config with a similar name: `windows`
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(widnows)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `bar`
   --> $DIR/mix.rs:43:10
@@ -51,6 +64,8 @@ LL |     cfg!(feature = "bar");
    |          ^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `zebra`
   --> $DIR/mix.rs:45:10
@@ -59,24 +74,35 @@ LL |     cfg!(feature = "zebra");
    |          ^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:47:10
    |
 LL |     cfg!(xxx = "foo");
    |          ^^^^^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:49:10
    |
 LL |     cfg!(xxx);
    |          ^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:51:14
    |
 LL |     cfg!(any(xxx, windows));
    |              ^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `bad`
   --> $DIR/mix.rs:53:14
@@ -85,42 +111,62 @@ LL |     cfg!(any(feature = "bad", windows));
    |              ^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("bad"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:55:23
    |
 LL |     cfg!(any(windows, xxx));
    |                       ^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:57:20
    |
 LL |     cfg!(all(unix, xxx));
    |                    ^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `aa`
   --> $DIR/mix.rs:59:14
    |
 LL |     cfg!(all(aa, bb));
    |              ^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(aa)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `bb`
   --> $DIR/mix.rs:59:18
    |
 LL |     cfg!(all(aa, bb));
    |                  ^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(bb)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `aa`
   --> $DIR/mix.rs:62:14
    |
 LL |     cfg!(any(aa, bb));
    |              ^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(aa)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `bb`
   --> $DIR/mix.rs:62:18
    |
 LL |     cfg!(any(aa, bb));
    |                  ^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(bb)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `zebra`
   --> $DIR/mix.rs:65:20
@@ -129,12 +175,17 @@ LL |     cfg!(any(unix, feature = "zebra"));
    |                    ^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:67:14
    |
 LL |     cfg!(any(xxx, feature = "zebra"));
    |              ^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `zebra`
   --> $DIR/mix.rs:67:19
@@ -143,18 +194,26 @@ LL |     cfg!(any(xxx, feature = "zebra"));
    |                   ^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:70:14
    |
 LL |     cfg!(any(xxx, unix, xxx));
    |              ^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `xxx`
   --> $DIR/mix.rs:70:25
    |
 LL |     cfg!(any(xxx, unix, xxx));
    |                         ^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(xxx)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `zebra`
   --> $DIR/mix.rs:73:14
@@ -163,6 +222,8 @@ LL |     cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
    |              ^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `zebra`
   --> $DIR/mix.rs:73:33
@@ -171,6 +232,8 @@ LL |     cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
    |                                 ^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `zebra`
   --> $DIR/mix.rs:73:52
@@ -179,6 +242,8 @@ LL |     cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
    |                                                    ^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `foo`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 26 warnings emitted
 
diff --git a/tests/ui/check-cfg/no-expected-values.empty.stderr b/tests/ui/check-cfg/no-expected-values.empty.stderr
index 0969d61dd40..ae55c95c0b1 100644
--- a/tests/ui/check-cfg/no-expected-values.empty.stderr
+++ b/tests/ui/check-cfg/no-expected-values.empty.stderr
@@ -7,6 +7,8 @@ LL | #[cfg(feature = "foo")]
    |              help: remove the value
    |
    = note: no expected value for `feature`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `foo`
@@ -18,6 +20,8 @@ LL | #[cfg(test = "foo")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/check-cfg/no-expected-values.mixed.stderr b/tests/ui/check-cfg/no-expected-values.mixed.stderr
index 0969d61dd40..ae55c95c0b1 100644
--- a/tests/ui/check-cfg/no-expected-values.mixed.stderr
+++ b/tests/ui/check-cfg/no-expected-values.mixed.stderr
@@ -7,6 +7,8 @@ LL | #[cfg(feature = "foo")]
    |              help: remove the value
    |
    = note: no expected value for `feature`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `foo`
@@ -18,6 +20,8 @@ LL | #[cfg(test = "foo")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/check-cfg/no-expected-values.simple.stderr b/tests/ui/check-cfg/no-expected-values.simple.stderr
index 0969d61dd40..ae55c95c0b1 100644
--- a/tests/ui/check-cfg/no-expected-values.simple.stderr
+++ b/tests/ui/check-cfg/no-expected-values.simple.stderr
@@ -7,6 +7,8 @@ LL | #[cfg(feature = "foo")]
    |              help: remove the value
    |
    = note: no expected value for `feature`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `foo`
@@ -18,6 +20,8 @@ LL | #[cfg(test = "foo")]
    |           help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/check-cfg/order-independant.values_after.stderr b/tests/ui/check-cfg/order-independant.values_after.stderr
index ed162fb5489..d1de26ba303 100644
--- a/tests/ui/check-cfg/order-independant.values_after.stderr
+++ b/tests/ui/check-cfg/order-independant.values_after.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(a = "unk")]
    |       ^^^^^^^^^
    |
    = note: expected values for `a` are: (none), `b`
+   = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/order-independant.values_before.stderr b/tests/ui/check-cfg/order-independant.values_before.stderr
index ed162fb5489..d1de26ba303 100644
--- a/tests/ui/check-cfg/order-independant.values_before.stderr
+++ b/tests/ui/check-cfg/order-independant.values_before.stderr
@@ -5,6 +5,8 @@ LL | #[cfg(a = "unk")]
    |       ^^^^^^^^^
    |
    = note: expected values for `a` are: (none), `b`
+   = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/stmt-no-ice.stderr b/tests/ui/check-cfg/stmt-no-ice.stderr
index c2483fe4a06..112367606dc 100644
--- a/tests/ui/check-cfg/stmt-no-ice.stderr
+++ b/tests/ui/check-cfg/stmt-no-ice.stderr
@@ -5,6 +5,8 @@ LL |     #[cfg(crossbeam_loom)]
    |           ^^^^^^^^^^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(crossbeam_loom)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/unexpected-cfg-name.stderr b/tests/ui/check-cfg/unexpected-cfg-name.stderr
index 0874ccfc461..8748b324fb6 100644
--- a/tests/ui/check-cfg/unexpected-cfg-name.stderr
+++ b/tests/ui/check-cfg/unexpected-cfg-name.stderr
@@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `widnows`
 LL | #[cfg(widnows)]
    |       ^^^^^^^ help: there is a config with a similar name: `windows`
    |
+   = help: to expect this configuration use `--check-cfg=cfg(widnows)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr b/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr
deleted file mode 100644
index 2855aa75966..00000000000
--- a/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-warning: unexpected `cfg` condition value: `sedre`
-  --> $DIR/unexpected-cfg-value.rs:9:7
-   |
-LL | #[cfg(feature = "sedre")]
-   |       ^^^^^^^^^^-------
-   |                 |
-   |                 help: there is a expected value with a similar name: `"serde"`
-   |
-   = note: expected values for `feature` are: `full`, `serde`
-   = note: `#[warn(unexpected_cfgs)]` on by default
-
-warning: unexpected `cfg` condition value: `rand`
-  --> $DIR/unexpected-cfg-value.rs:16:7
-   |
-LL | #[cfg(feature = "rand")]
-   |       ^^^^^^^^^^^^^^^^
-   |
-   = note: expected values for `feature` are: `full`, `serde`
-
-warning: 2 warnings emitted
-
diff --git a/tests/ui/check-cfg/unexpected-cfg-value.stderr b/tests/ui/check-cfg/unexpected-cfg-value.stderr
index 31c473a08cb..e5435d37670 100644
--- a/tests/ui/check-cfg/unexpected-cfg-value.stderr
+++ b/tests/ui/check-cfg/unexpected-cfg-value.stderr
@@ -7,6 +7,8 @@ LL | #[cfg(feature = "sedre")]
    |                 help: there is a expected value with a similar name: `"serde"`
    |
    = note: expected values for `feature` are: `full`, `serde`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("sedre"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `rand`
@@ -16,6 +18,8 @@ LL | #[cfg(feature = "rand")]
    |       ^^^^^^^^^^^^^^^^
    |
    = note: expected values for `feature` are: `full`, `serde`
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("rand"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/check-cfg/well-known-names.stderr b/tests/ui/check-cfg/well-known-names.stderr
index 6040663074d..763ba4646c3 100644
--- a/tests/ui/check-cfg/well-known-names.stderr
+++ b/tests/ui/check-cfg/well-known-names.stderr
@@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `target_oz`
 LL | #[cfg(target_oz = "linux")]
    |       ^^^^^^^^^^^^^^^^^^^
    |
+   = help: to expect this configuration use `--check-cfg=cfg(target_oz, values("linux"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 help: there is a config with a similar name and value
    |
@@ -17,18 +19,26 @@ LL | #[cfg(features = "foo")]
    |       ^^^^^^^^^^^^^^^^
    |
    = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `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`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(features, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `feature`
   --> $DIR/well-known-names.rs:17:7
    |
 LL | #[cfg(feature = "foo")]
    |       ^^^^^^^^^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `uniw`
   --> $DIR/well-known-names.rs:21:7
    |
 LL | #[cfg(uniw)]
    |       ^^^^ help: there is a config with a similar name: `unix`
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(uniw)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 4 warnings emitted
 
diff --git a/tests/ui/check-cfg/well-known-values.rs b/tests/ui/check-cfg/well-known-values.rs
index 39a470c202f..21268bf10d5 100644
--- a/tests/ui/check-cfg/well-known-values.rs
+++ b/tests/ui/check-cfg/well-known-values.rs
@@ -51,7 +51,8 @@
     //~^ WARN unexpected `cfg` condition value
     target_family = "_UNEXPECTED_VALUE",
     //~^ WARN unexpected `cfg` condition value
-    target_feature = "_UNEXPECTED_VALUE", // currently *any* values are "expected"
+    target_feature = "_UNEXPECTED_VALUE",
+    //~^ WARN unexpected `cfg` condition value
     target_has_atomic = "_UNEXPECTED_VALUE",
     //~^ WARN unexpected `cfg` condition value
     target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE",
@@ -90,6 +91,9 @@ fn target_os_linux_misspell() {}
 #[cfg(target_os = "linux")]
 fn target_os_linux() {}
 
+#[cfg(target_feature = "crt-static")] // pure rustc feature
+fn target_feature() {}
+
 #[cfg(target_has_atomic = "8")]
 fn target_has_atomic_8() {}
 
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index a6b9c75a142..4f708e62cd3 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -7,6 +7,8 @@ LL |     debug_assertions = "_UNEXPECTED_VALUE",
    |                     help: remove the value
    |
    = note: no expected value for `debug_assertions`
+   = help: to expect this configuration use `--check-cfg=cfg(debug_assertions, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -18,6 +20,8 @@ LL |     doc = "_UNEXPECTED_VALUE",
    |        help: remove the value
    |
    = note: no expected value for `doc`
+   = help: to expect this configuration use `--check-cfg=cfg(doc, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:30:5
@@ -28,6 +32,8 @@ LL |     doctest = "_UNEXPECTED_VALUE",
    |            help: remove the value
    |
    = note: no expected value for `doctest`
+   = help: to expect this configuration use `--check-cfg=cfg(doctest, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:32:5
@@ -38,6 +44,8 @@ LL |     miri = "_UNEXPECTED_VALUE",
    |         help: remove the value
    |
    = note: no expected value for `miri`
+   = help: to expect this configuration use `--check-cfg=cfg(miri, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:34:5
@@ -48,6 +56,8 @@ LL |     overflow_checks = "_UNEXPECTED_VALUE",
    |                    help: remove the value
    |
    = note: no expected value for `overflow_checks`
+   = help: to expect this configuration use `--check-cfg=cfg(overflow_checks, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:36:5
@@ -56,6 +66,8 @@ LL |     panic = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `panic` are: `abort`, `unwind`
+   = help: to expect this configuration use `--check-cfg=cfg(panic, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:38:5
@@ -66,6 +78,8 @@ LL |     proc_macro = "_UNEXPECTED_VALUE",
    |               help: remove the value
    |
    = note: no expected value for `proc_macro`
+   = help: to expect this configuration use `--check-cfg=cfg(proc_macro, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:40:5
@@ -74,6 +88,8 @@ LL |     relocation_model = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `relocation_model` are: `dynamic-no-pic`, `pic`, `pie`, `ropi`, `ropi-rwpi`, `rwpi`, `static`
+   = help: to expect this configuration use `--check-cfg=cfg(relocation_model, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:42:5
@@ -82,6 +98,8 @@ LL |     sanitize = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `sanitize` are: `address`, `cfi`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`
+   = help: to expect this configuration use `--check-cfg=cfg(sanitize, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:44:5
@@ -90,6 +108,8 @@ LL |     target_abi = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_abi` are: ``, `abi64`, `abiv2`, `abiv2hf`, `eabi`, `eabihf`, `elf`, `fortanix`, `ilp32`, `llvm`, `macabi`, `sim`, `softfloat`, `spe`, `uwp`, `vec-extabi`, `x32`
+   = help: to expect this configuration use `--check-cfg=cfg(target_abi, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:46:5
@@ -98,6 +118,8 @@ LL |     target_arch = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`
+   = help: to expect this configuration use `--check-cfg=cfg(target_arch, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:48:5
@@ -106,6 +128,8 @@ LL |     target_endian = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_endian` are: `big`, `little`
+   = help: to expect this configuration use `--check-cfg=cfg(target_endian, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:50:5
@@ -114,6 +138,8 @@ LL |     target_env = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_env` are: ``, `eabihf`, `gnu`, `gnueabihf`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `psx`, `relibc`, `sgx`, `uclibc`
+   = help: to expect this configuration use `--check-cfg=cfg(target_env, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
   --> $DIR/well-known-values.rs:52:5
@@ -122,49 +148,71 @@ LL |     target_family = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_family` are: `unix`, `wasm`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(target_family, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:55:5
+  --> $DIR/well-known-values.rs:54:5
+   |
+LL |     target_feature = "_UNEXPECTED_VALUE",
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt`
+   = help: to expect this configuration use `--check-cfg=cfg(target_feature, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
+  --> $DIR/well-known-values.rs:56:5
    |
 LL |     target_has_atomic = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_has_atomic` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr`
+   = help: to expect this configuration use `--check-cfg=cfg(target_has_atomic, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:57:5
+  --> $DIR/well-known-values.rs:58:5
    |
 LL |     target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_has_atomic_equal_alignment` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr`
+   = help: to expect this configuration use `--check-cfg=cfg(target_has_atomic_equal_alignment, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:59:5
+  --> $DIR/well-known-values.rs:60:5
    |
 LL |     target_has_atomic_load_store = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_has_atomic_load_store` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr`
+   = help: to expect this configuration use `--check-cfg=cfg(target_has_atomic_load_store, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:61:5
+  --> $DIR/well-known-values.rs:62:5
    |
 LL |     target_os = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
+   = help: to expect this configuration use `--check-cfg=cfg(target_os, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:63:5
+  --> $DIR/well-known-values.rs:64:5
    |
 LL |     target_pointer_width = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_pointer_width` are: `16`, `32`, `64`
+   = help: to expect this configuration use `--check-cfg=cfg(target_pointer_width, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:65:5
+  --> $DIR/well-known-values.rs:66:5
    |
 LL |     target_thread_local = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^----------------------
@@ -172,17 +220,21 @@ LL |     target_thread_local = "_UNEXPECTED_VALUE",
    |                        help: remove the value
    |
    = note: no expected value for `target_thread_local`
+   = help: to expect this configuration use `--check-cfg=cfg(target_thread_local, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:67:5
+  --> $DIR/well-known-values.rs:68:5
    |
 LL |     target_vendor = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `nintendo`, `nvidia`, `pc`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, `wrs`
+   = help: to expect this configuration use `--check-cfg=cfg(target_vendor, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:69:5
+  --> $DIR/well-known-values.rs:70:5
    |
 LL |     test = "_UNEXPECTED_VALUE",
    |     ^^^^----------------------
@@ -190,9 +242,11 @@ LL |     test = "_UNEXPECTED_VALUE",
    |         help: remove the value
    |
    = note: no expected value for `test`
+   = help: to expect this configuration use `--check-cfg=cfg(test, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:71:5
+  --> $DIR/well-known-values.rs:72:5
    |
 LL |     unix = "_UNEXPECTED_VALUE",
    |     ^^^^----------------------
@@ -200,9 +254,11 @@ LL |     unix = "_UNEXPECTED_VALUE",
    |         help: remove the value
    |
    = note: no expected value for `unix`
+   = help: to expect this configuration use `--check-cfg=cfg(unix, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
-  --> $DIR/well-known-values.rs:73:5
+  --> $DIR/well-known-values.rs:74:5
    |
 LL |     windows = "_UNEXPECTED_VALUE",
    |     ^^^^^^^----------------------
@@ -210,9 +266,11 @@ LL |     windows = "_UNEXPECTED_VALUE",
    |            help: remove the value
    |
    = note: no expected value for `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(windows, values("_UNEXPECTED_VALUE"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `linuz`
-  --> $DIR/well-known-values.rs:79:7
+  --> $DIR/well-known-values.rs:80:7
    |
 LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
    |       ^^^^^^^^^^^^-------
@@ -220,6 +278,8 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
    |                   help: there is a expected value with a similar name: `"linux"`
    |
    = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
+   = help: to expect this configuration use `--check-cfg=cfg(target_os, values("linuz"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
-warning: 25 warnings emitted
+warning: 26 warnings emitted
 
diff --git a/tests/ui/closures/infer-signature-from-impl.rs b/tests/ui/closures/infer-signature-from-impl.rs
index 6e8c94177bf..8b18e4ef9e7 100644
--- a/tests/ui/closures/infer-signature-from-impl.rs
+++ b/tests/ui/closures/infer-signature-from-impl.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[next] known-bug: trait-system-refactor-initiative#71
 //[current] check-pass
 
diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs
index 2c3ef4fd3f7..94a7ecbe11f 100644
--- a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs
+++ b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even
 // though no impls are found.
diff --git a/tests/ui/coherence/coherence-overlap-downstream.rs b/tests/ui/coherence/coherence-overlap-downstream.rs
index a4e559604a0..171b2a32fc5 100644
--- a/tests/ui/coherence/coherence-overlap-downstream.rs
+++ b/tests/ui/coherence/coherence-overlap-downstream.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even
 // though no impls are found.
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs
index a7c90a6b8c8..6f5cc980491 100644
--- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs
+++ b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // Tests that we consider `Box<U>: !Sugar` to be ambiguous, even
 // though we see no impl of `Sugar` for `Box`. Therefore, an overlap
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.rs b/tests/ui/coherence/coherence-overlap-issue-23516.rs
index c846d39716b..4daaed4366f 100644
--- a/tests/ui/coherence/coherence-overlap-issue-23516.rs
+++ b/tests/ui/coherence/coherence-overlap-issue-23516.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // Tests that we consider `Box<U>: !Sugar` to be ambiguous, even
 // though we see no impl of `Sugar` for `Box`. Therefore, an overlap
diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs
index 743e80d3f18..0f785b4e5f6 100644
--- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs
+++ b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 struct S;
 
diff --git a/tests/ui/coherence/normalize-for-errors.rs b/tests/ui/coherence/normalize-for-errors.rs
index 367d34251ae..30723518bce 100644
--- a/tests/ui/coherence/normalize-for-errors.rs
+++ b/tests/ui/coherence/normalize-for-errors.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 struct MyType;
 trait MyTrait<S> {}
diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr
index 69f541cba05..f64e8b39798 100644
--- a/tests/ui/coherence/occurs-check/associated-type.next.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr
@@ -1,11 +1,11 @@
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
 error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
   --> $DIR/associated-type.rs:31:1
    |
diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr
index c2c951af0db..8e852ec796e 100644
--- a/tests/ui/coherence/occurs-check/associated-type.old.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr
@@ -1,11 +1,11 @@
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
 error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
   --> $DIR/associated-type.rs:31:1
    |
diff --git a/tests/ui/coherence/occurs-check/associated-type.rs b/tests/ui/coherence/occurs-check/associated-type.rs
index 909551f65be..227b6684785 100644
--- a/tests/ui/coherence/occurs-check/associated-type.rs
+++ b/tests/ui/coherence/occurs-check/associated-type.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // A regression test for #105787
 
diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs
index 9d31a3dc82d..2fa9dcebfde 100644
--- a/tests/ui/coherence/occurs-check/opaques.rs
+++ b/tests/ui/coherence/occurs-check/opaques.rs
@@ -1,5 +1,5 @@
 //revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // A regression test for #105787
 
diff --git a/tests/ui/coinduction/canonicalization-rerun.rs b/tests/ui/coinduction/canonicalization-rerun.rs
index c68895fc4e6..bbd8d802630 100644
--- a/tests/ui/coinduction/canonicalization-rerun.rs
+++ b/tests/ui/coinduction/canonicalization-rerun.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // If we use canonical goals during trait solving we have to reevaluate
 // the root goal of a cycle until we hit a fixpoint.
diff --git a/tests/ui/const-generics/defaults/default-param-wf-concrete.rs b/tests/ui/const-generics/defaults/default-param-wf-concrete.rs
index 09a00dd8e70..aa3307b92e4 100644
--- a/tests/ui/const-generics/defaults/default-param-wf-concrete.rs
+++ b/tests/ui/const-generics/defaults/default-param-wf-concrete.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 struct Foo<const N: u8 = { 255 + 1 }>;
 //~^ ERROR evaluation of constant value failed
diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs
new file mode 100644
index 00000000000..c6960fa7259
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs
@@ -0,0 +1,43 @@
+// Test that we can handle unsized types with an extern type tail part.
+// Regression test for issue #91827.
+
+#![feature(extern_types)]
+
+use std::ptr::addr_of;
+
+extern "C" {
+    type Opaque;
+}
+
+struct Newtype(Opaque);
+
+struct S {
+    i: i32,
+    j: i32,
+    a: Newtype,
+}
+
+const NEWTYPE: () = unsafe {
+    let buf = [0i32; 4];
+    let x: &Newtype = &*(&buf as *const _ as *const Newtype);
+
+    // Projecting to the newtype works, because it is always at offset 0.
+    let field = &x.0;
+};
+
+const OFFSET: () = unsafe {
+    let buf = [0i32; 4];
+    let x: &S = &*(&buf as *const _ as *const S);
+
+    // Accessing sized fields is perfectly fine, even at non-zero offsets.
+    let field = &x.i;
+    let field = &x.j;
+
+    // This needs to compute the field offset, but we don't know the type's alignment, so this
+    // fails.
+    let field = &x.a;
+    //~^ ERROR: evaluation of constant value failed
+    //~| does not have a known offset
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr
new file mode 100644
index 00000000000..99f37fedd3d
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/issue-91827-extern-types-field-offset.rs:38:17
+   |
+LL |     let field = &x.a;
+   |                 ^^^^ `extern type` does not have a known offset
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types.rs b/tests/ui/consts/const-eval/issue-91827-extern-types.rs
deleted file mode 100644
index c9aaa6e5587..00000000000
--- a/tests/ui/consts/const-eval/issue-91827-extern-types.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-// run-pass
-//
-// Test that we can handle unsized types with an extern type tail part.
-// Regression test for issue #91827.
-
-#![feature(extern_types)]
-
-use std::ptr::addr_of;
-
-extern "C" {
-    type Opaque;
-}
-
-unsafe impl Sync for Opaque {}
-
-#[repr(C)]
-pub struct List<T> {
-    len: usize,
-    data: [T; 0],
-    tail: Opaque,
-}
-
-#[repr(C)]
-pub struct ListImpl<T, const N: usize> {
-    len: usize,
-    data: [T; N],
-}
-
-impl<T> List<T> {
-    const fn as_slice(&self) -> &[T] {
-        unsafe {
-            let ptr = addr_of!(self.tail) as *const T;
-            std::slice::from_raw_parts(ptr, self.len)
-        }
-    }
-}
-
-impl<T, const N: usize> ListImpl<T, N> {
-    const fn as_list(&self) -> &List<T> {
-        unsafe { std::mem::transmute(self) }
-    }
-}
-
-pub static A: ListImpl<u128, 3> = ListImpl {
-    len: 3,
-    data: [5, 6, 7],
-};
-pub static A_REF: &'static List<u128> = A.as_list();
-pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
-
-const fn tail_offset<T>(list: &List<T>) -> isize {
-    unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
-}
-
-fn main() {
-    assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
-    // Check that interpreter and code generation agree about the position of the tail field.
-    assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
-}
diff --git a/tests/ui/consts/const-len-underflow-separate-spans.rs b/tests/ui/consts/const-len-underflow-separate-spans.rs
index 55704b64154..bd37be21576 100644
--- a/tests/ui/consts/const-len-underflow-separate-spans.rs
+++ b/tests/ui/consts/const-len-underflow-separate-spans.rs
@@ -3,7 +3,7 @@
 // overall context for what caused the evaluation.
 
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 const ONE: usize = 1;
 const TWO: usize = 2;
diff --git a/tests/ui/coroutine/async-gen-deduce-yield.rs b/tests/ui/coroutine/async-gen-deduce-yield.rs
new file mode 100644
index 00000000000..9ccc8ee41f6
--- /dev/null
+++ b/tests/ui/coroutine/async-gen-deduce-yield.rs
@@ -0,0 +1,14 @@
+// compile-flags: --edition 2024 -Zunstable-options
+// check-pass
+
+#![feature(async_iterator, gen_blocks)]
+
+use std::async_iter::AsyncIterator;
+
+fn deduce() -> impl AsyncIterator<Item = ()> {
+    async gen {
+        yield Default::default();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/coroutine/async_gen_fn_iter.rs b/tests/ui/coroutine/async_gen_fn_iter.rs
index 4fa29e1095a..ec6464d0048 100644
--- a/tests/ui/coroutine/async_gen_fn_iter.rs
+++ b/tests/ui/coroutine/async_gen_fn_iter.rs
@@ -3,6 +3,7 @@
 // run-pass
 
 #![feature(gen_blocks, async_iterator)]
+#![feature(noop_waker)]
 
 // make sure that a ridiculously simple async gen fn works as an iterator.
 
@@ -42,7 +43,7 @@ async fn async_main() {
 // ------------------------------------------------------------------------- //
 // Implementation Details Below...
 
-use std::pin::Pin;
+use std::pin::{Pin, pin};
 use std::task::*;
 use std::async_iter::AsyncIterator;
 use std::future::Future;
@@ -69,30 +70,15 @@ impl<'s, S: AsyncIterator> Future for Next<'s, S> where S: Unpin {
     }
 }
 
-pub fn noop_waker() -> Waker {
-    let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE);
-
-    // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld
-    unsafe { Waker::from_raw(raw) }
-}
-
-const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
-
-unsafe fn noop_clone(_p: *const ()) -> RawWaker {
-    RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
-}
-
-unsafe fn noop(_p: *const ()) {}
-
 fn main() {
-    let mut fut = async_main();
+    let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = noop_waker();
+    let waker = Waker::noop();
     let ctx = &mut Context::from_waker(&waker);
 
     loop {
-        match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } {
+        match fut.as_mut().poll(ctx) {
             Poll::Pending => {}
             Poll::Ready(()) => break,
         }
diff --git a/tests/ui/coroutine/clone-rpit.rs b/tests/ui/coroutine/clone-rpit.rs
index e0061e1c6bb..cbd28f88fcb 100644
--- a/tests/ui/coroutine/clone-rpit.rs
+++ b/tests/ui/coroutine/clone-rpit.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 
 #![feature(coroutines, coroutine_trait, coroutine_clone)]
diff --git a/tests/ui/coroutine/gen_block_is_iter.rs b/tests/ui/coroutine/gen_block_is_iter.rs
index 92625cf7c28..d43eef4a18d 100644
--- a/tests/ui/coroutine/gen_block_is_iter.rs
+++ b/tests/ui/coroutine/gen_block_is_iter.rs
@@ -1,6 +1,6 @@
 // revisions: next old
 //compile-flags: --edition 2024 -Zunstable-options
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/gen_block_iterate.rs b/tests/ui/coroutine/gen_block_iterate.rs
index 18e1bb88772..8e72b00d99d 100644
--- a/tests/ui/coroutine/gen_block_iterate.rs
+++ b/tests/ui/coroutine/gen_block_iterate.rs
@@ -1,6 +1,6 @@
 // revisions: next old
 //compile-flags: --edition 2024 -Zunstable-options
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // run-pass
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/non-static-is-unpin.rs b/tests/ui/coroutine/non-static-is-unpin.rs
index d77fe659f08..238e49bbfdf 100644
--- a/tests/ui/coroutine/non-static-is-unpin.rs
+++ b/tests/ui/coroutine/non-static-is-unpin.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // run-pass
 
 #![feature(coroutines, coroutine_trait)]
diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs
index 6ce78046dcc..f27183d11db 100644
--- a/tests/ui/coroutine/static-not-unpin.rs
+++ b/tests/ui/coroutine/static-not-unpin.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(coroutines)]
 
diff --git a/tests/ui/coroutine/uninhabited-field.rs b/tests/ui/coroutine/uninhabited-field.rs
new file mode 100644
index 00000000000..d9570c2fed8
--- /dev/null
+++ b/tests/ui/coroutine/uninhabited-field.rs
@@ -0,0 +1,37 @@
+// Test that uninhabited saved local doesn't make the entire variant uninhabited.
+// run-pass
+#![allow(unused)]
+#![feature(assert_matches)]
+#![feature(coroutine_trait)]
+#![feature(coroutines)]
+#![feature(never_type)]
+use std::assert_matches::assert_matches;
+use std::ops::Coroutine;
+use std::ops::CoroutineState;
+use std::pin::Pin;
+
+fn conjure<T>() -> T { loop {} }
+
+fn run<T>(x: bool, y: bool) {
+    let mut c = || {
+        if x {
+            let a : T;
+            if y {
+                a = conjure::<T>();
+            }
+            yield ();
+        } else {
+            let a : T;
+            if y {
+                a = conjure::<T>();
+            }
+            yield ();
+        }
+    };
+    assert_matches!(Pin::new(&mut c).resume(()), CoroutineState::Yielded(()));
+    assert_matches!(Pin::new(&mut c).resume(()), CoroutineState::Complete(()));
+}
+
+fn main() {
+    run::<!>(false, false);
+}
diff --git a/tests/ui/destructuring-assignment/bad-expr-lhs.rs b/tests/ui/destructuring-assignment/bad-expr-lhs.rs
index 53794783a3c..90e1ac19943 100644
--- a/tests/ui/destructuring-assignment/bad-expr-lhs.rs
+++ b/tests/ui/destructuring-assignment/bad-expr-lhs.rs
@@ -4,6 +4,4 @@ fn main() {
     (1, 2) = (3, 4);
     //~^ ERROR invalid left-hand side of assignment
     //~| ERROR invalid left-hand side of assignment
-
-    None = Some(3); //~ ERROR invalid left-hand side of assignment
 }
diff --git a/tests/ui/destructuring-assignment/bad-expr-lhs.stderr b/tests/ui/destructuring-assignment/bad-expr-lhs.stderr
index d2986747480..2916d6d9f11 100644
--- a/tests/ui/destructuring-assignment/bad-expr-lhs.stderr
+++ b/tests/ui/destructuring-assignment/bad-expr-lhs.stderr
@@ -30,15 +30,7 @@ LL |     (1, 2) = (3, 4);
    |         |
    |         cannot assign to this expression
 
-error[E0070]: invalid left-hand side of assignment
-  --> $DIR/bad-expr-lhs.rs:8:10
-   |
-LL |     None = Some(3);
-   |     ---- ^
-   |     |
-   |     cannot assign to this expression
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0067, E0070.
 For more information about an error, try `rustc --explain E0067`.
diff --git a/tests/ui/destructuring-assignment/non-exhaustive-destructure.rs b/tests/ui/destructuring-assignment/non-exhaustive-destructure.rs
new file mode 100644
index 00000000000..39939f2bad6
--- /dev/null
+++ b/tests/ui/destructuring-assignment/non-exhaustive-destructure.rs
@@ -0,0 +1,4 @@
+fn main() {
+    None = Some(3);
+    //~^ ERROR refutable pattern in local binding
+}
diff --git a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
new file mode 100644
index 00000000000..b9ceaa4af7b
--- /dev/null
+++ b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
@@ -0,0 +1,17 @@
+error[E0005]: refutable pattern in local binding
+  --> $DIR/non-exhaustive-destructure.rs:2:5
+   |
+LL |     None = Some(3);
+   |     ^^^^ pattern `Some(_)` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `Option<i32>`
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |     if None = Some(3) { todo!() };
+   |     ++                +++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0005`.
diff --git a/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs b/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs
index 8da7f90c524..f82e029983b 100644
--- a/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs
+++ b/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs
@@ -11,17 +11,22 @@ type A = E;
 fn main() {
     let mut a;
 
+    S = S;
     (S, a) = (S, ());
 
+    E::V = E::V;
     (E::V, a) = (E::V, ());
 
+    <E>::V = E::V;
     (<E>::V, a) = (E::V, ());
+    A::V = A::V;
     (A::V, a) = (E::V, ());
 }
 
 impl S {
     fn check() {
         let a;
+        Self = S;
         (Self, a) = (S, ());
     }
 }
@@ -29,6 +34,7 @@ impl S {
 impl E {
     fn check() {
         let a;
+        Self::V = E::V;
         (Self::V, a) = (E::V, ());
     }
 }
diff --git a/tests/ui/diagnostic-width/long-E0308.stderr b/tests/ui/diagnostic-width/long-E0308.stderr
index 20b018b9f77..1e5966a1c5d 100644
--- a/tests/ui/diagnostic-width/long-E0308.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.stderr
@@ -19,9 +19,8 @@ LL |  |     ))))))))))))))))))))))))))))));
    |  |__________________________________^ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>`
    |
    = note: expected struct `Atype<Btype<..., ...>, ...>`
-           the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
                 found enum `Result<Result<..., ...>, ...>`
-           the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
 
 error[E0308]: mismatched types
   --> $DIR/long-E0308.rs:57:26
@@ -35,9 +34,8 @@ LL | |     ))))))))))))))))))))))));
    | |____________________________^ expected `Option<Result<..., ...>>`, found `Result<Result<..., ...>, ...>`
    |
    = note: expected enum `Option<Result<..., ...>>`
-           the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
               found enum `Result<Result<..., ...>, ...>`
-           the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
 
 error[E0308]: mismatched types
   --> $DIR/long-E0308.rs:88:9
@@ -55,8 +53,8 @@ LL | |     > = ();
    |       expected due to this
    |
    = note: expected struct `Atype<Btype<..., ...>, ...>`
-           the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
            found unit type `()`
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
 
 error[E0308]: mismatched types
   --> $DIR/long-E0308.rs:91:17
@@ -73,7 +71,7 @@ LL | |     ))))))))))))))))))))))));
    |
    = note: expected unit type `()`
                    found enum `Result<Result<..., ...>, ...>`
-           the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr
index 592640a884c..3b5998df353 100644
--- a/tests/ui/duplicate_entry_error.stderr
+++ b/tests/ui/duplicate_entry_error.stderr
@@ -1,8 +1,11 @@
 error[E0152]: found duplicate lang item `panic_impl`
   --> $DIR/duplicate_entry_error.rs:11:1
    |
-LL | fn panic_impl(info: &PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic_impl(info: &PanicInfo) -> ! {
+LL | |
+LL | |     loop {}
+LL | | }
+   | |_^
    |
    = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on)
    = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
diff --git a/tests/ui/dyn-star/box.rs b/tests/ui/dyn-star/box.rs
index 87c8356a174..8b2f46bd1b2 100644
--- a/tests/ui/dyn-star/box.rs
+++ b/tests/ui/dyn-star/box.rs
@@ -1,7 +1,7 @@
 // run-pass
 // revisions: current next
 //[current] compile-flags: -C opt-level=0
-//[next] compile-flags: -Ztrait-solver=next -C opt-level=0
+//[next] compile-flags: -Znext-solver -C opt-level=0
 
 #![feature(dyn_star)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
index 9846f871424..dffe6ae8a36 100644
--- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
+++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(dyn_star)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/dyn-star/dispatch-on-pin-mut.rs b/tests/ui/dyn-star/dispatch-on-pin-mut.rs
index 5774c8b2a67..c4ae279e6c1 100644
--- a/tests/ui/dyn-star/dispatch-on-pin-mut.rs
+++ b/tests/ui/dyn-star/dispatch-on-pin-mut.rs
@@ -4,6 +4,7 @@
 
 #![feature(dyn_star)]
 //~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+#![feature(noop_waker)]
 
 use std::future::Future;
 
@@ -18,33 +19,18 @@ async fn async_main() {
 // ------------------------------------------------------------------------- //
 // Implementation Details Below...
 
-use std::pin::Pin;
 use std::task::*;
-
-pub fn noop_waker() -> Waker {
-    let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE);
-
-    // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld
-    unsafe { Waker::from_raw(raw) }
-}
-
-const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
-
-unsafe fn noop_clone(_p: *const ()) -> RawWaker {
-    RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
-}
-
-unsafe fn noop(_p: *const ()) {}
+use std::pin::pin;
 
 fn main() {
-    let mut fut = async_main();
+    let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = noop_waker();
+    let waker = Waker::noop();
     let ctx = &mut Context::from_waker(&waker);
 
     loop {
-        match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } {
+        match fut.as_mut().poll(ctx) {
             Poll::Pending => {}
             Poll::Ready(()) => break,
         }
diff --git a/tests/ui/dyn-star/param-env-region-infer.rs b/tests/ui/dyn-star/param-env-region-infer.rs
index 50dec94d25b..1e331777765 100644
--- a/tests/ui/dyn-star/param-env-region-infer.rs
+++ b/tests/ui/dyn-star/param-env-region-infer.rs
@@ -1,7 +1,7 @@
 // revisions: current
 // incremental
 
-// FIXME(-Ztrait-solver=next): THis currently results in unstable query results:
+// FIXME(-Znext-solver): THis currently results in unstable query results:
 // `normalizes-to(opaque, opaque)` changes from `Maybe(Ambiguous)` to `Maybe(Overflow)`
 // once the hidden type of the opaque is already defined to be itself.
 
diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr
index 816ba2d569b..dbea7e6d27f 100644
--- a/tests/ui/error-codes/E0152.stderr
+++ b/tests/ui/error-codes/E0152.stderr
@@ -2,7 +2,7 @@ error[E0152]: found duplicate lang item `owned_box`
   --> $DIR/E0152.rs:5:1
    |
 LL | struct Foo<T>(T);
-   | ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^
    |
    = note: the lang item is first defined in crate `alloc` (which `std` depends on)
    = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib
diff --git a/tests/ui/error-codes/E0264.stderr b/tests/ui/error-codes/E0264.stderr
index 14a4ffbe316..3503fb229e4 100644
--- a/tests/ui/error-codes/E0264.stderr
+++ b/tests/ui/error-codes/E0264.stderr
@@ -2,7 +2,7 @@ error[E0264]: unknown external lang item: `cake`
   --> $DIR/E0264.rs:5:5
    |
 LL |     fn cake();
-   |     ^^^^^^^^^
+   |     ^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs
index e9afc756726..d87916198c5 100644
--- a/tests/ui/error-codes/E0476.rs
+++ b/tests/ui/error-codes/E0476.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next-coherence
+//[next] compile-flags: -Znext-solver=coherence
 #![feature(coerce_unsized)]
 #![feature(unsize)]
 
diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs
new file mode 100644
index 00000000000..bfbc1e9bffa
--- /dev/null
+++ b/tests/ui/extern/extern-types-field-offset.rs
@@ -0,0 +1,33 @@
+// run-fail
+// check-run-results
+// exec-env:RUST_BACKTRACE=0
+// normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL"
+#![feature(extern_types)]
+
+extern "C" {
+    type Opaque;
+}
+
+struct Newtype(Opaque);
+
+struct S {
+    i: i32,
+    j: i32,
+    a: Newtype,
+}
+
+fn main() {
+    let buf = [0i32; 4];
+
+    let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) };
+    // Projecting to the newtype works, because it is always at offset 0.
+    let field = &x.0;
+
+    let x: &S = unsafe { &*(&buf as *const _ as *const S) };
+    // Accessing sized fields is perfectly fine, even at non-zero offsets.
+    let field = &x.i;
+    let field = &x.j;
+    // This needs to compute the field offset, but we don't know the type's alignment,
+    // so this panics.
+    let field = &x.a;
+}
diff --git a/tests/ui/extern/extern-types-field-offset.run.stderr b/tests/ui/extern/extern-types-field-offset.run.stderr
new file mode 100644
index 00000000000..1b04b860db5
--- /dev/null
+++ b/tests/ui/extern/extern-types-field-offset.run.stderr
@@ -0,0 +1,4 @@
+thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+attempted to compute the size or alignment of extern type `Opaque`
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/extern/extern-types-size_of_val.align.run.stderr b/tests/ui/extern/extern-types-size_of_val.align.run.stderr
new file mode 100644
index 00000000000..20c4d8785e8
--- /dev/null
+++ b/tests/ui/extern/extern-types-size_of_val.align.run.stderr
@@ -0,0 +1,4 @@
+thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+attempted to compute the size or alignment of extern type `A`
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/extern/extern-types-size_of_val.rs b/tests/ui/extern/extern-types-size_of_val.rs
index 3b02ea28eaa..4c4de873b7f 100644
--- a/tests/ui/extern/extern-types-size_of_val.rs
+++ b/tests/ui/extern/extern-types-size_of_val.rs
@@ -1,4 +1,8 @@
-// run-pass
+// run-fail
+// check-run-results
+// exec-env:RUST_BACKTRACE=0
+// normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL"
+// revisions: size align
 #![feature(extern_types)]
 
 use std::mem::{align_of_val, size_of_val};
@@ -10,6 +14,10 @@ extern "C" {
 fn main() {
     let x: &A = unsafe { &*(1usize as *const A) };
 
-    assert_eq!(size_of_val(x), 0);
-    assert_eq!(align_of_val(x), 1);
+    // These don't have a dynamic size, so this should panic.
+    if cfg!(size) {
+        assert_eq!(size_of_val(x), 0);
+    } else {
+        assert_eq!(align_of_val(x), 1);
+    }
 }
diff --git a/tests/ui/extern/extern-types-size_of_val.size.run.stderr b/tests/ui/extern/extern-types-size_of_val.size.run.stderr
new file mode 100644
index 00000000000..20c4d8785e8
--- /dev/null
+++ b/tests/ui/extern/extern-types-size_of_val.size.run.stderr
@@ -0,0 +1,4 @@
+thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+attempted to compute the size or alignment of extern type `A`
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr
index 1462c41e957..c582ca7ba3d 100644
--- a/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr
+++ b/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr
@@ -2,16 +2,34 @@ error[E0658]: gen blocks are experimental
   --> $DIR/feature-gate-gen_blocks.rs:5:5
    |
 LL |     gen {};
-   |     ^^^^^
+   |     ^^^
    |
    = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
    = help: add `#![feature(gen_blocks)]` to the crate attributes to enable
 
 error[E0658]: gen blocks are experimental
-  --> $DIR/feature-gate-gen_blocks.rs:13:5
+  --> $DIR/feature-gate-gen_blocks.rs:12:5
+   |
+LL |     async gen {};
+   |     ^^^^^^^^^
+   |
+   = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
+   = help: add `#![feature(gen_blocks)]` to the crate attributes to enable
+
+error[E0658]: gen blocks are experimental
+  --> $DIR/feature-gate-gen_blocks.rs:22:5
    |
 LL |     gen {};
-   |     ^^^^^
+   |     ^^^
+   |
+   = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
+   = help: add `#![feature(gen_blocks)]` to the crate attributes to enable
+
+error[E0658]: gen blocks are experimental
+  --> $DIR/feature-gate-gen_blocks.rs:25:5
+   |
+LL |     async gen {};
+   |     ^^^^^^^^^
    |
    = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
    = help: add `#![feature(gen_blocks)]` to the crate attributes to enable
@@ -22,7 +40,13 @@ error[E0282]: type annotations needed
 LL |     gen {};
    |         ^^ cannot infer type
 
-error: aborting due to 3 previous errors
+error[E0282]: type annotations needed
+  --> $DIR/feature-gate-gen_blocks.rs:12:15
+   |
+LL |     async gen {};
+   |               ^^ cannot infer type
+
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0282, E0658.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr
index 56f8309a69f..b4b37f0e638 100644
--- a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr
+++ b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr
@@ -1,9 +1,21 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
+  --> $DIR/feature-gate-gen_blocks.rs:12:11
+   |
+LL |     async gen {};
+   |           ^^^ expected one of 8 possible tokens
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
+  --> $DIR/feature-gate-gen_blocks.rs:25:11
+   |
+LL |     async gen {};
+   |           ^^^ expected one of 8 possible tokens
+
 error[E0422]: cannot find struct, variant or union type `gen` in this scope
   --> $DIR/feature-gate-gen_blocks.rs:5:5
    |
 LL |     gen {};
    |     ^^^ not found in this scope
 
-error: aborting due to 1 previous error
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0422`.
diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.rs b/tests/ui/feature-gates/feature-gate-gen_blocks.rs
index e2e1574a36a..ff9a0b139c0 100644
--- a/tests/ui/feature-gates/feature-gate-gen_blocks.rs
+++ b/tests/ui/feature-gates/feature-gate-gen_blocks.rs
@@ -1,15 +1,28 @@
 // revisions: e2024 none
 //[e2024] compile-flags: --edition 2024 -Zunstable-options
 
-fn main() {
+fn test_gen() {
     gen {};
     //[none]~^ ERROR: cannot find struct, variant or union type `gen`
     //[e2024]~^^ ERROR: gen blocks are experimental
     //[e2024]~| ERROR: type annotations needed
 }
 
+fn test_async_gen() {
+    async gen {};
+    //[none]~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
+    //[e2024]~^^ ERROR: gen blocks are experimental
+    //[e2024]~| ERROR: type annotations needed
+}
+
+fn main() {}
+
 #[cfg(FALSE)]
 fn foo() {
     gen {};
     //[e2024]~^ ERROR: gen blocks are experimental
+
+    async gen {};
+    //[e2024]~^ ERROR: gen blocks are experimental
+    //[none]~^^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
 }
diff --git a/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr b/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr
index d2ad372dfbc..1b87ebd9f20 100644
--- a/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr
+++ b/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr
@@ -95,7 +95,7 @@ LL | fn unsized_local() where Dst<dyn A>: Sized {
    |                          ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `Dst<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)`
-note: required because it appears within the type `Dst<dyn A>`
+note: required because it appears within the type `Dst<(dyn A + 'static)>`
   --> $DIR/feature-gate-trivial_bounds.rs:48:8
    |
 LL | struct Dst<X: ?Sized> {
diff --git a/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr
index e3ebe6cdcb8..6c9c7941eb3 100644
--- a/tests/ui/fmt/send-sync.stderr
+++ b/tests/ui/fmt/send-sync.stderr
@@ -8,9 +8,9 @@ LL |     send(format_args!("{:?}", c));
    |
    = help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`
    = note: required because it appears within the type `&core::fmt::rt::Opaque`
-note: required because it appears within the type `Argument<'_>`
+note: required because it appears within the type `core::fmt::rt::Argument<'_>`
   --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
-   = note: required because it appears within the type `[Argument<'_>]`
+   = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]`
    = note: required for `&[core::fmt::rt::Argument<'_>]` to implement `Send`
 note: required because it appears within the type `Arguments<'_>`
   --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
@@ -30,10 +30,10 @@ LL |     sync(format_args!("{:?}", c));
    |
    = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`
    = note: required because it appears within the type `&core::fmt::rt::Opaque`
-note: required because it appears within the type `Argument<'_>`
+note: required because it appears within the type `core::fmt::rt::Argument<'_>`
   --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
-   = note: required because it appears within the type `[Argument<'_>]`
-   = note: required because it appears within the type `&[Argument<'_>]`
+   = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]`
+   = note: required because it appears within the type `&[core::fmt::rt::Argument<'_>]`
 note: required because it appears within the type `Arguments<'_>`
   --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
 note: required by a bound in `sync`
diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs
index 50d4c3fddb5..8ae9494faf8 100644
--- a/tests/ui/for/issue-20605.rs
+++ b/tests/ui/for/issue-20605.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
     for item in *things { *item = 0 }
@@ -13,7 +13,7 @@ fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
     //[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
     //[next]~| ERROR the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time
     //[next]~| ERROR type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced
-    // FIXME(-Ztrait-solver=next): these error messages are horrible and have to be
+    // FIXME(-Znext-solver): these error messages are horrible and have to be
     // improved before we stabilize the new solver.
 }
 
diff --git a/tests/ui/function-pointer/unsized-ret.stderr b/tests/ui/function-pointer/unsized-ret.stderr
index dcfec53eeb9..66116273ff4 100644
--- a/tests/ui/function-pointer/unsized-ret.stderr
+++ b/tests/ui/function-pointer/unsized-ret.stderr
@@ -19,7 +19,7 @@ LL |     foo::<for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&()
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)`
-   = note: required because it appears within the type `fn(&()) -> dyn Display`
+   = note: required because it appears within the type `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`
 note: required by a bound in `foo`
   --> $DIR/unsized-ret.rs:5:11
    |
diff --git a/tests/ui/generic-associated-types/issue-102114.rs b/tests/ui/generic-associated-types/issue-102114.rs
index bb6622c0a5f..bb6369d7f8f 100644
--- a/tests/ui/generic-associated-types/issue-102114.rs
+++ b/tests/ui/generic-associated-types/issue-102114.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 trait A {
     type B<'b>;
diff --git a/tests/ui/higher-ranked/leak-check-in-selection.rs b/tests/ui/higher-ranked/leak-check-in-selection.rs
index e8d6cff856c..5b36902ffdf 100644
--- a/tests/ui/higher-ranked/leak-check-in-selection.rs
+++ b/tests/ui/higher-ranked/leak-check-in-selection.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 #![allow(coherence_leak_check)]
 
 trait Trait: Sized {
diff --git a/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs
index adb19c035bc..41f24dde01a 100644
--- a/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs
+++ b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs
@@ -1,5 +1,5 @@
 // revisions: classic next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[next] check-pass
 
 fn ice()
diff --git a/tests/ui/higher-ranked/trait-bounds/future.rs b/tests/ui/higher-ranked/trait-bounds/future.rs
index 61d86a9cb23..baeb56e5d78 100644
--- a/tests/ui/higher-ranked/trait-bounds/future.rs
+++ b/tests/ui/higher-ranked/trait-bounds/future.rs
@@ -1,7 +1,7 @@
 // ignore-tidy-linelength
 // edition:2021
 // revisions: classic next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[next] check-pass
 //[classic] known-bug: #112347
 //[classic] build-fail
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs
index 49a1584d54e..027644a280b 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[old] check-pass
 //[next] known-bug: #109764
 
diff --git a/tests/ui/hygiene/cross-crate-define-and-use.rs b/tests/ui/hygiene/cross-crate-define-and-use.rs
index 94f1adff626..62b1820235c 100644
--- a/tests/ui/hygiene/cross-crate-define-and-use.rs
+++ b/tests/ui/hygiene/cross-crate-define-and-use.rs
@@ -6,7 +6,6 @@
 // check-pass
 // aux-build:use_by_macro.rs
 
-#![feature(type_name_of_val)]
 extern crate use_by_macro;
 
 use use_by_macro::*;
diff --git a/tests/ui/impl-trait/auto-trait-coherence.rs b/tests/ui/impl-trait/auto-trait-coherence.rs
index a5cd01a87ff..e4226b20074 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.rs
+++ b/tests/ui/impl-trait/auto-trait-coherence.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 // Tests that type alias impls traits do not leak auto-traits for
 // the purposes of coherence checking
diff --git a/tests/ui/impl-trait/autoderef.rs b/tests/ui/impl-trait/autoderef.rs
index cd2cdd9e3b3..48ff8be6549 100644
--- a/tests/ui/impl-trait/autoderef.rs
+++ b/tests/ui/impl-trait/autoderef.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 
 use std::path::Path;
diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
index ed9261d0de5..4a52f82540d 100644
--- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
+++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
@@ -16,7 +16,7 @@ LL | fn fuz() -> (usize, Trait) { (42, Struct) }
    |             doesn't have a size known at compile-time
    |
    = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
-   = note: required because it appears within the type `(usize, dyn Trait)`
+   = note: required because it appears within the type `(usize, (dyn Trait + 'static))`
    = note: the return type of a function must have a statically known size
 
 error[E0308]: mismatched types
@@ -37,7 +37,7 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
    |             doesn't have a size known at compile-time
    |
    = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
-   = note: required because it appears within the type `(usize, dyn Trait)`
+   = note: required because it appears within the type `(usize, (dyn Trait + 'static))`
    = note: the return type of a function must have a statically known size
 
 error[E0746]: return type cannot have an unboxed trait object
diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs
index 698123a932d..b1f36fc247f 100644
--- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs
+++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs
@@ -1,6 +1,6 @@
 // revisions: current next
 // compile-flags: -Zverbose
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // normalize-stderr-test "DefId\([^\)]+\)" -> "DefId(..)"
 
 #![feature(rustc_attrs)]
diff --git a/tests/ui/impl-trait/in-trait/object-safety-sized.rs b/tests/ui/impl-trait/in-trait/object-safety-sized.rs
index 35afe80c97f..1a23493a94d 100644
--- a/tests/ui/impl-trait/in-trait/object-safety-sized.rs
+++ b/tests/ui/impl-trait/in-trait/object-safety-sized.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 
 fn main() {
diff --git a/tests/ui/impl-trait/in-trait/opaque-variances.rs b/tests/ui/impl-trait/in-trait/opaque-variances.rs
index 60bfab0deb5..63e56051d1a 100644
--- a/tests/ui/impl-trait/in-trait/opaque-variances.rs
+++ b/tests/ui/impl-trait/in-trait/opaque-variances.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Sized {
     ()
diff --git a/tests/ui/impl-trait/issue-103181-1.rs b/tests/ui/impl-trait/issue-103181-1.rs
index 5154abcd690..14c813cf00f 100644
--- a/tests/ui/impl-trait/issue-103181-1.rs
+++ b/tests/ui/impl-trait/issue-103181-1.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // edition:2021
 
 mod hyper {
diff --git a/tests/ui/impl-trait/recursive-coroutine.rs b/tests/ui/impl-trait/recursive-coroutine.rs
index f0bee4f120f..b82fe134a40 100644
--- a/tests/ui/impl-trait/recursive-coroutine.rs
+++ b/tests/ui/impl-trait/recursive-coroutine.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 #![feature(coroutines, coroutine_trait)]
 
 use std::ops::{Coroutine, CoroutineState};
diff --git a/tests/ui/impl-trait/reveal-during-codegen.rs b/tests/ui/impl-trait/reveal-during-codegen.rs
index 11463772eb3..7b2ca9c33f6 100644
--- a/tests/ui/impl-trait/reveal-during-codegen.rs
+++ b/tests/ui/impl-trait/reveal-during-codegen.rs
@@ -1,6 +1,6 @@
 // build-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 fn test() -> Option<impl Sized> {
     Some("")
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other.rs b/tests/ui/impl-trait/two_tait_defining_each_other.rs
index b43a7cabd05..6a9e33500e5 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[next] check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs
index 817de109fbe..8a79af19776 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 #![feature(type_alias_impl_trait)]
 
 type A = impl Foo; //[current]~ ERROR unconstrained opaque type
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other3.rs b/tests/ui/impl-trait/two_tait_defining_each_other3.rs
index 6fb9e6e7188..55def937f48 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other3.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other3.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[next] check-pass
 #![feature(type_alias_impl_trait)]
 
diff --git a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
index c177655c5ac..27c8f30ec32 100644
--- a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
+++ b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
@@ -1,5 +1,5 @@
 // A test exploiting the bug behind #25860 except with
-// implied trait bounds which currently don't exist without `-Ztrait-solver=chalk`.
+// implied trait bounds which currently don't exist.
 use std::marker::PhantomData;
 struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
 where
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
index 6ccbb5bb266..280856805e5 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
@@ -1,5 +1,3 @@
-#![deny(implied_bounds_entailment)]
-
 trait Project {
     type Ty;
 }
@@ -11,8 +9,7 @@ trait Trait {
 }
 impl Trait for () {
     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
-        //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
-        //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+        //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
         s
     }
 }
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
index 86b12cf8fa2..c8d1614a7f3 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
@@ -1,31 +1,28 @@
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
    |
 LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9
-   |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-Future incompatibility report: Future breakage diagnostic:
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31
+note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12
    |
 LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()`
+   |            ^^
+note: ...so that the method type is compatible with trait
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
    |
-   = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9
+LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `fn(&'s _, ()) -> &'static _`
+              found `fn(&_, ()) -> &'static _`
+   = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the reference type `&'static &()` does not outlive the data it points at
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
    |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
index d097bc16a22..7f3817b326a 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
@@ -1,5 +1,3 @@
-#![deny(implied_bounds_entailment)]
-
 use std::cell::RefCell;
 
 pub struct MessageListeners<'a> {
@@ -12,8 +10,7 @@ pub trait MessageListenersInterface {
 
 impl<'a> MessageListenersInterface for MessageListeners<'a> {
     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
-        //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
-        //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+        //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
         self
     }
 }
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
index a89645c128b..6a412eb5e4b 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
@@ -1,31 +1,32 @@
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility.rs:14:35
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
 LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility.rs:1:9
+note: first, the lifetime cannot outlive the lifetime `'c` as defined here...
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-Future incompatibility report: Future breakage diagnostic:
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility.rs:14:35
+LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...so that the method type is compatible with trait
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
 LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `fn(&'c MessageListeners<'_>) -> &'c MessageListeners<'c>`
+              found `fn(&MessageListeners<'_>) -> &'a MessageListeners<'_>`
+note: but, the lifetime must be valid for the lifetime `'a` as defined here...
+  --> $DIR/impl-implied-bounds-compatibility.rs:11:6
    |
-   = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility.rs:1:9
+LL | impl<'a> MessageListenersInterface for MessageListeners<'a> {
+   |      ^^
+note: ...so that the reference type `&'a MessageListeners<'_>` does not outlive the data it points at
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/inference/issue-103587.stderr b/tests/ui/inference/issue-103587.stderr
index b373fbfbb94..589cb7ea7b1 100644
--- a/tests/ui/inference/issue-103587.stderr
+++ b/tests/ui/inference/issue-103587.stderr
@@ -26,14 +26,10 @@ error[E0308]: mismatched types
 LL |     if None = x { }
    |        ^^^^^^^^ expected `bool`, found `()`
    |
-help: you might have meant to use pattern matching
+help: consider adding `let`
    |
 LL |     if let None = x { }
    |        +++
-help: you might have meant to compare for equality
-   |
-LL |     if None == x { }
-   |              +
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/inference/type-infer-generalize-ty-var.rs b/tests/ui/inference/type-infer-generalize-ty-var.rs
index 8b4a8c32bb2..6bf3c61ada8 100644
--- a/tests/ui/inference/type-infer-generalize-ty-var.rs
+++ b/tests/ui/inference/type-infer-generalize-ty-var.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![allow(non_upper_case_globals)]
 #![allow(dead_code)]
diff --git a/tests/ui/issues/issue-13167.rs b/tests/ui/issues/issue-13167.rs
index 9a9f129ec3a..747f652d4af 100644
--- a/tests/ui/issues/issue-13167.rs
+++ b/tests/ui/issues/issue-13167.rs
@@ -1,7 +1,7 @@
 // check-pass
 // pretty-expanded FIXME #23616
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 use std::slice;
 
diff --git a/tests/ui/issues/issue-13407.rs b/tests/ui/issues/issue-13407.rs
index 7ea81ffb59e..7794be37b85 100644
--- a/tests/ui/issues/issue-13407.rs
+++ b/tests/ui/issues/issue-13407.rs
@@ -4,6 +4,6 @@ mod A {
 
 fn main() {
     A::C = 1;
-    //~^ ERROR: invalid left-hand side of assignment
-    //~| ERROR: struct `C` is private
+    //~^ ERROR: mismatched types
+    //~| ERROR: unit struct `C` is private
 }
diff --git a/tests/ui/issues/issue-13407.stderr b/tests/ui/issues/issue-13407.stderr
index 54b6c640d9d..ac2eb6581fe 100644
--- a/tests/ui/issues/issue-13407.stderr
+++ b/tests/ui/issues/issue-13407.stderr
@@ -10,15 +10,18 @@ note: the unit struct `C` is defined here
 LL |     struct C;
    |     ^^^^^^^^^
 
-error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-13407.rs:6:10
+error[E0308]: mismatched types
+  --> $DIR/issue-13407.rs:6:5
    |
+LL |     struct C;
+   |     -------- unit struct defined here
+...
 LL |     A::C = 1;
-   |     ---- ^
+   |     ^^^^   - this expression has type `{integer}`
    |     |
-   |     cannot assign to this expression
+   |     expected integer, found `C`
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0070, E0603.
-For more information about an error, try `rustc --explain E0070`.
+Some errors have detailed explanations: E0308, E0603.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/issues/issue-15734.rs b/tests/ui/issues/issue-15734.rs
index 27410d4c3b0..77517f61813 100644
--- a/tests/ui/issues/issue-15734.rs
+++ b/tests/ui/issues/issue-15734.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 use std::ops::Index;
 
diff --git a/tests/ui/issues/issue-21763.stderr b/tests/ui/issues/issue-21763.stderr
index 3d623985cbb..135b705eeef 100644
--- a/tests/ui/issues/issue-21763.stderr
+++ b/tests/ui/issues/issue-21763.stderr
@@ -7,7 +7,7 @@ LL |     foo::<HashMap<Rc<()>, Rc<()>>>();
    = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>`
    = note: required because it appears within the type `(Rc<()>, Rc<()>)`
    = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send`
-note: required because it appears within the type `HashMap<Rc<()>, Rc<()>, RandomState>`
+note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>`
   --> $HASHBROWN_SRC_LOCATION
 note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>`
   --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr
index 269193f73b4..c0d516e3f62 100644
--- a/tests/ui/kindck/kindck-send-object1.stderr
+++ b/tests/ui/kindck/kindck-send-object1.stderr
@@ -20,7 +20,7 @@ LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |
    = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)`
    = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send`
-note: required because it appears within the type `Box<dyn Dummy>`
+note: required because it appears within the type `Box<(dyn Dummy + 'a)>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object1.rs:5:18
diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs
index 3d33adf6831..21bd7187e15 100644
--- a/tests/ui/lang-items/lang-item-generic-requirements.rs
+++ b/tests/ui/lang-items/lang-item-generic-requirements.rs
@@ -22,6 +22,8 @@ trait MyIndex<'a, T> {}
 #[lang = "phantom_data"]
 //~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument
 struct MyPhantomData<T, U>;
+//~^ ERROR parameter `T` is never used
+//~| ERROR parameter `U` is never used
 
 #[lang = "owned_box"]
 //~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument
@@ -40,6 +42,7 @@ fn ice() {
     let r = 5;
     let a = 6;
     r + a;
+    //~^ ERROR cannot add `{integer}` to `{integer}`
 
     // Use drop in place
     my_ptr_drop();
diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr
index 4d349a25f9c..8072e6797e4 100644
--- a/tests/ui/lang-items/lang-item-generic-requirements.stderr
+++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr
@@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>;
    |                     ------ this struct has 2 generic arguments
 
 error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument
-  --> $DIR/lang-item-generic-requirements.rs:26:1
+  --> $DIR/lang-item-generic-requirements.rs:28:1
    |
 LL | #[lang = "owned_box"]
    | ^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL | struct Foo;
    |           - this struct has 0 generic arguments
 
 error[E0718]: `start` language item must be applied to a function with 1 generic argument
-  --> $DIR/lang-item-generic-requirements.rs:32:1
+  --> $DIR/lang-item-generic-requirements.rs:34:1
    |
 LL | #[lang = "start"]
    | ^^^^^^^^^^^^^^^^^
@@ -50,6 +50,35 @@ LL |
 LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
    |         - this function has 0 generic arguments
 
-error: aborting due to 6 previous errors
+error[E0392]: parameter `T` is never used
+  --> $DIR/lang-item-generic-requirements.rs:24:22
+   |
+LL | struct MyPhantomData<T, U>;
+   |                      ^ unused parameter
+   |
+   = help: consider removing `T` or referring to it in a field
+   = help: if you intended `T` to be a const parameter, use `const T: usize` instead
+
+error[E0392]: parameter `U` is never used
+  --> $DIR/lang-item-generic-requirements.rs:24:25
+   |
+LL | struct MyPhantomData<T, U>;
+   |                         ^ unused parameter
+   |
+   = help: consider removing `U` or referring to it in a field
+   = help: if you intended `U` to be a const parameter, use `const U: usize` instead
+
+error[E0369]: cannot add `{integer}` to `{integer}`
+  --> $DIR/lang-item-generic-requirements.rs:44:7
+   |
+LL |     r + a;
+   |     - ^ - {integer}
+   |     |
+   |     {integer}
+
+error: requires `copy` lang_item
+
+error: aborting due to 10 previous errors
 
-For more information about this error, try `rustc --explain E0718`.
+Some errors have detailed explanations: E0369, E0392, E0718.
+For more information about an error, try `rustc --explain E0369`.
diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs
index 745eadb9625..ec9a6739975 100644
--- a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs
+++ b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(lazy_type_alias)]
 //~^ WARN the feature `lazy_type_alias` is incomplete
diff --git a/tests/ui/lint/ptr_null_checks.rs b/tests/ui/lint/ptr_null_checks.rs
index 3028084e962..4925019be1e 100644
--- a/tests/ui/lint/ptr_null_checks.rs
+++ b/tests/ui/lint/ptr_null_checks.rs
@@ -1,7 +1,5 @@
 // check-pass
 
-#![feature(ptr_from_ref)]
-
 use std::ptr;
 
 extern "C" fn c_fn() {}
diff --git a/tests/ui/lint/ptr_null_checks.stderr b/tests/ui/lint/ptr_null_checks.stderr
index 0edc1b86536..70a27790c5b 100644
--- a/tests/ui/lint/ptr_null_checks.stderr
+++ b/tests/ui/lint/ptr_null_checks.stderr
@@ -1,5 +1,5 @@
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:14:8
+  --> $DIR/ptr_null_checks.rs:12:8
    |
 LL |     if (fn_ptr as *mut ()).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^
@@ -10,7 +10,7 @@ LL |     if (fn_ptr as *mut ()).is_null() {}
    = note: `#[warn(useless_ptr_null_checks)]` on by default
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:16:8
+  --> $DIR/ptr_null_checks.rs:14:8
    |
 LL |     if (fn_ptr as *const u8).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL |     if (fn_ptr as *const u8).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:18:8
+  --> $DIR/ptr_null_checks.rs:16:8
    |
 LL |     if (fn_ptr as *const ()) == std::ptr::null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,7 +30,7 @@ LL |     if (fn_ptr as *const ()) == std::ptr::null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:20:8
+  --> $DIR/ptr_null_checks.rs:18:8
    |
 LL |     if (fn_ptr as *mut ()) == std::ptr::null_mut() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     if (fn_ptr as *mut ()) == std::ptr::null_mut() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:22:8
+  --> $DIR/ptr_null_checks.rs:20:8
    |
 LL |     if (fn_ptr as *const ()) == (0 as *const ()) {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +50,7 @@ LL |     if (fn_ptr as *const ()) == (0 as *const ()) {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:24:8
+  --> $DIR/ptr_null_checks.rs:22:8
    |
 LL |     if <*const _>::is_null(fn_ptr as *const ()) {}
    |        ^^^^^^^^^^^^^^^^^^^^------^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL |     if <*const _>::is_null(fn_ptr as *const ()) {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:26:8
+  --> $DIR/ptr_null_checks.rs:24:8
    |
 LL |     if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:28:8
+  --> $DIR/ptr_null_checks.rs:26:8
    |
 LL |     if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:30:8
+  --> $DIR/ptr_null_checks.rs:28:8
    |
 LL |     if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() {}
    |        ^^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() {
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:32:8
+  --> $DIR/ptr_null_checks.rs:30:8
    |
 LL |     if (fn_ptr as fn() as *const ()).is_null() {}
    |        ^--------------^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +100,7 @@ LL |     if (fn_ptr as fn() as *const ()).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:34:8
+  --> $DIR/ptr_null_checks.rs:32:8
    |
 LL |     if (c_fn as *const fn()).is_null() {}
    |        ^----^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,7 +110,7 @@ LL |     if (c_fn as *const fn()).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:38:8
+  --> $DIR/ptr_null_checks.rs:36:8
    |
 LL |     if (&mut 8 as *mut i32).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,13 +118,13 @@ LL |     if (&mut 8 as *mut i32).is_null() {}
    |         expression has type `&mut i32`
 
 warning: returned pointer of `from_mut` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:40:8
+  --> $DIR/ptr_null_checks.rs:38:8
    |
 LL |     if ptr::from_mut(&mut 8).is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:42:8
+  --> $DIR/ptr_null_checks.rs:40:8
    |
 LL |     if (&8 as *const i32).is_null() {}
    |        ^--^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,25 +132,25 @@ LL |     if (&8 as *const i32).is_null() {}
    |         expression has type `&i32`
 
 warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:44:8
+  --> $DIR/ptr_null_checks.rs:42:8
    |
 LL |     if ptr::from_ref(&8).is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:46:8
+  --> $DIR/ptr_null_checks.rs:44:8
    |
 LL |     if ptr::from_ref(&8).cast_mut().is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:48:8
+  --> $DIR/ptr_null_checks.rs:46:8
    |
 LL |     if (ptr::from_ref(&8).cast_mut() as *mut i32).is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:50:8
+  --> $DIR/ptr_null_checks.rs:48:8
    |
 LL |     if (&8 as *const i32) == std::ptr::null() {}
    |        ^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -158,7 +158,7 @@ LL |     if (&8 as *const i32) == std::ptr::null() {}
    |         expression has type `&i32`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:53:8
+  --> $DIR/ptr_null_checks.rs:51:8
    |
 LL |     if (ref_num as *const i32) == std::ptr::null() {}
    |        ^-------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -166,7 +166,7 @@ LL |     if (ref_num as *const i32) == std::ptr::null() {}
    |         expression has type `&i32`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:55:8
+  --> $DIR/ptr_null_checks.rs:53:8
    |
 LL |     if (b"\0" as *const u8).is_null() {}
    |        ^-----^^^^^^^^^^^^^^^^^^^^^^^^
@@ -174,7 +174,7 @@ LL |     if (b"\0" as *const u8).is_null() {}
    |         expression has type `&[u8; 1]`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:57:8
+  --> $DIR/ptr_null_checks.rs:55:8
    |
 LL |     if ("aa" as *const str).is_null() {}
    |        ^----^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -182,7 +182,7 @@ LL |     if ("aa" as *const str).is_null() {}
    |         expression has type `&str`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:59:8
+  --> $DIR/ptr_null_checks.rs:57:8
    |
 LL |     if (&[1, 2] as *const i32).is_null() {}
    |        ^-------^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -190,7 +190,7 @@ LL |     if (&[1, 2] as *const i32).is_null() {}
    |         expression has type `&[i32; 2]`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:61:8
+  --> $DIR/ptr_null_checks.rs:59:8
    |
 LL |     if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {}
    |        ^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +198,7 @@ LL |     if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {}
    |         expression has type `&mut [i32; 2]`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:63:8
+  --> $DIR/ptr_null_checks.rs:61:8
    |
 LL |     if (static_i32() as *const i32).is_null() {}
    |        ^------------^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -206,7 +206,7 @@ LL |     if (static_i32() as *const i32).is_null() {}
    |         expression has type `&i32`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:65:8
+  --> $DIR/ptr_null_checks.rs:63:8
    |
 LL |     if (&*{ static_i32() } as *const i32).is_null() {}
    |        ^------------------^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -214,13 +214,13 @@ LL |     if (&*{ static_i32() } as *const i32).is_null() {}
    |         expression has type `&i32`
 
 warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:69:8
+  --> $DIR/ptr_null_checks.rs:67:8
    |
 LL |     if ptr::NonNull::new(&mut 8).unwrap().as_ptr().is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:71:8
+  --> $DIR/ptr_null_checks.rs:69:8
    |
 LL |     if ptr::NonNull::<u8>::dangling().as_ptr().is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs
index 25e0c75f70d..84267c0af03 100644
--- a/tests/ui/lint/reference_casting.rs
+++ b/tests/ui/lint/reference_casting.rs
@@ -1,7 +1,5 @@
 // check-fail
 
-#![feature(ptr_from_ref)]
-
 extern "C" {
     // N.B., mutability can be easily incorrect in FFI calls -- as
     // in C, the default is mutable pointers.
@@ -116,6 +114,13 @@ unsafe fn assign_to_ref() {
     let value = num as *const i32 as *mut i32;
     *value = 1;
     //~^ ERROR assigning to `&T` is undefined behavior
+    let value = num as *const i32;
+    let value = value as *mut i32;
+    *value = 1;
+    //~^ ERROR assigning to `&T` is undefined behavior
+    let value = num as *const i32 as *mut i32;
+    *value = 1;
+    //~^ ERROR assigning to `&T` is undefined behavior
     let value_rebind = value;
     *value_rebind = 1;
     //~^ ERROR assigning to `&T` is undefined behavior
diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr
index 8d5f8da6852..374a58d7b7b 100644
--- a/tests/ui/lint/reference_casting.stderr
+++ b/tests/ui/lint/reference_casting.stderr
@@ -1,5 +1,5 @@
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:19:16
+  --> $DIR/reference_casting.rs:17:16
    |
 LL |     let _num = &mut *(num as *const i32 as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let _num = &mut *(num as *const i32 as *mut i32);
    = note: `#[deny(invalid_reference_casting)]` on by default
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:21:16
+  --> $DIR/reference_casting.rs:19:16
    |
 LL |     let _num = &mut *(num as *const i32).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     let _num = &mut *(num as *const i32).cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:23:16
+  --> $DIR/reference_casting.rs:21:16
    |
 LL |     let _num = &mut *std::ptr::from_ref(num).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     let _num = &mut *std::ptr::from_ref(num).cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:25:16
+  --> $DIR/reference_casting.rs:23:16
    |
 LL |     let _num = &mut *std::ptr::from_ref({ num }).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL |     let _num = &mut *std::ptr::from_ref({ num }).cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:27:16
+  --> $DIR/reference_casting.rs:25:16
    |
 LL |     let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:29:16
+  --> $DIR/reference_casting.rs:27:16
    |
 LL |     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:31:16
+  --> $DIR/reference_casting.rs:29:16
    |
 LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:33:16
+  --> $DIR/reference_casting.rs:31:16
    |
 LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_const().cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_cons
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:35:16
+  --> $DIR/reference_casting.rs:33:16
    |
 LL |     let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:37:16
+  --> $DIR/reference_casting.rs:35:16
    |
 LL |     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:39:16
+  --> $DIR/reference_casting.rs:37:16
    |
 LL |     let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +88,7 @@ LL |     let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:41:16
+  --> $DIR/reference_casting.rs:39:16
    |
 LL |       let _num = &mut *std::cell::UnsafeCell::raw_get(
    |  ________________^
@@ -100,7 +100,7 @@ LL | |     );
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:47:16
+  --> $DIR/reference_casting.rs:45:16
    |
 LL |     let deferred = num as *const i32 as *mut i32;
    |                    ----------------------------- casting happend here
@@ -110,7 +110,7 @@ LL |     let _num = &mut *deferred;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:50:16
+  --> $DIR/reference_casting.rs:48:16
    |
 LL |     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32;
    |                    ---------------------------------------------------------------------------- casting happend here
@@ -120,7 +120,7 @@ LL |     let _num = &mut *deferred;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:53:16
+  --> $DIR/reference_casting.rs:51:16
    |
 LL |     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32;
    |                    ---------------------------------------------------------------------------- casting happend here
@@ -131,7 +131,7 @@ LL |     let _num = &mut *deferred_rebind;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:55:16
+  --> $DIR/reference_casting.rs:53:16
    |
 LL |     let _num = &mut *(num as *const _ as usize as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -139,7 +139,7 @@ LL |     let _num = &mut *(num as *const _ as usize as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:57:16
+  --> $DIR/reference_casting.rs:55:16
    |
 LL |     let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -147,7 +147,7 @@ LL |     let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) a
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:64:16
+  --> $DIR/reference_casting.rs:62:16
    |
 LL |     let num = NUM as *const i32 as *mut i32;
    |               ----------------------------- casting happend here
@@ -158,7 +158,7 @@ LL |     let _num = &mut *num;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:68:16
+  --> $DIR/reference_casting.rs:66:16
    |
 LL |     let _num = &mut *(cell as *const _ as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -167,7 +167,7 @@ LL |     let _num = &mut *(cell as *const _ as *mut i32);
    = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:72:9
+  --> $DIR/reference_casting.rs:70:9
    |
 LL |         &mut *((this as *const _) as *mut _)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -175,7 +175,7 @@ LL |         &mut *((this as *const _) as *mut _)
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:77:18
+  --> $DIR/reference_casting.rs:75:18
    |
 LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -183,7 +183,7 @@ LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:82:18
+  --> $DIR/reference_casting.rs:80:18
    |
 LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -191,7 +191,7 @@ LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:92:5
+  --> $DIR/reference_casting.rs:90:5
    |
 LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:94:5
+  --> $DIR/reference_casting.rs:92:5
    |
 LL |     *(a as *const _ as *mut String) += " world";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -207,7 +207,7 @@ LL |     *(a as *const _ as *mut String) += " world";
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:96:5
+  --> $DIR/reference_casting.rs:94:5
    |
 LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -215,7 +215,7 @@ LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:98:5
+  --> $DIR/reference_casting.rs:96:5
    |
 LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -223,7 +223,7 @@ LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:100:5
+  --> $DIR/reference_casting.rs:98:5
    |
 LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -231,7 +231,7 @@ LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:102:5
+  --> $DIR/reference_casting.rs:100:5
    |
 LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -239,7 +239,7 @@ LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:104:5
+  --> $DIR/reference_casting.rs:102:5
    |
 LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -247,7 +247,7 @@ LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:106:5
+  --> $DIR/reference_casting.rs:104:5
    |
 LL |     *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:108:5
+  --> $DIR/reference_casting.rs:106:5
    |
 LL | /     std::ptr::write(
 LL | |
@@ -267,7 +267,7 @@ LL | |     );
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:113:5
+  --> $DIR/reference_casting.rs:111:5
    |
 LL |     *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -276,7 +276,27 @@ LL |     *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5;
    = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:117:5
+  --> $DIR/reference_casting.rs:115:5
+   |
+LL |     let value = num as *const i32 as *mut i32;
+   |                 ----------------------------- casting happend here
+LL |     *value = 1;
+   |     ^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:119:5
+   |
+LL |     let value = value as *mut i32;
+   |                 ----------------- casting happend here
+LL |     *value = 1;
+   |     ^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:122:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -286,7 +306,7 @@ LL |     *value = 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:120:5
+  --> $DIR/reference_casting.rs:125:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -297,7 +317,7 @@ LL |     *value_rebind = 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:122:5
+  --> $DIR/reference_casting.rs:127:5
    |
 LL |     *(num as *const i32).cast::<i32>().cast_mut() = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -305,7 +325,7 @@ LL |     *(num as *const i32).cast::<i32>().cast_mut() = 2;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:124:5
+  --> $DIR/reference_casting.rs:129:5
    |
 LL |     *(num as *const _ as usize as *mut i32) = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -313,7 +333,7 @@ LL |     *(num as *const _ as usize as *mut i32) = 2;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:126:5
+  --> $DIR/reference_casting.rs:131:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -324,7 +344,7 @@ LL |     std::ptr::write(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:128:5
+  --> $DIR/reference_casting.rs:133:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -335,7 +355,7 @@ LL |     std::ptr::write_unaligned(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:130:5
+  --> $DIR/reference_casting.rs:135:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -346,12 +366,12 @@ LL |     std::ptr::write_volatile(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:134:9
+  --> $DIR/reference_casting.rs:139:9
    |
 LL |         *(this as *const _ as *mut _) = a;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
-error: aborting due to 40 previous errors
+error: aborting due to 42 previous errors
 
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs b/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs
index ab8d95a41d0..1b8ce10ccce 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs
+++ b/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs
@@ -10,11 +10,11 @@ fn main() {
                 $(
                     // inner-most repetition
                     $(
-                        ${ignore(l)} ${index()}, ${length()},
+                        ${ignore($l)} ${index()}, ${length()},
                     )*
-                    ${count(l)}, ${index()}, ${length()},
+                    ${count($l)}, ${index()}, ${length()},
                 )*
-                ${count(l)},
+                ${count($l)},
             ]
         };
     }
@@ -72,30 +72,30 @@ fn main() {
             &[
                 $( $( $(
                     &[
-                        ${ignore(i)} ${count(i, 0)},
+                        ${ignore($i)} ${count($i, 0)},
                     ][..],
                 )* )* )*
 
                 $( $(
                     &[
-                        ${ignore(i)} ${count(i, 0)},
-                        ${ignore(i)} ${count(i, 1)},
+                        ${ignore($i)} ${count($i, 0)},
+                        ${ignore($i)} ${count($i, 1)},
                     ][..],
                 )* )*
 
                 $(
                     &[
-                        ${ignore(i)} ${count(i, 0)},
-                        ${ignore(i)} ${count(i, 1)},
-                        ${ignore(i)} ${count(i, 2)},
+                        ${ignore($i)} ${count($i, 0)},
+                        ${ignore($i)} ${count($i, 1)},
+                        ${ignore($i)} ${count($i, 2)},
                     ][..],
                 )*
 
                 &[
-                    ${count(i, 0)},
-                    ${count(i, 1)},
-                    ${count(i, 2)},
-                    ${count(i, 3)},
+                    ${count($i, 0)},
+                    ${count($i, 1)},
+                    ${count($i, 2)},
+                    ${count($i, 3)},
                 ][..]
             ][..]
         }
@@ -133,23 +133,23 @@ fn main() {
             &[7][..],
 
             // (a b c) (d e f)
-            &[2, 6][..],
+            &[6, 2][..],
             // (g h) (i j k l m)
-            &[2, 7][..],
+            &[7, 2][..],
             // (n)
             &[1, 1][..],
             // (o) (p q) (r s)
-            &[3, 5][..],
+            &[5, 3][..],
             // (t u v w x y z)
-            &[1, 7][..],
+            &[7, 1][..],
 
             // [ (a b c) (d e f) ]
             // [ (g h) (i j k l m) ]
             // [ (n) ]
-            &[3, 5, 14][..],
+            &[14, 5, 3][..],
             // [ (o) (p q) (r s) ]
             // [ (t u v w x y z) ]
-            &[2, 4, 12][..],
+            &[12, 4, 2][..],
 
             // {
             //     [ (a b c) (d e f) ]
@@ -160,7 +160,7 @@ fn main() {
             //     [ (o) (p q) (r s) ]
             //     [ (t u v w x y z) ]
             // }
-            &[2, 5, 9, 26][..]
+            &[26, 9, 5, 2][..]
         ][..]
     );
 
@@ -170,31 +170,31 @@ fn main() {
             &[
                 $( $( $( $(
                     &[
-                        ${ignore(i)} ${length(3)},
-                        ${ignore(i)} ${length(2)},
-                        ${ignore(i)} ${length(1)},
-                        ${ignore(i)} ${length(0)},
+                        ${ignore($i)} ${length(3)},
+                        ${ignore($i)} ${length(2)},
+                        ${ignore($i)} ${length(1)},
+                        ${ignore($i)} ${length(0)},
                     ][..],
                 )* )* )* )*
 
                 $( $( $(
                     &[
-                        ${ignore(i)} ${length(2)},
-                        ${ignore(i)} ${length(1)},
-                        ${ignore(i)} ${length(0)},
+                        ${ignore($i)} ${length(2)},
+                        ${ignore($i)} ${length(1)},
+                        ${ignore($i)} ${length(0)},
                     ][..],
                 )* )* )*
 
                 $( $(
                     &[
-                        ${ignore(i)} ${length(1)},
-                        ${ignore(i)} ${length(0)},
+                        ${ignore($i)} ${length(1)},
+                        ${ignore($i)} ${length(0)},
                     ][..],
                 )* )*
 
                 $(
                     &[
-                        ${ignore(i)} ${length(0)},
+                        ${ignore($i)} ${length(0)},
                     ][..],
                 )*
             ][..]
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs b/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs
index d05cd1b31bc..950e70153ba 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs
+++ b/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs
@@ -5,14 +5,14 @@
 /// Count the number of idents in a macro repetition.
 macro_rules! count_idents {
     ( $( $i:ident ),* ) => {
-        ${count(i)}
+        ${count($i)}
     };
 }
 
 /// Count the number of idents in a 2-dimensional macro repetition.
 macro_rules! count_idents_2 {
     ( $( [ $( $i:ident ),* ] ),* ) => {
-        ${count(i)}
+        ${count($i)}
     };
 }
 
@@ -21,17 +21,17 @@ macro_rules! count_depth_limits {
     ( $( { $( [ $( $outer:ident : ( $( $inner:ident )* ) )* ] )* } )* ) => {
         (
             (
-                ${count(inner)},
-                ${count(inner, 0)},
-                ${count(inner, 1)},
-                ${count(inner, 2)},
-                ${count(inner, 3)},
+                ${count($inner)},
+                ${count($inner, 0)},
+                ${count($inner, 1)},
+                ${count($inner, 2)},
+                ${count($inner, 3)},
             ),
             (
-                ${count(outer)},
-                ${count(outer, 0)},
-                ${count(outer, 1)},
-                ${count(outer, 2)},
+                ${count($outer)},
+                ${count($outer, 0)},
+                ${count($outer, 1)},
+                ${count($outer, 2)},
             ),
         )
     };
@@ -43,7 +43,7 @@ macro_rules! count_depth_limits {
 /// repetition binding.
 macro_rules! enumerate_literals {
     ( $( ($l:stmt) ),* ) => {
-        [$( ${ignore(l)} (${index()}, ${length()}) ),*]
+        [$( ${ignore($l)} (${index()}, ${length()}) ),*]
     };
 }
 
@@ -77,7 +77,7 @@ macro_rules! make_count_adders {
         $(
             macro_rules! $i {
                 ( $$( $$j:ident ),* ) => {
-                    $b + $${count(j)}
+                    $b + $${count($j)}
                 };
             }
         )*
@@ -122,7 +122,7 @@ fn main() {
                 [ T: (t u v w x y z) ]
             }
         },
-        ((26, 2, 5, 9, 26), (9, 2, 5, 9))
+        ((26, 26, 9, 5, 2), (9, 9, 5, 2))
     );
     assert_eq!(enumerate_literals![("foo"), ("bar")], [(0, 2), (1, 2)]);
     assert_eq!(
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs
index 9cc572c23a1..3000bfed6a8 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs
+++ b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs
@@ -1,7 +1,7 @@
 #![feature(macro_metavar_expr)]
 
 macro_rules! foo {
-    ( $( $($t:ident),* );* ) => { ${count(t,)} }
+    ( $( $($t:ident),* );* ) => { ${count($t,)} }
     //~^ ERROR `count` followed by a comma must have an associated
     //~| ERROR expected expression, found `$`
 }
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr
index e9317a5c347..fd53c1686cf 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr
+++ b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr
@@ -1,13 +1,13 @@
 error: `count` followed by a comma must have an associated index indicating its depth
   --> $DIR/issue-111904.rs:4:37
    |
-LL |     ( $( $($t:ident),* );* ) => { ${count(t,)} }
+LL |     ( $( $($t:ident),* );* ) => { ${count($t,)} }
    |                                     ^^^^^
 
 error: expected expression, found `$`
   --> $DIR/issue-111904.rs:4:35
    |
-LL |     ( $( $($t:ident),* );* ) => { ${count(t,)} }
+LL |     ( $( $($t:ident),* );* ) => { ${count($t,)} }
    |                                   ^ expected expression
 ...
 LL |     foo!(a, a; b, b);
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs b/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs
index b954967c4fe..04924f0efa6 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs
+++ b/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs
@@ -13,17 +13,17 @@ macro_rules! example {
     ( $( [ $( ( $( $x:ident )* ) )* ] )* ) => {
         Example {
             _indexes: &[],
-            _counts: &[${count(x, 0)}, ${count(x, 1)}, ${count(x, 2)}],
+            _counts: &[${count($x, 0)}, ${count($x, 1)}, ${count($x, 2)}],
             _nested: vec![
             $(
                 Example {
                     _indexes: &[(${index()}, ${length()})],
-                    _counts: &[${count(x, 0)}, ${count(x, 1)}],
+                    _counts: &[${count($x, 0)}, ${count($x, 1)}],
                     _nested: vec![
                     $(
                         Example {
                             _indexes: &[(${index(1)}, ${length(1)}), (${index()}, ${length()})],
-                            _counts: &[${count(x)}],
+                            _counts: &[${count($x)}],
                             _nested: vec![
                             $(
                                 Example {
@@ -34,7 +34,7 @@ macro_rules! example {
                                     ],
                                     _counts: &[],
                                     _nested: vec![],
-                                    ${ignore(x)}
+                                    ${ignore($x)}
                                 }
                             ),*
                             ]
@@ -49,9 +49,9 @@ macro_rules! example {
 }
 
 static EXPECTED: &str = concat!(
-    "Example { _indexes: [], _counts: [2, 4, 13], _nested: [",
+    "Example { _indexes: [], _counts: [13, 4, 2], _nested: [",
     concat!(
-        "Example { _indexes: [(0, 2)], _counts: [3, 10], _nested: [",
+        "Example { _indexes: [(0, 2)], _counts: [10, 3], _nested: [",
         concat!(
             "Example { _indexes: [(0, 2), (0, 3)], _counts: [4], _nested: [",
             concat!(
@@ -77,7 +77,7 @@ static EXPECTED: &str = concat!(
             "] }",
         ),
         "] }, ",
-        "Example { _indexes: [(1, 2)], _counts: [1, 3], _nested: [",
+        "Example { _indexes: [(1, 2)], _counts: [3, 1], _nested: [",
         concat!(
             "Example { _indexes: [(1, 2), (0, 1)], _counts: [3], _nested: [",
             concat!(
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs
index 6a0d68bd6b1..d195506af36 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs
+++ b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs
@@ -3,9 +3,9 @@
 macro_rules! a {
     ( $( { $( [ $( ( $( $foo:ident )* ) )* ] )* } )* ) => {
         (
-            ${count(foo, 0)},
-            ${count(foo, 10)},
-            //~^ ERROR depth parameter on meta-variable expression `count` must be less than 4
+            ${count($foo, 0)},
+            ${count($foo, 10)},
+            //~^ ERROR depth parameter of meta-variable expression `count` must be less than 4
         )
     };
 }
@@ -14,10 +14,10 @@ macro_rules! b {
     ( $( { $( [ $( $foo:ident )* ] )* } )* ) => {
         (
             $( $( $(
-                ${ignore(foo)}
+                ${ignore($foo)}
                 ${index(0)},
                 ${index(10)},
-                //~^ ERROR depth parameter on meta-variable expression `index` must be less than 3
+                //~^ ERROR depth parameter of meta-variable expression `index` must be less than 3
             )* )* )*
         )
     };
@@ -27,10 +27,10 @@ macro_rules! c {
     ( $( { $( $foo:ident )* } )* ) => {
         (
             $( $(
-                ${ignore(foo)}
+                ${ignore($foo)}
                 ${length(0)}
                 ${length(10)}
-                //~^ ERROR depth parameter on meta-variable expression `length` must be less than 2
+                //~^ ERROR depth parameter of meta-variable expression `length` must be less than 2
             )* )*
         )
     };
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr
index 236122b6465..f757b8af219 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr
+++ b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr
@@ -1,16 +1,16 @@
-error: depth parameter on meta-variable expression `count` must be less than 4
+error: depth parameter of meta-variable expression `count` must be less than 4
   --> $DIR/out-of-bounds-arguments.rs:7:14
    |
-LL |             ${count(foo, 10)},
-   |              ^^^^^^^^^^^^^^^^
+LL |             ${count($foo, 10)},
+   |              ^^^^^^^^^^^^^^^^^
 
-error: depth parameter on meta-variable expression `index` must be less than 3
+error: depth parameter of meta-variable expression `index` must be less than 3
   --> $DIR/out-of-bounds-arguments.rs:19:18
    |
 LL |                 ${index(10)},
    |                  ^^^^^^^^^^^
 
-error: depth parameter on meta-variable expression `length` must be less than 2
+error: depth parameter of meta-variable expression `length` must be less than 2
   --> $DIR/out-of-bounds-arguments.rs:32:18
    |
 LL |                 ${length(10)}
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs
index b4fef11f1e2..53d045700f9 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs
+++ b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs
@@ -1,6 +1,6 @@
 macro_rules! count {
     ( $( $e:stmt ),* ) => {
-        ${ count(e) }
+        ${ count($e) }
         //~^ ERROR meta-variable expressions are unstable
     };
 }
@@ -19,7 +19,7 @@ macro_rules! dollar_dollar {
 
 macro_rules! index {
     ( $( $e:stmt ),* ) => {
-        $( ${ignore(e)} ${index()} )*
+        $( ${ignore($e)} ${index()} )*
         //~^ ERROR meta-variable expressions are unstable
         //~| ERROR meta-variable expressions are unstable
     };
@@ -27,14 +27,14 @@ macro_rules! index {
 
 macro_rules! ignore {
     ( $( $i:stmt ),* ) => {{
-        0 $( + 1 ${ignore(i)} )*
+        0 $( + 1 ${ignore($i)} )*
         //~^ ERROR meta-variable expressions are unstable
     }};
 }
 
 macro_rules! length {
     ( $( $e:stmt ),* ) => {
-        $( ${ignore(e)} ${length()} )*
+        $( ${ignore($e)} ${length()} )*
         //~^ ERROR meta-variable expressions are unstable
         //~| ERROR meta-variable expressions are unstable
     };
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr
index ecf598b104d..2c2cbb15b72 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr
+++ b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr
@@ -1,8 +1,8 @@
 error[E0658]: meta-variable expressions are unstable
   --> $DIR/required-feature.rs:3:10
    |
-LL |         ${ count(e) }
-   |          ^^^^^^^^^^^^
+LL |         ${ count($e) }
+   |          ^^^^^^^^^^^^^
    |
    = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
    = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
@@ -46,17 +46,17 @@ LL |             ( $$( $$any:tt )* ) => { $$( $$any )* };
 error[E0658]: meta-variable expressions are unstable
   --> $DIR/required-feature.rs:22:13
    |
-LL |         $( ${ignore(e)} ${index()} )*
-   |             ^^^^^^^^^^^
+LL |         $( ${ignore($e)} ${index()} )*
+   |             ^^^^^^^^^^^^
    |
    = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
    = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
 
 error[E0658]: meta-variable expressions are unstable
-  --> $DIR/required-feature.rs:22:26
+  --> $DIR/required-feature.rs:22:27
    |
-LL |         $( ${ignore(e)} ${index()} )*
-   |                          ^^^^^^^^^
+LL |         $( ${ignore($e)} ${index()} )*
+   |                           ^^^^^^^^^
    |
    = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
    = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
@@ -64,8 +64,8 @@ LL |         $( ${ignore(e)} ${index()} )*
 error[E0658]: meta-variable expressions are unstable
   --> $DIR/required-feature.rs:30:19
    |
-LL |         0 $( + 1 ${ignore(i)} )*
-   |                   ^^^^^^^^^^^
+LL |         0 $( + 1 ${ignore($i)} )*
+   |                   ^^^^^^^^^^^^
    |
    = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
    = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
@@ -73,17 +73,17 @@ LL |         0 $( + 1 ${ignore(i)} )*
 error[E0658]: meta-variable expressions are unstable
   --> $DIR/required-feature.rs:37:13
    |
-LL |         $( ${ignore(e)} ${length()} )*
-   |             ^^^^^^^^^^^
+LL |         $( ${ignore($e)} ${length()} )*
+   |             ^^^^^^^^^^^^
    |
    = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
    = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
 
 error[E0658]: meta-variable expressions are unstable
-  --> $DIR/required-feature.rs:37:26
+  --> $DIR/required-feature.rs:37:27
    |
-LL |         $( ${ignore(e)} ${length()} )*
-   |                          ^^^^^^^^^^
+LL |         $( ${ignore($e)} ${length()} )*
+   |                           ^^^^^^^^^^
    |
    = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
    = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs
index fdf16442d2a..05c65fe8690 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs
+++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs
@@ -5,24 +5,17 @@
 // `round` = Left hand side round brackets
 
 macro_rules! curly__no_rhs_dollar__round {
-    ( $( $i:ident ),* ) => { ${ count(i) } };
+    ( $( $i:ident ),* ) => { ${ count($i) } };
 }
 
 macro_rules! curly__no_rhs_dollar__no_round {
-    ( $i:ident ) => { ${ count(i) } };
+    ( $i:ident ) => { ${ count($i) } };
     //~^ ERROR `count` can not be placed inside the inner-most repetition
 }
 
-macro_rules! curly__rhs_dollar__round {
-    ( $( $i:ident ),* ) => { ${ count($i) } };
-    //~^ ERROR expected identifier, found `$`
-    //~| ERROR expected expression, found `$`
-}
-
 macro_rules! curly__rhs_dollar__no_round {
     ( $i:ident ) => { ${ count($i) } };
-    //~^ ERROR expected identifier, found `$`
-    //~| ERROR expected expression, found `$`
+    //~^ ERROR `count` can not be placed inside the inner-most repetition
 }
 
 macro_rules! no_curly__no_rhs_dollar__round {
@@ -60,16 +53,16 @@ macro_rules! extra_garbage_after_metavar {
         ${count() a b c}
         //~^ ERROR unexpected token: a
         //~| ERROR expected expression, found `$`
-        ${count(i a b c)}
+        ${count($i a b c)}
         //~^ ERROR unexpected token: a
-        ${count(i, 1 a b c)}
+        ${count($i, 1 a b c)}
         //~^ ERROR unexpected token: a
-        ${count(i) a b c}
+        ${count($i) a b c}
         //~^ ERROR unexpected token: a
 
-        ${ignore(i) a b c}
+        ${ignore($i) a b c}
         //~^ ERROR unexpected token: a
-        ${ignore(i a b c)}
+        ${ignore($i a b c)}
         //~^ ERROR unexpected token: a
 
         ${index() a b c}
@@ -100,8 +93,8 @@ macro_rules! metavar_in_the_lhs {
 
 macro_rules! metavar_token_without_ident {
     ( $( $i:ident ),* ) => { ${ ignore() } };
-    //~^ ERROR expected identifier
-    //~| ERROR expected expression, found `$`
+    //~^ ERROR meta-variable expressions must be referenced using a dollar sign
+    //~| ERROR expected expression
 }
 
 macro_rules! metavar_with_literal_suffix {
@@ -125,14 +118,16 @@ macro_rules! open_brackets_without_tokens {
 macro_rules! unknown_count_ident {
     ( $( $i:ident )* ) => {
         ${count(foo)}
-        //~^ ERROR variable `foo` is not recognized in meta-variable expression
+        //~^ ERROR meta-variable expressions must be referenced using a dollar sign
+        //~| ERROR expected expression
     };
 }
 
 macro_rules! unknown_ignore_ident {
     ( $( $i:ident )* ) => {
         ${ignore(bar)}
-        //~^ ERROR variable `bar` is not recognized in meta-variable expression
+        //~^ ERROR meta-variable expressions must be referenced using a dollar sign
+        //~| ERROR expected expression
     };
 }
 
@@ -145,7 +140,6 @@ macro_rules! unknown_metavar {
 fn main() {
     curly__no_rhs_dollar__round!(a, b, c);
     curly__no_rhs_dollar__no_round!(a);
-    curly__rhs_dollar__round!(a, b, c);
     curly__rhs_dollar__no_round!(a);
     no_curly__no_rhs_dollar__round!(a, b, c);
     no_curly__no_rhs_dollar__no_round!(a);
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr
index a6cff95fd91..0dda38290ab 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr
+++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr
@@ -1,197 +1,197 @@
-error: expected identifier, found `$`
-  --> $DIR/syntax-errors.rs:17:33
-   |
-LL |     ( $( $i:ident ),* ) => { ${ count($i) } };
-   |                                 ^^^^^ - help: try removing `$`
-
-error: expected identifier, found `$`
-  --> $DIR/syntax-errors.rs:23:26
-   |
-LL |     ( $i:ident ) => { ${ count($i) } };
-   |                          ^^^^^ - help: try removing `$`
-
 error: unexpected token: $
-  --> $DIR/syntax-errors.rs:53:8
+  --> $DIR/syntax-errors.rs:46:8
    |
 LL |     ( $$ $a:ident ) => {
    |        ^
 
 note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions
-  --> $DIR/syntax-errors.rs:53:8
+  --> $DIR/syntax-errors.rs:46:8
    |
 LL |     ( $$ $a:ident ) => {
    |        ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:60:19
+  --> $DIR/syntax-errors.rs:53:19
    |
 LL |         ${count() a b c}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:60:19
+  --> $DIR/syntax-errors.rs:53:19
    |
 LL |         ${count() a b c}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:63:19
+  --> $DIR/syntax-errors.rs:56:20
    |
-LL |         ${count(i a b c)}
-   |                   ^
+LL |         ${count($i a b c)}
+   |                    ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:63:19
+  --> $DIR/syntax-errors.rs:56:20
    |
-LL |         ${count(i a b c)}
-   |                   ^
+LL |         ${count($i a b c)}
+   |                    ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:65:22
+  --> $DIR/syntax-errors.rs:58:23
    |
-LL |         ${count(i, 1 a b c)}
-   |                      ^
+LL |         ${count($i, 1 a b c)}
+   |                       ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:65:22
+  --> $DIR/syntax-errors.rs:58:23
    |
-LL |         ${count(i, 1 a b c)}
-   |                      ^
+LL |         ${count($i, 1 a b c)}
+   |                       ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:67:20
+  --> $DIR/syntax-errors.rs:60:21
    |
-LL |         ${count(i) a b c}
-   |                    ^
+LL |         ${count($i) a b c}
+   |                     ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:67:20
+  --> $DIR/syntax-errors.rs:60:21
    |
-LL |         ${count(i) a b c}
-   |                    ^
+LL |         ${count($i) a b c}
+   |                     ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:70:21
+  --> $DIR/syntax-errors.rs:63:22
    |
-LL |         ${ignore(i) a b c}
-   |                     ^
+LL |         ${ignore($i) a b c}
+   |                      ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:70:21
+  --> $DIR/syntax-errors.rs:63:22
    |
-LL |         ${ignore(i) a b c}
-   |                     ^
+LL |         ${ignore($i) a b c}
+   |                      ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:72:20
+  --> $DIR/syntax-errors.rs:65:21
    |
-LL |         ${ignore(i a b c)}
-   |                    ^
+LL |         ${ignore($i a b c)}
+   |                     ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:72:20
+  --> $DIR/syntax-errors.rs:65:21
    |
-LL |         ${ignore(i a b c)}
-   |                    ^
+LL |         ${ignore($i a b c)}
+   |                     ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:75:19
+  --> $DIR/syntax-errors.rs:68:19
    |
 LL |         ${index() a b c}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:75:19
+  --> $DIR/syntax-errors.rs:68:19
    |
 LL |         ${index() a b c}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:77:19
+  --> $DIR/syntax-errors.rs:70:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:77:19
+  --> $DIR/syntax-errors.rs:70:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:80:19
+  --> $DIR/syntax-errors.rs:73:19
    |
 LL |         ${index() a b c}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:80:19
+  --> $DIR/syntax-errors.rs:73:19
    |
 LL |         ${index() a b c}
    |                   ^
 
 error: unexpected token: a
-  --> $DIR/syntax-errors.rs:82:19
+  --> $DIR/syntax-errors.rs:75:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
    |
 note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:82:19
+  --> $DIR/syntax-errors.rs:75:19
    |
 LL |         ${index(1 a b c)}
    |                   ^
 
 error: meta-variable expression depth must be a literal
-  --> $DIR/syntax-errors.rs:89:33
+  --> $DIR/syntax-errors.rs:82:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ index(IDX) } };
    |                                 ^^^^^
 
 error: unexpected token: {
-  --> $DIR/syntax-errors.rs:95:8
+  --> $DIR/syntax-errors.rs:88:8
    |
 LL |     ( ${ length() } ) => {
    |        ^^^^^^^^^^^^
 
 note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions
-  --> $DIR/syntax-errors.rs:95:8
+  --> $DIR/syntax-errors.rs:88:8
    |
 LL |     ( ${ length() } ) => {
    |        ^^^^^^^^^^^^
 
 error: expected one of: `*`, `+`, or `?`
-  --> $DIR/syntax-errors.rs:95:8
+  --> $DIR/syntax-errors.rs:88:8
    |
 LL |     ( ${ length() } ) => {
    |        ^^^^^^^^^^^^
 
-error: expected identifier
-  --> $DIR/syntax-errors.rs:102:33
+error: meta-variables within meta-variable expressions must be referenced using a dollar sign
+  --> $DIR/syntax-errors.rs:95:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ ignore() } };
    |                                 ^^^^^^
 
 error: only unsuffixes integer literals are supported in meta-variable expressions
-  --> $DIR/syntax-errors.rs:108:33
+  --> $DIR/syntax-errors.rs:101:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ index(1u32) } };
    |                                 ^^^^^
 
 error: meta-variable expression parameter must be wrapped in parentheses
-  --> $DIR/syntax-errors.rs:114:33
+  --> $DIR/syntax-errors.rs:107:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ count{i} } };
    |                                 ^^^^^
 
 error: expected identifier
-  --> $DIR/syntax-errors.rs:120:31
+  --> $DIR/syntax-errors.rs:113:31
    |
 LL |     ( $( $i:ident ),* ) => { ${ {} } };
    |                               ^^^^^^
 
+error: meta-variables within meta-variable expressions must be referenced using a dollar sign
+  --> $DIR/syntax-errors.rs:120:11
+   |
+LL |         ${count(foo)}
+   |           ^^^^^
+
+error: meta-variables within meta-variable expressions must be referenced using a dollar sign
+  --> $DIR/syntax-errors.rs:128:11
+   |
+LL |         ${ignore(bar)}
+   |           ^^^^^^
+
 error: unrecognized meta-variable expression
-  --> $DIR/syntax-errors.rs:140:33
+  --> $DIR/syntax-errors.rs:135:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
    |                                 ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and length
@@ -199,39 +199,23 @@ LL |     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
 error: `count` can not be placed inside the inner-most repetition
   --> $DIR/syntax-errors.rs:12:24
    |
-LL |     ( $i:ident ) => { ${ count(i) } };
-   |                        ^^^^^^^^^^^^
-
-error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:17:30
-   |
-LL |     ( $( $i:ident ),* ) => { ${ count($i) } };
-   |                              ^ expected expression
-...
-LL |     curly__rhs_dollar__round!(a, b, c);
-   |     ---------------------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `curly__rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
+LL |     ( $i:ident ) => { ${ count($i) } };
+   |                        ^^^^^^^^^^^^^
 
-error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:23:23
+error: `count` can not be placed inside the inner-most repetition
+  --> $DIR/syntax-errors.rs:17:24
    |
 LL |     ( $i:ident ) => { ${ count($i) } };
-   |                       ^ expected expression
-...
-LL |     curly__rhs_dollar__no_round!(a);
-   |     ------------------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
+   |                        ^^^^^^^^^^^^^
 
 error: variable 'i' is still repeating at this depth
-  --> $DIR/syntax-errors.rs:41:36
+  --> $DIR/syntax-errors.rs:34:36
    |
 LL |     ( $( $i:ident ),* ) => { count($i) };
    |                                    ^^
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:60:9
+  --> $DIR/syntax-errors.rs:53:9
    |
 LL |         ${count() a b c}
    |         ^ expected expression
@@ -242,7 +226,7 @@ LL |     extra_garbage_after_metavar!(a);
    = note: this error originates in the macro `extra_garbage_after_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:89:30
+  --> $DIR/syntax-errors.rs:82:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ index(IDX) } };
    |                              ^ expected expression
@@ -253,7 +237,7 @@ LL |     metavar_depth_is_not_literal!(a);
    = note: this error originates in the macro `metavar_depth_is_not_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:102:30
+  --> $DIR/syntax-errors.rs:95:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ ignore() } };
    |                              ^ expected expression
@@ -264,7 +248,7 @@ LL |     metavar_token_without_ident!(a);
    = note: this error originates in the macro `metavar_token_without_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:108:30
+  --> $DIR/syntax-errors.rs:101:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ index(1u32) } };
    |                              ^ expected expression
@@ -275,7 +259,7 @@ LL |     metavar_with_literal_suffix!(a);
    = note: this error originates in the macro `metavar_with_literal_suffix` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:114:30
+  --> $DIR/syntax-errors.rs:107:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ count{i} } };
    |                              ^ expected expression
@@ -286,7 +270,7 @@ LL |     metavar_without_parens!(a);
    = note: this error originates in the macro `metavar_without_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:120:30
+  --> $DIR/syntax-errors.rs:113:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ {} } };
    |                              ^ expected expression
@@ -296,20 +280,30 @@ LL |     open_brackets_without_tokens!(a);
    |
    = note: this error originates in the macro `open_brackets_without_tokens` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: variable `foo` is not recognized in meta-variable expression
-  --> $DIR/syntax-errors.rs:127:17
+error: expected expression, found `$`
+  --> $DIR/syntax-errors.rs:120:9
    |
 LL |         ${count(foo)}
-   |                 ^^^
+   |         ^ expected expression
+...
+LL |     unknown_count_ident!(a);
+   |     ----------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `unknown_count_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: variable `bar` is not recognized in meta-variable expression
-  --> $DIR/syntax-errors.rs:134:18
+error: expected expression, found `$`
+  --> $DIR/syntax-errors.rs:128:9
    |
 LL |         ${ignore(bar)}
-   |                  ^^^
+   |         ^ expected expression
+...
+LL |     unknown_ignore_ident!(a);
+   |     ------------------------ in this macro invocation
+   |
+   = note: this error originates in the macro `unknown_ignore_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found `$`
-  --> $DIR/syntax-errors.rs:140:30
+  --> $DIR/syntax-errors.rs:135:30
    |
 LL |     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
    |                              ^ expected expression
@@ -320,7 +314,7 @@ LL |     unknown_metavar!(a);
    = note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `i` in this scope
-  --> $DIR/syntax-errors.rs:29:36
+  --> $DIR/syntax-errors.rs:22:36
    |
 LL |     ( $( $i:ident ),* ) => { count(i) };
    |                                    ^ not found in this scope
@@ -331,7 +325,7 @@ LL |     no_curly__no_rhs_dollar__round!(a, b, c);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `i` in this scope
-  --> $DIR/syntax-errors.rs:35:29
+  --> $DIR/syntax-errors.rs:28:29
    |
 LL |     ( $i:ident ) => { count(i) };
    |                             ^ not found in this scope
@@ -342,13 +336,13 @@ LL |     no_curly__no_rhs_dollar__no_round!(a);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `a` in this scope
-  --> $DIR/syntax-errors.rs:153:37
+  --> $DIR/syntax-errors.rs:147:37
    |
 LL |     no_curly__rhs_dollar__no_round!(a);
    |                                     ^ not found in this scope
 
 error[E0425]: cannot find function `count` in this scope
-  --> $DIR/syntax-errors.rs:29:30
+  --> $DIR/syntax-errors.rs:22:30
    |
 LL |     ( $( $i:ident ),* ) => { count(i) };
    |                              ^^^^^ not found in this scope
@@ -359,7 +353,7 @@ LL |     no_curly__no_rhs_dollar__round!(a, b, c);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find function `count` in this scope
-  --> $DIR/syntax-errors.rs:35:23
+  --> $DIR/syntax-errors.rs:28:23
    |
 LL |     ( $i:ident ) => { count(i) };
    |                       ^^^^^ not found in this scope
@@ -370,7 +364,7 @@ LL |     no_curly__no_rhs_dollar__no_round!(a);
    = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find function `count` in this scope
-  --> $DIR/syntax-errors.rs:46:23
+  --> $DIR/syntax-errors.rs:39:23
    |
 LL |     ( $i:ident ) => { count($i) };
    |                       ^^^^^ not found in this scope
@@ -380,6 +374,6 @@ LL |     no_curly__rhs_dollar__no_round!(a);
    |
    = note: this error originates in the macro `no_curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 40 previous errors
+error: aborting due to 39 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/never_type/never-from-impl-is-reserved.rs b/tests/ui/never_type/never-from-impl-is-reserved.rs
index f358e045cf0..97fac59149b 100644
--- a/tests/ui/never_type/never-from-impl-is-reserved.rs
+++ b/tests/ui/never_type/never-from-impl-is-reserved.rs
@@ -1,7 +1,7 @@
 // check that the `for<T> T: From<!>` impl is reserved
 
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next-coherence
+//[next] compile-flags: -Znext-solver=coherence
 
 #![feature(never_type)]
 
diff --git a/tests/ui/nll/issue-53119.rs b/tests/ui/nll/issue-53119.rs
index 015b72367f1..d19a9a0327c 100644
--- a/tests/ui/nll/issue-53119.rs
+++ b/tests/ui/nll/issue-53119.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 use std::ops::Deref;
 
diff --git a/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
index 0b30a88fdd4..21dda7b8c9b 100644
--- a/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
+++ b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 trait Foo {
     type Bar<'a>
diff --git a/tests/ui/packed/dyn-trait.rs b/tests/ui/packed/dyn-trait.rs
new file mode 100644
index 00000000000..bb73c26c18a
--- /dev/null
+++ b/tests/ui/packed/dyn-trait.rs
@@ -0,0 +1,21 @@
+// run-pass
+use std::ptr::addr_of;
+
+// When the unsized tail is a `dyn Trait`, its alignments is only dynamically known. This means the
+// packed(2) needs to be applied at runtime: the actual alignment of the field is `min(2,
+// usual_alignment)`. Here we check that we do this right by comparing size, alignment, and field
+// offset before and after unsizing.
+fn main() {
+    #[repr(C, packed(2))]
+    struct Packed<T: ?Sized>(u8, core::mem::ManuallyDrop<T>);
+
+    let p = Packed(0, core::mem::ManuallyDrop::new(1));
+    let p: &Packed<usize> = &p;
+    let sized = (core::mem::size_of_val(p), core::mem::align_of_val(p));
+    let sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) };
+    let p: &Packed<dyn Send> = p;
+    let un_sized = (core::mem::size_of_val(p), core::mem::align_of_val(p));
+    let un_sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) };
+    assert_eq!(sized, un_sized);
+    assert_eq!(sized_offset, un_sized_offset);
+}
diff --git a/tests/ui/panic-handler/panic-handler-duplicate.stderr b/tests/ui/panic-handler/panic-handler-duplicate.stderr
index 5c50b7016b2..299847474cd 100644
--- a/tests/ui/panic-handler/panic-handler-duplicate.stderr
+++ b/tests/ui/panic-handler/panic-handler-duplicate.stderr
@@ -1,14 +1,18 @@
 error[E0152]: found duplicate lang item `panic_impl`
   --> $DIR/panic-handler-duplicate.rs:15:1
    |
-LL | fn panic2(info: &PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic2(info: &PanicInfo) -> ! {
+LL | |     loop {}
+LL | | }
+   | |_^
    |
 note: the lang item is first defined here
   --> $DIR/panic-handler-duplicate.rs:10:1
    |
-LL | fn panic(info: &PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic(info: &PanicInfo) -> ! {
+LL | |     loop {}
+LL | | }
+   | |_^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr
index ad9addec8eb..48c216ce27e 100644
--- a/tests/ui/panic-handler/panic-handler-std.stderr
+++ b/tests/ui/panic-handler/panic-handler-std.stderr
@@ -1,8 +1,10 @@
 error[E0152]: found duplicate lang item `panic_impl`
   --> $DIR/panic-handler-std.rs:8:1
    |
-LL | fn panic(info: PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic(info: PanicInfo) -> ! {
+LL | |     loop {}
+LL | | }
+   | |_^
    |
    = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on)
    = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
diff --git a/tests/ui/panics/abort-on-panic.rs b/tests/ui/panics/abort-on-panic.rs
index 7fbee85ffd1..ff31fc24317 100644
--- a/tests/ui/panics/abort-on-panic.rs
+++ b/tests/ui/panics/abort-on-panic.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![allow(unused_must_use)]
 #![feature(c_unwind)]
diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout
index f34a8e9a706..71a7f3c6381 100644
--- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout
+++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout
@@ -9,3 +9,9 @@ print-type-size         padding: 3 bytes
 print-type-size         local `.z`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Returned`: 0 bytes
 print-type-size     variant `Panicked`: 0 bytes
+print-type-size type: `std::mem::ManuallyDrop<i32>`: 4 bytes, alignment: 4 bytes
+print-type-size     field `.value`: 4 bytes
+print-type-size type: `std::mem::MaybeUninit<i32>`: 4 bytes, alignment: 4 bytes
+print-type-size     variant `MaybeUninit`: 4 bytes
+print-type-size         field `.uninit`: 0 bytes
+print-type-size         field `.value`: 4 bytes
diff --git a/tests/ui/regions/resolve-re-error-ice.rs b/tests/ui/regions/resolve-re-error-ice.rs
index f37b27a82b3..bf6defb9bae 100644
--- a/tests/ui/regions/resolve-re-error-ice.rs
+++ b/tests/ui/regions/resolve-re-error-ice.rs
@@ -1,8 +1,3 @@
-// check-pass
-
-// Allow this for now, can remove this UI test when this becomes a hard error.
-#![allow(implied_bounds_entailment)]
-
 use std::collections::hash_map::{Keys, HashMap};
 use std::marker::PhantomData;
 
@@ -15,6 +10,7 @@ struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>);
 impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R>
 {
     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+        //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements
         todo!()
     }
 }
diff --git a/tests/ui/regions/resolve-re-error-ice.stderr b/tests/ui/regions/resolve-re-error-ice.stderr
index e7003e1c32f..41c5f0fa92e 100644
--- a/tests/ui/regions/resolve-re-error-ice.stderr
+++ b/tests/ui/regions/resolve-re-error-ice.stderr
@@ -1,15 +1,37 @@
-Future incompatibility report: Future breakage diagnostic:
-warning: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/resolve-re-error-ice.rs:17:16
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements
+  --> $DIR/resolve-re-error-ice.rs:12:5
    |
 LL |     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
-   |                ^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `Subject<'_, std::collections::hash_map::Keys<'_, K, V>, (), R>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/resolve-re-error-ice.rs:4:10
+note: first, the lifetime cannot outlive the anonymous lifetime defined here...
+  --> $DIR/resolve-re-error-ice.rs:5:16
    |
-LL | #![allow(implied_bounds_entailment)]
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn key_set(&self) -> Subject<Keys<K, V>, (), R>;
+   |                ^^^^^
+note: ...so that the method type is compatible with trait
+  --> $DIR/resolve-re-error-ice.rs:12:5
+   |
+LL |     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `fn(&Subject<'_, _, _, _>) -> Subject<'_, std::collections::hash_map::Keys<'_, _, _>, _, _>`
+              found `fn(&Subject<'_, _, _, _>) -> Subject<'a, std::collections::hash_map::Keys<'_, _, _>, _, _>`
+note: but, the lifetime must be valid for the lifetime `'a` as defined here...
+  --> $DIR/resolve-re-error-ice.rs:10:6
+   |
+LL | impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R>
+   |      ^^
+note: ...so that the type `std::collections::hash_map::Keys<'_, K, V>` will meet its required lifetime bounds...
+  --> $DIR/resolve-re-error-ice.rs:12:5
+   |
+LL |     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...that is required by this bound
+  --> $DIR/resolve-re-error-ice.rs:8:29
+   |
+LL | struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>);
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
index c27e8c4b019..c7665affb99 100644
--- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
+++ b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
@@ -1,7 +1,7 @@
 // Check that we can manually implement an object-unsafe trait for its trait object.
 
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // run-pass
 
 #![feature(object_safe_for_dispatch)]
diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
index 44c598f19cb..37903c21071 100644
--- a/tests/ui/specialization/specialization-default-items-drop-coherence.rs
+++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
@@ -1,6 +1,6 @@
 // revisions: classic coherence next
-//[next] compile-flags: -Ztrait-solver=next
-//[coherence] compile-flags: -Ztrait-solver=next-coherence
+//[next] compile-flags: -Znext-solver
+//[coherence] compile-flags: -Znext-solver=coherence
 //[classic] check-pass
 //[classic] known-bug: #105782
 
diff --git a/tests/ui/stable-mir-print/basic_function.rs b/tests/ui/stable-mir-print/basic_function.rs
new file mode 100644
index 00000000000..6394edcbb78
--- /dev/null
+++ b/tests/ui/stable-mir-print/basic_function.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Z unpretty=stable-mir -Z mir-opt-level=3
+// check-pass
+// only-x86_64
+
+fn foo(i:i32) -> i32 {
+    i + 1
+}
+
+fn bar(vec: &mut Vec<i32>) -> Vec<i32> {
+    let mut new_vec = vec.clone();
+    new_vec.push(1);
+    new_vec
+}
+
+fn main(){}
diff --git a/tests/ui/stable-mir-print/basic_function.stdout b/tests/ui/stable-mir-print/basic_function.stdout
new file mode 100644
index 00000000000..d9b33a4257c
--- /dev/null
+++ b/tests/ui/stable-mir-print/basic_function.stdout
@@ -0,0 +1,234 @@
+// 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(_0: i32) -> i32 {
+    let mut _0: (i32, bool);
+}
+    bb0: {
+        _2 = 1 Add const 1_i32
+        assert(!move _2 bool),"attempt to compute `{} + {}`, which would overflow", 1, const 1_i32) -> [success: bb1, unwind continue]
+    }
+    bb1: {
+        _0 = move _2
+        return
+    }
+fn bar(_0: &mut Ty {
+    id: 10,
+    kind: RigidTy(
+        Adt(
+            AdtDef(
+                DefId {
+                    id: 3,
+                    name: "std::vec::Vec",
+                },
+            ),
+            GenericArgs(
+                [
+                    Type(
+                        Ty {
+                            id: 11,
+                            kind: Param(
+                                ParamTy {
+                                    index: 0,
+                                    name: "T",
+                                },
+                            ),
+                        },
+                    ),
+                    Type(
+                        Ty {
+                            id: 12,
+                            kind: Param(
+                                ParamTy {
+                                    index: 1,
+                                    name: "A",
+                                },
+                            ),
+                        },
+                    ),
+                ],
+            ),
+        ),
+    ),
+}) -> Ty {
+    id: 10,
+    kind: RigidTy(
+        Adt(
+            AdtDef(
+                DefId {
+                    id: 3,
+                    name: "std::vec::Vec",
+                },
+            ),
+            GenericArgs(
+                [
+                    Type(
+                        Ty {
+                            id: 11,
+                            kind: Param(
+                                ParamTy {
+                                    index: 0,
+                                    name: "T",
+                                },
+                            ),
+                        },
+                    ),
+                    Type(
+                        Ty {
+                            id: 12,
+                            kind: Param(
+                                ParamTy {
+                                    index: 1,
+                                    name: "A",
+                                },
+                            ),
+                        },
+                    ),
+                ],
+            ),
+        ),
+    ),
+} {
+    let mut _0: Ty {
+    id: 10,
+    kind: RigidTy(
+        Adt(
+            AdtDef(
+                DefId {
+                    id: 3,
+                    name: "std::vec::Vec",
+                },
+            ),
+            GenericArgs(
+                [
+                    Type(
+                        Ty {
+                            id: 11,
+                            kind: Param(
+                                ParamTy {
+                                    index: 0,
+                                    name: "T",
+                                },
+                            ),
+                        },
+                    ),
+                    Type(
+                        Ty {
+                            id: 12,
+                            kind: Param(
+                                ParamTy {
+                                    index: 1,
+                                    name: "A",
+                                },
+                            ),
+                        },
+                    ),
+                ],
+            ),
+        ),
+    ),
+};
+    let mut _1: &Ty {
+    id: 10,
+    kind: RigidTy(
+        Adt(
+            AdtDef(
+                DefId {
+                    id: 3,
+                    name: "std::vec::Vec",
+                },
+            ),
+            GenericArgs(
+                [
+                    Type(
+                        Ty {
+                            id: 11,
+                            kind: Param(
+                                ParamTy {
+                                    index: 0,
+                                    name: "T",
+                                },
+                            ),
+                        },
+                    ),
+                    Type(
+                        Ty {
+                            id: 12,
+                            kind: Param(
+                                ParamTy {
+                                    index: 1,
+                                    name: "A",
+                                },
+                            ),
+                        },
+                    ),
+                ],
+            ),
+        ),
+    ),
+};
+    let _2: ();
+    let mut _3: &mut Ty {
+    id: 10,
+    kind: RigidTy(
+        Adt(
+            AdtDef(
+                DefId {
+                    id: 3,
+                    name: "std::vec::Vec",
+                },
+            ),
+            GenericArgs(
+                [
+                    Type(
+                        Ty {
+                            id: 11,
+                            kind: Param(
+                                ParamTy {
+                                    index: 0,
+                                    name: "T",
+                                },
+                            ),
+                        },
+                    ),
+                    Type(
+                        Ty {
+                            id: 12,
+                            kind: Param(
+                                ParamTy {
+                                    index: 1,
+                                    name: "A",
+                                },
+                            ),
+                        },
+                    ),
+                ],
+            ),
+        ),
+    ),
+};
+}
+    bb0: {
+        _3 = refShared1
+        _2 = const <Vec<i32> as Clone>::clone(move _3) -> [return: bb1, unwind continue]
+    }
+    bb1: {
+        _5 = refMut {
+    kind: TwoPhaseBorrow,
+}2
+        _4 = const Vec::<i32>::push(move _5, const 1_i32) -> [return: bb2, unwind: bb3]
+    }
+    bb2: {
+        _0 = move _2
+        return
+    }
+    bb3: {
+        drop(_2) -> [return: bb4, unwind terminate]
+    }
+    bb4: {
+        resume
+    }
+fn main() -> () {
+}
+    bb0: {
+        return
+    }
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index 406e5c8441e..490d6a2f918 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -4,7 +4,6 @@
 #![allow(dead_code)]
 #![feature(never_type)]
 #![feature(pointer_is_aligned)]
-#![feature(ptr_from_ref)]
 #![feature(strict_provenance)]
 
 use std::mem::size_of;
diff --git a/tests/ui/traits/deny-builtin-object-impl.rs b/tests/ui/traits/deny-builtin-object-impl.rs
index dce03a43b68..d0eb6382e41 100644
--- a/tests/ui/traits/deny-builtin-object-impl.rs
+++ b/tests/ui/traits/deny-builtin-object-impl.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(rustc_attrs)]
 
diff --git a/tests/ui/traits/issue-102989.rs b/tests/ui/traits/issue-102989.rs
index 216cd78e56f..f1ecee0a552 100644
--- a/tests/ui/traits/issue-102989.rs
+++ b/tests/ui/traits/issue-102989.rs
@@ -7,6 +7,7 @@ trait Sized { } //~ ERROR found duplicate lang item `sized`
 fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
     //~^ ERROR `self` parameter is only allowed in associated functions
     //~| ERROR cannot find type `Struct` in this scope
+    //~| ERROR mismatched types
     let x = x << 1;
     //~^ ERROR cannot find value `x` in this scope
 }
diff --git a/tests/ui/traits/issue-102989.stderr b/tests/ui/traits/issue-102989.stderr
index 7d0098fe885..40e49df2b2d 100644
--- a/tests/ui/traits/issue-102989.stderr
+++ b/tests/ui/traits/issue-102989.stderr
@@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                      ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-102989.rs:10:13
+  --> $DIR/issue-102989.rs:11:13
    |
 LL |     let x = x << 1;
    |             ^ help: a local variable with a similar name exists: `f`
@@ -22,13 +22,27 @@ error[E0152]: found duplicate lang item `sized`
   --> $DIR/issue-102989.rs:5:1
    |
 LL | trait Sized { }
-   | ^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^
    |
    = note: the lang item is first defined in crate `core` (which `std` depends on)
    = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib
    = note: second definition in the local crate (`issue_102989`)
 
-error: aborting due to 4 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-102989.rs:7:42
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |    ----------                            ^^^^ expected `&u32`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+help: consider returning the local binding `f`
+   |
+LL ~     let x = x << 1;
+LL +     f
+   |
+
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0152, E0412, E0425.
+Some errors have detailed explanations: E0152, E0308, E0412, E0425.
 For more information about an error, try `rustc --explain E0152`.
diff --git a/tests/ui/traits/issue-24010.rs b/tests/ui/traits/issue-24010.rs
index fd7d6751d5c..1eaa5bf0c67 100644
--- a/tests/ui/traits/issue-24010.rs
+++ b/tests/ui/traits/issue-24010.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: classic next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 trait Foo: Fn(i32) -> i32 + Send {}
 
diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr
index a53879657f5..8f5b937e586 100644
--- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr
+++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr
@@ -50,7 +50,7 @@ LL |     is_send((8, TestType));
    |     required by a bound introduced by this call
    |
    = help: within `({integer}, dummy1c::TestType)`, the trait `Send` is not implemented for `dummy1c::TestType`
-   = note: required because it appears within the type `({integer}, TestType)`
+   = note: required because it appears within the type `({integer}, dummy1c::TestType)`
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
    |
@@ -67,7 +67,7 @@ LL |     is_send(Box::new(TestType));
    |
    = note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied
    = note: required for `Unique<dummy2::TestType>` to implement `Send`
-note: required because it appears within the type `Box<TestType>`
+note: required because it appears within the type `Box<dummy2::TestType>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
@@ -88,13 +88,13 @@ LL |     is_send(Box::new(Outer2(TestType)));
    |     required by a bound introduced by this call
    |
    = help: within `Outer2<dummy3::TestType>`, the trait `Send` is not implemented for `dummy3::TestType`
-note: required because it appears within the type `Outer2<TestType>`
+note: required because it appears within the type `Outer2<dummy3::TestType>`
   --> $DIR/negated-auto-traits-error.rs:12:8
    |
 LL | struct Outer2<T>(T);
    |        ^^^^^^
    = note: required for `Unique<Outer2<dummy3::TestType>>` to implement `Send`
-note: required because it appears within the type `Box<Outer2<TestType>>`
+note: required because it appears within the type `Box<Outer2<dummy3::TestType>>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr
deleted file mode 100644
index e4922b0c3e9..00000000000
--- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0284]: type annotations needed: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc`
-  --> $DIR/generalize-proj-new-universe-index-2.rs:74:5
-   |
-LL |     bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/new-solver/alias-bound-preference.rs b/tests/ui/traits/next-solver/alias-bound-preference.rs
index e4e0f634ef7..1c6e1209610 100644
--- a/tests/ui/traits/new-solver/alias-bound-preference.rs
+++ b/tests/ui/traits/next-solver/alias-bound-preference.rs
@@ -1,5 +1,5 @@
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // run-pass
 
 // A test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/45.
diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs
index ab84e3875e2..565bfe1186e 100644
--- a/tests/ui/traits/new-solver/alias-bound-unsound.rs
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // Makes sure that alias bounds are not unsound!
 
diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
index b09c22f3f41..b09c22f3f41 100644
--- a/tests/ui/traits/new-solver/alias-bound-unsound.stderr
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
diff --git a/tests/ui/traits/new-solver/alias-eq-in-canonical-response.rs b/tests/ui/traits/next-solver/alias-eq-in-canonical-response.rs
index 4bfb6323a53..aa7c94791a7 100644
--- a/tests/ui/traits/new-solver/alias-eq-in-canonical-response.rs
+++ b/tests/ui/traits/next-solver/alias-eq-in-canonical-response.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Foo {
     type Gat<'a>
diff --git a/tests/ui/traits/new-solver/alias-relate/deeply-nested-no-hang.rs b/tests/ui/traits/next-solver/alias-relate/deeply-nested-no-hang.rs
index 4abce7b57d5..91cfda37adf 100644
--- a/tests/ui/traits/new-solver/alias-relate/deeply-nested-no-hang.rs
+++ b/tests/ui/traits/next-solver/alias-relate/deeply-nested-no-hang.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // regression test for trait-system-refactor-initiative#68
 trait Identity {
     type Assoc: ?Sized;
diff --git a/tests/ui/traits/new-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs b/tests/ui/traits/next-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs
index 29a73e1a967..88bbd13f9a2 100644
--- a/tests/ui/traits/new-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs
+++ b/tests/ui/traits/next-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 fn test<T: Iterator>(x: T::Item) -> impl Sized {
     x
diff --git a/tests/ui/traits/new-solver/alias-sub.rs b/tests/ui/traits/next-solver/alias-sub.rs
index 30c1981a92e..f7f23a024dd 100644
--- a/tests/ui/traits/new-solver/alias-sub.rs
+++ b/tests/ui/traits/next-solver/alias-sub.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Trait {
diff --git a/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs b/tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs
index dc726ba51f9..04d1b949692 100644
--- a/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs
+++ b/tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // check that a goal such as `alias-eq(<T as TraitB>::Assoc<bool>, <T as TraitB>::Assoc<?0>)`
 // succeeds with a constraint that `?0 = bool`
diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs b/tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
index 3c7fc7403b1..48157192a10 100644
--- a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
+++ b/tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // check-pass
 // (should not pass, should be turned into a coherence-only test)
diff --git a/tests/ui/traits/new-solver/alias_eq_simple.rs b/tests/ui/traits/next-solver/alias_eq_simple.rs
index 6792cf3ce35..21ad1a4fa3c 100644
--- a/tests/ui/traits/new-solver/alias_eq_simple.rs
+++ b/tests/ui/traits/next-solver/alias_eq_simple.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // test that the new solver can handle `alias-eq(<i32 as TraitB>::Assoc, u32)`
 
diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs
index 204f6e8b071..4717aa80499 100644
--- a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs
+++ b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // check that a `alias-eq(<?a as TraitB>::Assoc, <?b as TraitB>::Assoc)` goal fails
 // during coherence. We must not incorrectly constrain `?a` and `?b` to be
diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr
index 8c6840f72a7..8c6840f72a7 100644
--- a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr
+++ b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr
diff --git a/tests/ui/traits/new-solver/array-default.rs b/tests/ui/traits/next-solver/array-default.rs
index 5077137b09b..6bfbce7d433 100644
--- a/tests/ui/traits/new-solver/array-default.rs
+++ b/tests/ui/traits/next-solver/array-default.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn has_default<const N: usize>() where [(); N]: Default {}
diff --git a/tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs b/tests/ui/traits/next-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs
index 826e8c1e0b1..4401abd0783 100644
--- a/tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs
+++ b/tests/ui/traits/next-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // Checks that we do not get ambiguity by considering an impl
diff --git a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.rs
index 1dca86d3630..1edc1a8c58c 100644
--- a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs
+++ b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // In the new solver, we are trying to select `<?0 as Iterator>::Item: Debug`,
 // which, naively can be unified with every impl of `Debug` if we're not careful.
diff --git a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr
index 4bd55ee80c6..4bd55ee80c6 100644
--- a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr
+++ b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr
diff --git a/tests/ui/traits/new-solver/async.fail.stderr b/tests/ui/traits/next-solver/async.fail.stderr
index ebd0ada2604..ebd0ada2604 100644
--- a/tests/ui/traits/new-solver/async.fail.stderr
+++ b/tests/ui/traits/next-solver/async.fail.stderr
diff --git a/tests/ui/traits/new-solver/async.rs b/tests/ui/traits/next-solver/async.rs
index 155b71eb749..5833c052234 100644
--- a/tests/ui/traits/new-solver/async.rs
+++ b/tests/ui/traits/next-solver/async.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // edition: 2021
 // revisions: pass fail
 //[pass] check-pass
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr
index ac05dfb2d46..ac05dfb2d46 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
+++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs
index 6b54718e35c..d4010a55244 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
+++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // edition: 2021
 // revisions: pass fail
 //[pass] check-pass
diff --git a/tests/ui/traits/new-solver/borrowck-error.rs b/tests/ui/traits/next-solver/borrowck-error.rs
index 4787a2c7e11..25f1445941b 100644
--- a/tests/ui/traits/new-solver/borrowck-error.rs
+++ b/tests/ui/traits/next-solver/borrowck-error.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 use std::collections::HashMap;
 
diff --git a/tests/ui/traits/new-solver/borrowck-error.stderr b/tests/ui/traits/next-solver/borrowck-error.stderr
index 4cb41e7d597..4cb41e7d597 100644
--- a/tests/ui/traits/new-solver/borrowck-error.stderr
+++ b/tests/ui/traits/next-solver/borrowck-error.stderr
diff --git a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs
index ba473653ecf..eab25214d63 100644
--- a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs
+++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 #![feature(fn_traits)]
 #![feature(unboxed_closures)]
diff --git a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr
index 08047852f20..08047852f20 100644
--- a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr
+++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr
diff --git a/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs b/tests/ui/traits/next-solver/canonical-int-var-eq-in-response.rs
index 4b013983a4a..ea2740523c9 100644
--- a/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs
+++ b/tests/ui/traits/next-solver/canonical-int-var-eq-in-response.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Mirror {
diff --git a/tests/ui/traits/new-solver/canonical-ty-var-eq-in-response.rs b/tests/ui/traits/next-solver/canonical-ty-var-eq-in-response.rs
index d1c6b1077e8..b1e4a9e58cf 100644
--- a/tests/ui/traits/new-solver/canonical-ty-var-eq-in-response.rs
+++ b/tests/ui/traits/next-solver/canonical-ty-var-eq-in-response.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Mirror {
     type Item;
diff --git a/tests/ui/traits/new-solver/canonicalize-effect-var.rs b/tests/ui/traits/next-solver/canonicalize-effect-var.rs
index 35b69ed1a6b..4a13ba37303 100644
--- a/tests/ui/traits/new-solver/canonicalize-effect-var.rs
+++ b/tests/ui/traits/next-solver/canonicalize-effect-var.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 #![feature(effects)]
diff --git a/tests/ui/traits/new-solver/cast-checks-handling-projections.rs b/tests/ui/traits/next-solver/cast-checks-handling-projections.rs
index 3b261062f78..406b4dc1211 100644
--- a/tests/ui/traits/new-solver/cast-checks-handling-projections.rs
+++ b/tests/ui/traits/next-solver/cast-checks-handling-projections.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn main() {
diff --git a/tests/ui/traits/new-solver/closure-inference-guidance.rs b/tests/ui/traits/next-solver/closure-inference-guidance.rs
index d2ad0cc0316..8175b92f882 100644
--- a/tests/ui/traits/new-solver/closure-inference-guidance.rs
+++ b/tests/ui/traits/next-solver/closure-inference-guidance.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn foo(i: isize) -> isize { i + 1 }
diff --git a/tests/ui/traits/next-solver/closure-signature-inference-2.rs b/tests/ui/traits/next-solver/closure-signature-inference-2.rs
new file mode 100644
index 00000000000..8fece7ba91f
--- /dev/null
+++ b/tests/ui/traits/next-solver/closure-signature-inference-2.rs
@@ -0,0 +1,21 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+fn map<T: Default, U, F: FnOnce(T) -> U>(f: F) {
+    f(T::default());
+}
+
+fn main() {
+    map::<i32, _ /* ?U */, _ /* ?F */>(|x| x.to_string());
+    // PREVIOUSLY when confirming the `map` call, we register:
+    //
+    // (1.) ?F: FnOnce<(i32,)>
+    // (2.) <?F as FnOnce<(i32,)>>::Output projects-to ?U
+    //
+    // While (1.) is ambiguous, (2.) immediately gets processed
+    // and we infer `?U := <?F as FnOnce<(i32,)>>::Output`.
+    //
+    // Thus, the only pending obligation that remains is (1.).
+    // Since it is a trait obligation, we don't use it to deduce
+    // the closure signature, and we fail!
+}
diff --git a/tests/ui/traits/next-solver/closure-signature-inference.rs b/tests/ui/traits/next-solver/closure-signature-inference.rs
new file mode 100644
index 00000000000..355fc790229
--- /dev/null
+++ b/tests/ui/traits/next-solver/closure-signature-inference.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+struct A;
+impl A {
+    fn hi(self) {}
+}
+
+fn hello() -> Result<(A,), ()> {
+    Err(())
+}
+
+fn main() {
+    let x = hello().map(|(x,)| x.hi());
+}
diff --git a/tests/ui/traits/new-solver/closure-substs-ambiguity.rs b/tests/ui/traits/next-solver/closure-substs-ambiguity.rs
index 48432f4020f..cc9ee58f27f 100644
--- a/tests/ui/traits/new-solver/closure-substs-ambiguity.rs
+++ b/tests/ui/traits/next-solver/closure-substs-ambiguity.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn main() {
diff --git a/tests/ui/traits/new-solver/coherence/issue-102048.rs b/tests/ui/traits/next-solver/coherence/issue-102048.rs
index 11636bfeb55..600e63d4d44 100644
--- a/tests/ui/traits/new-solver/coherence/issue-102048.rs
+++ b/tests/ui/traits/next-solver/coherence/issue-102048.rs
@@ -17,7 +17,7 @@
 // that to `i32`. We then try to unify `i32` from `impl1` with `u32` from `impl2` which fails,
 // causing coherence to consider these two impls distinct.
 
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 pub trait Trait<T> {}
 
 pub trait WithAssoc1<'a> {
diff --git a/tests/ui/traits/new-solver/coherence/issue-102048.stderr b/tests/ui/traits/next-solver/coherence/issue-102048.stderr
index 4e93ae28496..4e93ae28496 100644
--- a/tests/ui/traits/new-solver/coherence/issue-102048.stderr
+++ b/tests/ui/traits/next-solver/coherence/issue-102048.stderr
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
index b39ae0333ad..af471b5e193 100644
--- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // Coherence should handle overflow while normalizing for
 // `trait_ref_is_knowable` correctly.
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
index e3c0dabf549..e3c0dabf549 100644
--- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-1.rs
index c38e3baf5b4..e6ffb55b441 100644
--- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-1.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Id {
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-2.rs
index 2d53266db09..d16f9d22ce0 100644
--- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-2.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 use std::future::{Future, IntoFuture};
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
index 2f27de4e4f4..90de6b847d0 100644
--- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Id {
diff --git a/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr b/tests/ui/traits/next-solver/const-param-placeholder.fail.stderr
index 163710706b0..163710706b0 100644
--- a/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr
+++ b/tests/ui/traits/next-solver/const-param-placeholder.fail.stderr
diff --git a/tests/ui/traits/new-solver/const-param-placeholder.rs b/tests/ui/traits/next-solver/const-param-placeholder.rs
index a83102a4cdd..c22bc54cfca 100644
--- a/tests/ui/traits/new-solver/const-param-placeholder.rs
+++ b/tests/ui/traits/next-solver/const-param-placeholder.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // revisions: pass fail
 //[pass] check-pass
 
diff --git a/tests/ui/traits/new-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr
index 14e67727d0b..14e67727d0b 100644
--- a/tests/ui/traits/new-solver/coroutine.fail.stderr
+++ b/tests/ui/traits/next-solver/coroutine.fail.stderr
diff --git a/tests/ui/traits/new-solver/coroutine.rs b/tests/ui/traits/next-solver/coroutine.rs
index af16f70fb56..727e2356859 100644
--- a/tests/ui/traits/new-solver/coroutine.rs
+++ b/tests/ui/traits/next-solver/coroutine.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // edition: 2021
 // revisions: pass fail
 //[pass] check-pass
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.rs
index 07c7d4fb29c..947b52da7c2 100644
--- a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs
+++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // Proving `W<?0>: Trait` instantiates `?0` with `(W<?1>, W<?2>)` and then
 // proves `W<?1>: Trait` and `W<?2>: Trait`, resulting in a coinductive cycle.
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
index 150100f2c53..150100f2c53 100644
--- a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
+++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs
index 0cd14f05c8d..a3c07b98722 100644
--- a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs
+++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 #![feature(rustc_attrs)]
 
 // This test is incredibly subtle. At its core the goal is to get a coinductive cycle,
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr
index d4932191791..d4932191791 100644
--- a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr
+++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr
diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs
index 5617e45adf6..0f19bc2c592 100644
--- a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs
+++ b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 #![feature(rustc_attrs)]
 
 // Test that having both an inductive and a coinductive cycle
diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
index a3404da51f0..a3404da51f0 100644
--- a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr
+++ b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
index 27906392340..c7e2e2d5e04 100644
--- a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
+++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 #![feature(rustc_attrs)]
 
 // Check that we correctly rerun the trait solver for heads of cycles,
diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
index 7b3075f4ff3..7b3075f4ff3 100644
--- a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
+++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs
index cda98789886..fdc7afea378 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs
+++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 #![feature(trivial_bounds, marker_trait_attr)]
 #![allow(trivial_bounds)]
 // This previously triggered a bug in the provisional cache.
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr
index acacaf6a331..acacaf6a331 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr
+++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-ok.rs
index d4851eb694b..d6d9762bb73 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs
+++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-ok.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 #![feature(trivial_bounds, marker_trait_attr)]
 #![allow(trivial_bounds)]
diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs b/tests/ui/traits/next-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs
index 530e6d0ecf3..a32f7a13a03 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs
+++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 #![feature(rustc_attrs, marker_trait_attr)]
 #[rustc_coinductive]
 trait Trait {}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs
index 062c6ae98d5..efeb8d0231e 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs
+++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // This currently hangs if we do not erase constraints from
 // overflow.
diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
index 42451920744..42451920744 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr
+++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs
index f06b98a79cf..f2f6e009d54 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
+++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 #![feature(rustc_attrs, trivial_bounds)]
 
 // We have to be careful here:
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
index 859b3f3f1c7..859b3f3f1c7 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
+++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
diff --git a/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs b/tests/ui/traits/next-solver/cycles/leak-check-coinductive-cycle.rs
index a6d31872673..9ff362ec882 100644
--- a/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs
+++ b/tests/ui/traits/next-solver/cycles/leak-check-coinductive-cycle.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 #![feature(rustc_attrs)]
 
diff --git a/tests/ui/traits/new-solver/cycles/provisional-result-done.rs b/tests/ui/traits/next-solver/cycles/provisional-result-done.rs
index 589d34dd7ab..0f3b84ce520 100644
--- a/tests/ui/traits/new-solver/cycles/provisional-result-done.rs
+++ b/tests/ui/traits/next-solver/cycles/provisional-result-done.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // This tests checks that we update results in the provisional cache when
diff --git a/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs
index 51f62bc2312..08f26686b2f 100644
--- a/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs
+++ b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Foo {
diff --git a/tests/ui/traits/new-solver/deduce-ty-from-object.rs b/tests/ui/traits/next-solver/deduce-ty-from-object.rs
index 7398bce7b61..b627fd720e3 100644
--- a/tests/ui/traits/new-solver/deduce-ty-from-object.rs
+++ b/tests/ui/traits/next-solver/deduce-ty-from-object.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 fn main() {
     let x: Box<dyn Iterator<Item = ()>> = Box::new(std::iter::empty());
diff --git a/tests/ui/traits/new-solver/dedup-regions.rs b/tests/ui/traits/next-solver/dedup-regions.rs
index f376f39a5a6..dd406333f27 100644
--- a/tests/ui/traits/new-solver/dedup-regions.rs
+++ b/tests/ui/traits/next-solver/dedup-regions.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 struct A(*mut ());
diff --git a/tests/ui/traits/new-solver/destruct.rs b/tests/ui/traits/next-solver/destruct.rs
index 30d7777b78a..5093344e4b6 100644
--- a/tests/ui/traits/new-solver/destruct.rs
+++ b/tests/ui/traits/next-solver/destruct.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 #![feature(const_trait_impl)]
diff --git a/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs b/tests/ui/traits/next-solver/dont-coerce-infer-to-dyn.rs
index c2ac80459ca..da07869f3b6 100644
--- a/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs
+++ b/tests/ui/traits/next-solver/dont-coerce-infer-to-dyn.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 use std::fmt::Display;
diff --git a/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs b/tests/ui/traits/next-solver/dont-elaborate-for-projections.rs
index e608250063c..9123871db97 100644
--- a/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs
+++ b/tests/ui/traits/next-solver/dont-elaborate-for-projections.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Iter<'a, I: 'a>: Iterator<Item = &'a I> {}
diff --git a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs
index b9798c79d5e..1e1ef8c23a2 100644
--- a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs
+++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next-coherence
+// compile-flags: -Znext-solver=coherence
 
 // Makes sure we don't ICE on associated const projection when the feature gate
 // is not enabled, since we should avoid encountering ICEs on stable if possible.
diff --git a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr
index 368f5cd0c3b..368f5cd0c3b 100644
--- a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr
+++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr
diff --git a/tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs b/tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs
index b241e3bf865..a85098a95ad 100644
--- a/tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs
+++ b/tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Eq<'a, 'b, T> {}
diff --git a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs
index 19a6fa990ff..fd1682cd61a 100644
--- a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs
+++ b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // Test that we don't incorrectly leak unconstrained inference variables
 // if the projection contained an error. This caused an ICE in writeback.
diff --git a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr
index 576ede52aff..576ede52aff 100644
--- a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr
+++ b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr
diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/next-solver/dont-remap-tait-substs.rs
index 309bee8aa8c..b089f0df3c7 100644
--- a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
+++ b/tests/ui/traits/next-solver/dont-remap-tait-substs.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // Makes sure we don't prepopulate the MIR typeck of `define`
diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
index 076dab29d89..076dab29d89 100644
--- a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
+++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs
index 08f14d7494d..a1f38e69e53 100644
--- a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs
+++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs
@@ -1,5 +1,5 @@
 // revisions: is_send not_send
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 //[is_send] check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs b/tests/ui/traits/next-solver/dyn-any-dont-prefer-impl.rs
index af35a6195e0..bb1c24a001f 100644
--- a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs
+++ b/tests/ui/traits/next-solver/dyn-any-dont-prefer-impl.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // Test that selection prefers the builtin trait object impl for `Any`
diff --git a/tests/ui/traits/new-solver/elaborate-item-bounds.rs b/tests/ui/traits/next-solver/elaborate-item-bounds.rs
index 076aefcf8fc..0f1f6c0445c 100644
--- a/tests/ui/traits/new-solver/elaborate-item-bounds.rs
+++ b/tests/ui/traits/next-solver/elaborate-item-bounds.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Foo {
diff --git a/tests/ui/traits/new-solver/equating-projection-cyclically.rs b/tests/ui/traits/next-solver/equating-projection-cyclically.rs
index 845597e9ce1..e7c80cfd797 100644
--- a/tests/ui/traits/new-solver/equating-projection-cyclically.rs
+++ b/tests/ui/traits/next-solver/equating-projection-cyclically.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Test {
     type Assoc;
diff --git a/tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs b/tests/ui/traits/next-solver/escaping-bound-vars-in-writeback-normalization.rs
index 29784c32a1b..77bedc351e7 100644
--- a/tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs
+++ b/tests/ui/traits/next-solver/escaping-bound-vars-in-writeback-normalization.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Trivial {
diff --git a/tests/ui/traits/new-solver/float-canonical.rs b/tests/ui/traits/next-solver/float-canonical.rs
index b8748cd433b..90d75bacbf4 100644
--- a/tests/ui/traits/new-solver/float-canonical.rs
+++ b/tests/ui/traits/next-solver/float-canonical.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn foo(x: f64) {
diff --git a/tests/ui/traits/new-solver/fn-trait-closure.rs b/tests/ui/traits/next-solver/fn-trait-closure.rs
index bd65737ee39..cd2ae1f6fb2 100644
--- a/tests/ui/traits/new-solver/fn-trait-closure.rs
+++ b/tests/ui/traits/next-solver/fn-trait-closure.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn require_fn(_: impl Fn() -> i32) {}
diff --git a/tests/ui/traits/new-solver/fn-trait.rs b/tests/ui/traits/next-solver/fn-trait.rs
index 0a19e626553..1e3d8a21c7c 100644
--- a/tests/ui/traits/new-solver/fn-trait.rs
+++ b/tests/ui/traits/next-solver/fn-trait.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 fn require_fn(_: impl Fn() -> i32) {}
 
diff --git a/tests/ui/traits/new-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr
index e33487235e6..e33487235e6 100644
--- a/tests/ui/traits/new-solver/fn-trait.stderr
+++ b/tests/ui/traits/next-solver/fn-trait.stderr
diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs
index b0b9b6bbd20..4a70bd5f815 100644
--- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs
+++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // A minimization of an ambiguity when using typenum. See
diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs
index 94d645a9859..70758e7deaa 100644
--- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs
+++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // known-bug: trait-system-refactor-initiative#60
 
 // Generalizing a projection containing an inference variable
diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr
new file mode 100644
index 00000000000..4548ab1e297
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr
@@ -0,0 +1,19 @@
+error[E0284]: type annotations needed
+  --> $DIR/generalize-proj-new-universe-index-2.rs:74:5
+   |
+LL |     bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
+   |
+   = note: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc == _`
+note: required by a bound in `bound`
+  --> $DIR/generalize-proj-new-universe-index-2.rs:69:21
+   |
+LL | fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
+   |    ----- required by a bound in this function
+LL | where
+LL |     T: WithAssoc<U, Assoc = V>,
+   |                     ^^^^^^^^^ required by this bound in `bound`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.next.stderr b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
index ad8b24a39c7..ad8b24a39c7 100644
--- a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.next.stderr
+++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
diff --git a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.rs b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs
index 02ac091c0a8..e51508d684f 100644
--- a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.rs
+++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs
@@ -3,7 +3,7 @@
 
 // Currently always fails to generalize the outer alias, even if it
 // is treated as rigid by `alias-relate`.
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[next] known-bug: trait-system-refactor-initiative#8
 #![crate_type = "lib"]
 #![allow(unused)]
diff --git a/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs b/tests/ui/traits/next-solver/higher-ranked-dyn-bounds.rs
index c886aeeda3e..b87210d7fb3 100644
--- a/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs
+++ b/tests/ui/traits/next-solver/higher-ranked-dyn-bounds.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Trait<'a> {
diff --git a/tests/ui/traits/new-solver/int-var-alias-eq.rs b/tests/ui/traits/next-solver/int-var-alias-eq.rs
index 790197e2d97..26ba7f8e511 100644
--- a/tests/ui/traits/new-solver/int-var-alias-eq.rs
+++ b/tests/ui/traits/next-solver/int-var-alias-eq.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // HIR typeck ends up equating `<?0i as Add>::Output == ?0i`.
 // Want to make sure that we emit an alias-eq goal for this,
diff --git a/tests/ui/traits/new-solver/int-var-is-send.rs b/tests/ui/traits/next-solver/int-var-is-send.rs
index 083aa90e1f6..d8b963f2008 100644
--- a/tests/ui/traits/new-solver/int-var-is-send.rs
+++ b/tests/ui/traits/next-solver/int-var-is-send.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn needs_send(_: impl Send) {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs
new file mode 100644
index 00000000000..10fb7d525b7
--- /dev/null
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Znext-solver
+//
+// This is a gnarly test but I don't know how to minimize it, frankly.
+
+#![feature(lazy_type_alias)]
+//~^ WARN the feature `lazy_type_alias` is incomplete
+
+trait ToUnit<'a> {
+    type Unit;
+}
+
+trait Overlap<T> {}
+
+type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
+
+impl<T> Overlap<T> for T {}
+
+impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
+//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
+//~| ERROR cannot find type `Missing` in this scope
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
new file mode 100644
index 00000000000..c16a48d5f15
--- /dev/null
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -0,0 +1,36 @@
+error[E0412]: cannot find type `Missing` in this scope
+  --> $DIR/issue-118950-root-region.rs:18:55
+   |
+LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
+   |                                                       ^^^^^^^ not found in this scope
+
+warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-118950-root-region.rs:5:12
+   |
+LL | #![feature(lazy_type_alias)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
+error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
+  --> $DIR/issue-118950-root-region.rs:18:1
+   |
+LL | impl<T> Overlap<T> for T {}
+   | ------------------------ first implementation here
+LL |
+LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0119, E0412.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/new-solver/iter-filter-projection.rs b/tests/ui/traits/next-solver/iter-filter-projection.rs
index 8fb62323aa5..f948831ad52 100644
--- a/tests/ui/traits/new-solver/iter-filter-projection.rs
+++ b/tests/ui/traits/next-solver/iter-filter-projection.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 use std::{iter, slice};
diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-1.rs b/tests/ui/traits/next-solver/lazy-nested-obligations-1.rs
index af00cbb3ba8..f9e73a93c27 100644
--- a/tests/ui/traits/new-solver/lazy-nested-obligations-1.rs
+++ b/tests/ui/traits/next-solver/lazy-nested-obligations-1.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // Issue 94358
 
 fn foo<C>(_: C)
diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs b/tests/ui/traits/next-solver/lazy-nested-obligations-2.rs
index 20f504928c7..b85f9d9736c 100644
--- a/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs
+++ b/tests/ui/traits/next-solver/lazy-nested-obligations-2.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 pub trait With {
diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-3.rs b/tests/ui/traits/next-solver/lazy-nested-obligations-3.rs
index baf39957240..5fb4832dd08 100644
--- a/tests/ui/traits/new-solver/lazy-nested-obligations-3.rs
+++ b/tests/ui/traits/next-solver/lazy-nested-obligations-3.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // Issue 96750
 
 use std::marker::PhantomData;
diff --git a/tests/ui/traits/new-solver/member-constraints-in-root-universe.rs b/tests/ui/traits/next-solver/member-constraints-in-root-universe.rs
index 97c44305864..16e95e94ce5 100644
--- a/tests/ui/traits/new-solver/member-constraints-in-root-universe.rs
+++ b/tests/ui/traits/next-solver/member-constraints-in-root-universe.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Trait {
diff --git a/tests/ui/traits/new-solver/more-object-bound.rs b/tests/ui/traits/next-solver/more-object-bound.rs
index bb730b18ef7..8522f034d87 100644
--- a/tests/ui/traits/new-solver/more-object-bound.rs
+++ b/tests/ui/traits/next-solver/more-object-bound.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // From #80800
 
 trait SuperTrait {
diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr
index e3be2931e12..e3be2931e12 100644
--- a/tests/ui/traits/new-solver/more-object-bound.stderr
+++ b/tests/ui/traits/next-solver/more-object-bound.stderr
diff --git a/tests/ui/traits/new-solver/negative-coherence-bounds.rs b/tests/ui/traits/next-solver/negative-coherence-bounds.rs
index 5436b02c3de..5436b02c3de 100644
--- a/tests/ui/traits/new-solver/negative-coherence-bounds.rs
+++ b/tests/ui/traits/next-solver/negative-coherence-bounds.rs
diff --git a/tests/ui/traits/new-solver/negative-coherence-bounds.stderr b/tests/ui/traits/next-solver/negative-coherence-bounds.stderr
index 4127f51f56d..4127f51f56d 100644
--- a/tests/ui/traits/new-solver/negative-coherence-bounds.stderr
+++ b/tests/ui/traits/next-solver/negative-coherence-bounds.stderr
diff --git a/tests/ui/traits/new-solver/nested-alias-bound.rs b/tests/ui/traits/next-solver/nested-alias-bound.rs
index c365902dbe5..2e3de0ac66d 100644
--- a/tests/ui/traits/new-solver/nested-alias-bound.rs
+++ b/tests/ui/traits/next-solver/nested-alias-bound.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait A {
diff --git a/tests/ui/traits/new-solver/nested-obligations-with-bound-vars-gat.rs b/tests/ui/traits/next-solver/nested-obligations-with-bound-vars-gat.rs
index 92bad959095..94c6c285680 100644
--- a/tests/ui/traits/new-solver/nested-obligations-with-bound-vars-gat.rs
+++ b/tests/ui/traits/next-solver/nested-obligations-with-bound-vars-gat.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // Issue 96230
 
 use std::fmt::Debug;
diff --git a/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs b/tests/ui/traits/next-solver/normalize-async-closure-in-trait.rs
index cc16cc87169..b58db2be841 100644
--- a/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs
+++ b/tests/ui/traits/next-solver/normalize-async-closure-in-trait.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 // edition:2021
 
diff --git a/tests/ui/traits/new-solver/normalize-param-env-1.rs b/tests/ui/traits/next-solver/normalize-param-env-1.rs
index b02a5d62330..92d4051378b 100644
--- a/tests/ui/traits/new-solver/normalize-param-env-1.rs
+++ b/tests/ui/traits/next-solver/normalize-param-env-1.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // Issue 108933
 
 trait Add<Rhs> {
diff --git a/tests/ui/traits/new-solver/normalize-param-env-2.rs b/tests/ui/traits/next-solver/normalize-param-env-2.rs
index 7c2cebdd200..ce084651bfb 100644
--- a/tests/ui/traits/new-solver/normalize-param-env-2.rs
+++ b/tests/ui/traits/next-solver/normalize-param-env-2.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // Issue 92505
 
 trait A<T> {
diff --git a/tests/ui/traits/new-solver/normalize-param-env-3.rs b/tests/ui/traits/next-solver/normalize-param-env-3.rs
index ce2974b2a16..e15e1155a1a 100644
--- a/tests/ui/traits/new-solver/normalize-param-env-3.rs
+++ b/tests/ui/traits/next-solver/normalize-param-env-3.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // Issue 100177
 
 trait GenericTrait<T> {}
diff --git a/tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs b/tests/ui/traits/next-solver/normalize-rcvr-for-inherent.rs
index d70534feb07..d308b1695f5 100644
--- a/tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs
+++ b/tests/ui/traits/next-solver/normalize-rcvr-for-inherent.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // Verify that we can assemble inherent impl candidates on a possibly
diff --git a/tests/ui/traits/new-solver/normalize-unsize-rhs.rs b/tests/ui/traits/next-solver/normalize-unsize-rhs.rs
index 1bb5c9b4111..6ca82d1b872 100644
--- a/tests/ui/traits/new-solver/normalize-unsize-rhs.rs
+++ b/tests/ui/traits/next-solver/normalize-unsize-rhs.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait A {}
diff --git a/tests/ui/traits/new-solver/normalized-const-built-in-op.rs b/tests/ui/traits/next-solver/normalized-const-built-in-op.rs
index 2443e517813..0fffe7b4369 100644
--- a/tests/ui/traits/new-solver/normalized-const-built-in-op.rs
+++ b/tests/ui/traits/next-solver/normalized-const-built-in-op.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 const fn foo() {
diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs
index 46343241b45..7dc87daccd9 100644
--- a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs
+++ b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs
@@ -1,5 +1,5 @@
 // [no_self_infer] check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // revisions: self_infer no_self_infer
 
 // checks that the new solver is smart enough to infer `?0 = U` when solving:
@@ -7,7 +7,7 @@
 // with `normalizes-to(<Vec<U> as Trait>::Assoc, u8)` in the paramenv even when
 // there is a separate `Vec<T>: Trait` bound  in the paramenv.
 //
-// FIXME(-Ztrait-solver=next)
+// FIXME(-Znext-solver)
 // This could also compile for `normalizes-to(<?0 as Trait>::Assoc, u8)` but
 // we currently immediately consider a goal ambiguous if the self type is an
 // inference variable.
diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr
index c1a8b74df08..c1a8b74df08 100644
--- a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr
+++ b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr
diff --git a/tests/ui/traits/new-solver/object-soundness-requires-generalization.rs b/tests/ui/traits/next-solver/object-soundness-requires-generalization.rs
index d02dada72c9..6e709d9ae8e 100644
--- a/tests/ui/traits/new-solver/object-soundness-requires-generalization.rs
+++ b/tests/ui/traits/next-solver/object-soundness-requires-generalization.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // ignore-test
 
 trait Trait {
diff --git a/tests/ui/traits/new-solver/object-unsafety.rs b/tests/ui/traits/next-solver/object-unsafety.rs
index da843c91478..8aae7217398 100644
--- a/tests/ui/traits/new-solver/object-unsafety.rs
+++ b/tests/ui/traits/next-solver/object-unsafety.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Setup {
     type From: Copy;
@@ -17,7 +17,7 @@ pub fn copy_any<T>(t: &T) -> T {
     //~| ERROR the type `<dyn Setup<From = T> as Setup>::From` is not well-formed
     //~| ERROR the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time
 
-    // FIXME(-Ztrait-solver=next): These error messages are horrible and some of them
+    // FIXME(-Znext-solver): These error messages are horrible and some of them
     // are even simple fallout from previous error.
 }
 
diff --git a/tests/ui/traits/new-solver/object-unsafety.stderr b/tests/ui/traits/next-solver/object-unsafety.stderr
index 914a8f9d4c5..914a8f9d4c5 100644
--- a/tests/ui/traits/new-solver/object-unsafety.stderr
+++ b/tests/ui/traits/next-solver/object-unsafety.stderr
diff --git a/tests/ui/traits/new-solver/opportunistic-region-resolve.rs b/tests/ui/traits/next-solver/opportunistic-region-resolve.rs
index 2610789cd48..d852332d0e5 100644
--- a/tests/ui/traits/new-solver/opportunistic-region-resolve.rs
+++ b/tests/ui/traits/next-solver/opportunistic-region-resolve.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 #![feature(rustc_attrs)]
diff --git a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs
index 3d2e70a639f..a465bcecfe0 100644
--- a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs
+++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Trait {}
 
diff --git a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
index 90b54b1e789..90b54b1e789 100644
--- a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr
+++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
diff --git a/tests/ui/traits/new-solver/overflow/global-cache.rs b/tests/ui/traits/next-solver/overflow/global-cache.rs
index adc03da04a8..fe4032ca62e 100644
--- a/tests/ui/traits/new-solver/overflow/global-cache.rs
+++ b/tests/ui/traits/next-solver/overflow/global-cache.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // Check that we consider the reached depth of global cache
 // entries when detecting overflow. We would otherwise be unstable
diff --git a/tests/ui/traits/new-solver/overflow/global-cache.stderr b/tests/ui/traits/next-solver/overflow/global-cache.stderr
index 67616619384..67616619384 100644
--- a/tests/ui/traits/new-solver/overflow/global-cache.stderr
+++ b/tests/ui/traits/next-solver/overflow/global-cache.stderr
diff --git a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
index 539c9614e82..52a17a14281 100644
--- a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.rs
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
@@ -2,7 +2,7 @@
 //~| ERROR overflow evaluating the requirement `Self: Trait`
 
 // This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
-// compile-flags: -Ztrait-solver=next --crate-type=lib
+// compile-flags: -Znext-solver --crate-type=lib
 // check-fail
 
 #![recursion_limit = "0"]
diff --git a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.stderr b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
index 16b25d90ace..16b25d90ace 100644
--- a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
index 3e10b2b595e..327ef865de9 100644
--- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Foo1 {
     type Assoc1;
diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
index eda62b99c44..eda62b99c44 100644
--- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
index 36ef856a466..f45d208e666 100644
--- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Foo {
     type Assoc;
diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
index b0a0a69761a..b0a0a69761a 100644
--- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
diff --git a/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs b/tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs
index bdf999ec5dd..f67b073c53c 100644
--- a/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs
+++ b/tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Foo {
diff --git a/tests/ui/traits/new-solver/param-discr-kind.rs b/tests/ui/traits/next-solver/param-discr-kind.rs
index e319ddea106..c66b0b9f45f 100644
--- a/tests/ui/traits/new-solver/param-discr-kind.rs
+++ b/tests/ui/traits/next-solver/param-discr-kind.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn foo<T>(x: T) {
diff --git a/tests/ui/traits/new-solver/pointee.rs b/tests/ui/traits/next-solver/pointee.rs
index 93c0542ace4..a56df549a8d 100644
--- a/tests/ui/traits/new-solver/pointee.rs
+++ b/tests/ui/traits/next-solver/pointee.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 #![feature(ptr_metadata)]
 
diff --git a/tests/ui/traits/new-solver/pointer-like.rs b/tests/ui/traits/next-solver/pointer-like.rs
index 98630176976..f6cc718c6e2 100644
--- a/tests/ui/traits/new-solver/pointer-like.rs
+++ b/tests/ui/traits/next-solver/pointer-like.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 #![feature(pointer_like_trait)]
 
diff --git a/tests/ui/traits/new-solver/pointer-like.stderr b/tests/ui/traits/next-solver/pointer-like.stderr
index 4b624fd0d35..4b624fd0d35 100644
--- a/tests/ui/traits/new-solver/pointer-like.stderr
+++ b/tests/ui/traits/next-solver/pointer-like.stderr
diff --git a/tests/ui/traits/new-solver/prefer-candidate-no-constraints.rs b/tests/ui/traits/next-solver/prefer-candidate-no-constraints.rs
index 6f8164f3a40..a47f819f192 100644
--- a/tests/ui/traits/new-solver/prefer-candidate-no-constraints.rs
+++ b/tests/ui/traits/next-solver/prefer-candidate-no-constraints.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Foo {}
diff --git a/tests/ui/traits/new-solver/prefer-param-env-on-ambiguity.rs b/tests/ui/traits/next-solver/prefer-param-env-on-ambiguity.rs
index 909b33ec3d5..f8c0223e187 100644
--- a/tests/ui/traits/new-solver/prefer-param-env-on-ambiguity.rs
+++ b/tests/ui/traits/next-solver/prefer-param-env-on-ambiguity.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Foo<'a> {}
diff --git a/tests/ui/traits/new-solver/projection-discr-kind.rs b/tests/ui/traits/next-solver/projection-discr-kind.rs
index 20296b287b1..bf557f8633a 100644
--- a/tests/ui/traits/new-solver/projection-discr-kind.rs
+++ b/tests/ui/traits/next-solver/projection-discr-kind.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // Check that `<T::Assoc as DiscriminantKind>::Discriminant` doesn't normalize
 // to itself and cause overflow/ambiguity.
diff --git a/tests/ui/traits/new-solver/projection-discr-kind.stderr b/tests/ui/traits/next-solver/projection-discr-kind.stderr
index 69999c75522..69999c75522 100644
--- a/tests/ui/traits/new-solver/projection-discr-kind.stderr
+++ b/tests/ui/traits/next-solver/projection-discr-kind.stderr
diff --git a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs
index e36d574efe2..b337c067374 100644
--- a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs
+++ b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // See https://github.com/rust-lang/trait-system-refactor-initiative/issues/1
 // a minimization of a pattern in core.
diff --git a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs
index c8050997a1d..db8dc1eb9be 100644
--- a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs
+++ b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // See https://github.com/rust-lang/trait-system-refactor-initiative/issues/1,
 // a minimization of a pattern in core.
diff --git a/tests/ui/traits/new-solver/slice-match-byte-lit.rs b/tests/ui/traits/next-solver/slice-match-byte-lit.rs
index 4f848062595..1edc9f1e8e9 100644
--- a/tests/ui/traits/new-solver/slice-match-byte-lit.rs
+++ b/tests/ui/traits/next-solver/slice-match-byte-lit.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 fn test(s: &[u8]) {
diff --git a/tests/ui/traits/new-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs
index fac7d76f8cf..58b62f52dfd 100644
--- a/tests/ui/traits/new-solver/specialization-transmute.rs
+++ b/tests/ui/traits/next-solver/specialization-transmute.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 #![feature(specialization)]
 //~^ WARN the feature `specialization` is incomplete
diff --git a/tests/ui/traits/new-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr
index eaf32a475ac..eaf32a475ac 100644
--- a/tests/ui/traits/new-solver/specialization-transmute.stderr
+++ b/tests/ui/traits/next-solver/specialization-transmute.stderr
diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.rs b/tests/ui/traits/next-solver/specialization-unconstrained.rs
index 7fd753109be..950fb1512bc 100644
--- a/tests/ui/traits/new-solver/specialization-unconstrained.rs
+++ b/tests/ui/traits/next-solver/specialization-unconstrained.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 #![feature(specialization)]
 //~^ WARN the feature `specialization` is incomplete
diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/next-solver/specialization-unconstrained.stderr
index ed4dafa1484..ed4dafa1484 100644
--- a/tests/ui/traits/new-solver/specialization-unconstrained.stderr
+++ b/tests/ui/traits/next-solver/specialization-unconstrained.stderr
diff --git a/tests/ui/traits/new-solver/stall-num-var-auto-trait.fallback.stderr b/tests/ui/traits/next-solver/stall-num-var-auto-trait.fallback.stderr
index 2e3c22c8d38..2e3c22c8d38 100644
--- a/tests/ui/traits/new-solver/stall-num-var-auto-trait.fallback.stderr
+++ b/tests/ui/traits/next-solver/stall-num-var-auto-trait.fallback.stderr
diff --git a/tests/ui/traits/new-solver/stall-num-var-auto-trait.rs b/tests/ui/traits/next-solver/stall-num-var-auto-trait.rs
index 0539c3a4292..f5bf985cdb2 100644
--- a/tests/ui/traits/new-solver/stall-num-var-auto-trait.rs
+++ b/tests/ui/traits/next-solver/stall-num-var-auto-trait.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // revisions: fallback constrain
 //[constrain] check-pass
 
diff --git a/tests/ui/traits/new-solver/structural-resolve-field.rs b/tests/ui/traits/next-solver/structural-resolve-field.rs
index 01899c9ad64..b247e237534 100644
--- a/tests/ui/traits/new-solver/structural-resolve-field.rs
+++ b/tests/ui/traits/next-solver/structural-resolve-field.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 #[derive(Default)]
diff --git a/tests/ui/traits/new-solver/tait-eq-proj-2.rs b/tests/ui/traits/next-solver/tait-eq-proj-2.rs
index 77ea8bc246e..a3df053dd83 100644
--- a/tests/ui/traits/new-solver/tait-eq-proj-2.rs
+++ b/tests/ui/traits/next-solver/tait-eq-proj-2.rs
@@ -1,9 +1,9 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 #![feature(type_alias_impl_trait)]
 
-// Similar to tests/ui/traits/new-solver/tait-eq-proj.rs
+// Similar to tests/ui/traits/next-solver/tait-eq-proj.rs
 // but check the alias-sub relation in the other direction.
 
 type Tait = impl Iterator<Item = impl Sized>;
diff --git a/tests/ui/traits/new-solver/tait-eq-proj.rs b/tests/ui/traits/next-solver/tait-eq-proj.rs
index 01ef2ec953a..871e8e1e9fc 100644
--- a/tests/ui/traits/new-solver/tait-eq-proj.rs
+++ b/tests/ui/traits/next-solver/tait-eq-proj.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/traits/new-solver/tait-eq-tait.rs b/tests/ui/traits/next-solver/tait-eq-tait.rs
index 70d9dc0eaa8..2629a124c3a 100644
--- a/tests/ui/traits/new-solver/tait-eq-tait.rs
+++ b/tests/ui/traits/next-solver/tait-eq-tait.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // Not exactly sure if this is the inference behavior we *want*,
diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/next-solver/temporary-ambiguity.rs
index c6c11a1a1de..6102de7e446 100644
--- a/tests/ui/traits/new-solver/temporary-ambiguity.rs
+++ b/tests/ui/traits/next-solver/temporary-ambiguity.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 // Checks that we don't explode when we assemble >1 candidate for a goal.
diff --git a/tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs b/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs
index 79114b93b78..2a482f74668 100644
--- a/tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs
+++ b/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 pub trait A {}
 pub trait B: A {}
diff --git a/tests/ui/traits/new-solver/try-example.rs b/tests/ui/traits/next-solver/try-example.rs
index e826f3a0059..92b0b597881 100644
--- a/tests/ui/traits/new-solver/try-example.rs
+++ b/tests/ui/traits/next-solver/try-example.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 use std::error::Error;
 
diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.rs
index 3c7fc0d813d..d25e372b5d8 100644
--- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs
+++ b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // When we're solving `<T as Foo>::Assoc = i32`, we actually first solve
 // `<T as Foo>::Assoc = ?1t`, then unify `?1t` with `i32`. That goal
diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.stderr
index dfff9f11b87..dfff9f11b87 100644
--- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr
+++ b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.stderr
diff --git a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.fails.stderr b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr
index 4be90c702a0..4be90c702a0 100644
--- a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.fails.stderr
+++ b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr
diff --git a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.rs b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs
index 26c595bc974..77a169d48de 100644
--- a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.rs
+++ b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // revisions: works fails
 //[works] check-pass
 
diff --git a/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs b/tests/ui/traits/next-solver/unsafe-auto-trait-impl.rs
index bcfc747ebb1..f66bf0b87ec 100644
--- a/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs
+++ b/tests/ui/traits/next-solver/unsafe-auto-trait-impl.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 struct Foo(*mut ());
diff --git a/tests/ui/traits/new-solver/unsize-although-ambiguous.rs b/tests/ui/traits/next-solver/unsize-although-ambiguous.rs
index 431988a5fff..8217701b9f8 100644
--- a/tests/ui/traits/new-solver/unsize-although-ambiguous.rs
+++ b/tests/ui/traits/next-solver/unsize-although-ambiguous.rs
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 use std::fmt::Display;
 
diff --git a/tests/ui/traits/new-solver/unsize-good.rs b/tests/ui/traits/next-solver/unsize-good.rs
index 87ed9cfd10a..04ebe66f21c 100644
--- a/tests/ui/traits/new-solver/unsize-good.rs
+++ b/tests/ui/traits/next-solver/unsize-good.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 #![feature(unsized_tuple_coercion)]
diff --git a/tests/ui/traits/new-solver/upcast-right-substs.rs b/tests/ui/traits/next-solver/upcast-right-substs.rs
index 97eb189d5c7..5e4d958c895 100644
--- a/tests/ui/traits/new-solver/upcast-right-substs.rs
+++ b/tests/ui/traits/next-solver/upcast-right-substs.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 // check-pass
 
 trait Foo: Bar<i32> + Bar<u32> {}
diff --git a/tests/ui/traits/new-solver/upcast-wrong-substs.rs b/tests/ui/traits/next-solver/upcast-wrong-substs.rs
index 3376f9787d3..0cd253007fc 100644
--- a/tests/ui/traits/new-solver/upcast-wrong-substs.rs
+++ b/tests/ui/traits/next-solver/upcast-wrong-substs.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 trait Foo: Bar<i32> + Bar<u32> {}
 
diff --git a/tests/ui/traits/new-solver/upcast-wrong-substs.stderr b/tests/ui/traits/next-solver/upcast-wrong-substs.stderr
index 00ba1ef678f..00ba1ef678f 100644
--- a/tests/ui/traits/new-solver/upcast-wrong-substs.stderr
+++ b/tests/ui/traits/next-solver/upcast-wrong-substs.stderr
diff --git a/tests/ui/traits/new-solver/winnow-specializing-impls.rs b/tests/ui/traits/next-solver/winnow-specializing-impls.rs
index 06f64de7403..d70a9159611 100644
--- a/tests/ui/traits/new-solver/winnow-specializing-impls.rs
+++ b/tests/ui/traits/next-solver/winnow-specializing-impls.rs
@@ -1,5 +1,5 @@
 // build-pass
-// compile-flags: -Ztrait-solver=next
+// compile-flags: -Znext-solver
 
 // Tests that the specializing impl `<() as Foo>` holds during codegen.
 
diff --git a/tests/ui/traits/non-lifetime-via-dyn-builtin.rs b/tests/ui/traits/non-lifetime-via-dyn-builtin.rs
index 9a8a5ced2e2..996cd295dc4 100644
--- a/tests/ui/traits/non-lifetime-via-dyn-builtin.rs
+++ b/tests/ui/traits/non-lifetime-via-dyn-builtin.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 
 #![feature(non_lifetime_binders)]
diff --git a/tests/ui/traits/reservation-impl/coherence-conflict.rs b/tests/ui/traits/reservation-impl/coherence-conflict.rs
index 6bbd90f94dc..cdea162d64a 100644
--- a/tests/ui/traits/reservation-impl/coherence-conflict.rs
+++ b/tests/ui/traits/reservation-impl/coherence-conflict.rs
@@ -1,6 +1,6 @@
 // check that reservation impls are accounted for in negative reasoning.
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 #![feature(rustc_attrs)]
 
 trait MyTrait {}
diff --git a/tests/ui/traits/reservation-impl/no-use.rs b/tests/ui/traits/reservation-impl/no-use.rs
index 864f1791fd0..10aad3605ea 100644
--- a/tests/ui/traits/reservation-impl/no-use.rs
+++ b/tests/ui/traits/reservation-impl/no-use.rs
@@ -1,6 +1,6 @@
 // check that reservation impls can't be used as normal impls in positive reasoning.
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 #![feature(rustc_attrs)]
 
 trait MyTrait { fn foo(&self); }
diff --git a/tests/ui/traits/reservation-impl/non-lattice-ok.rs b/tests/ui/traits/reservation-impl/non-lattice-ok.rs
index 7787904d9b2..9a3c2b4f991 100644
--- a/tests/ui/traits/reservation-impl/non-lattice-ok.rs
+++ b/tests/ui/traits/reservation-impl/non-lattice-ok.rs
@@ -34,7 +34,7 @@
 // check that reservation impls can't be used as normal impls in positive reasoning.
 
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(rustc_attrs, never_type)]
 
diff --git a/tests/ui/traits/reservation-impl/ok.rs b/tests/ui/traits/reservation-impl/ok.rs
index 8ff6645a2b3..2d945f6adeb 100644
--- a/tests/ui/traits/reservation-impl/ok.rs
+++ b/tests/ui/traits/reservation-impl/ok.rs
@@ -4,7 +4,7 @@
 // but still.
 
 // revisions: old next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(rustc_attrs)]
 
diff --git a/tests/ui/traits/trait-upcasting/fewer-associated.rs b/tests/ui/traits/trait-upcasting/fewer-associated.rs
index 937818aac58..e7ca6fa5208 100644
--- a/tests/ui/traits/trait-upcasting/fewer-associated.rs
+++ b/tests/ui/traits/trait-upcasting/fewer-associated.rs
@@ -1,7 +1,7 @@
 // check-pass
 // issue: 114035
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 trait A: B {
     type Assoc;
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs
index 4b730dab7cc..5a493fd48b3 100644
--- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 trait Super {
     type Assoc;
diff --git a/tests/ui/traits/trait-upcasting/issue-11515.rs b/tests/ui/traits/trait-upcasting/issue-11515.rs
index 66ab1ce260a..a1edb53ec37 100644
--- a/tests/ui/traits/trait-upcasting/issue-11515.rs
+++ b/tests/ui/traits/trait-upcasting/issue-11515.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 struct Test {
     func: Box<dyn FnMut() + 'static>,
diff --git a/tests/ui/traits/trait-upcasting/normalization.rs b/tests/ui/traits/trait-upcasting/normalization.rs
index c57640e7e34..b594969483a 100644
--- a/tests/ui/traits/trait-upcasting/normalization.rs
+++ b/tests/ui/traits/trait-upcasting/normalization.rs
@@ -1,7 +1,7 @@
 // check-pass
 // issue: 114113
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 trait Mirror {
     type Assoc;
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
index 3b6ec3b65e7..7d3deeeaa61 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 trait Foo: Bar<i32> + Bar<u32> {}
 trait Bar<T> {
diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs
index 9981d436062..f8cf793e4a4 100644
--- a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs
+++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 struct Wrapper<T: ?Sized>(T);
 
diff --git a/tests/ui/transmutability/primitives/bool-mut.rs b/tests/ui/transmutability/primitives/bool-mut.rs
index 49dbe90e4b8..6ee168d1a71 100644
--- a/tests/ui/transmutability/primitives/bool-mut.rs
+++ b/tests/ui/transmutability/primitives/bool-mut.rs
@@ -1,5 +1,5 @@
 // check-fail
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(transmutability)]
 mod assert {
diff --git a/tests/ui/transmutability/primitives/bool.rs b/tests/ui/transmutability/primitives/bool.rs
index 654e7b47ede..ac4024b7f33 100644
--- a/tests/ui/transmutability/primitives/bool.rs
+++ b/tests/ui/transmutability/primitives/bool.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(transmutability)]
 mod assert {
diff --git a/tests/ui/transmutability/primitives/numbers.rs b/tests/ui/transmutability/primitives/numbers.rs
index e980e91ed06..1afc7d677ee 100644
--- a/tests/ui/transmutability/primitives/numbers.rs
+++ b/tests/ui/transmutability/primitives/numbers.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![crate_type = "lib"]
 #![feature(transmutability)]
diff --git a/tests/ui/transmutability/primitives/unit.rs b/tests/ui/transmutability/primitives/unit.rs
index 12eac175106..5ea96cf8ba7 100644
--- a/tests/ui/transmutability/primitives/unit.rs
+++ b/tests/ui/transmutability/primitives/unit.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 //! The unit type, `()`, should be one byte.
 
diff --git a/tests/ui/type-alias-impl-trait/assoc-type-const.rs b/tests/ui/type-alias-impl-trait/assoc-type-const.rs
index 6632a3450e5..e385fe045fc 100644
--- a/tests/ui/type-alias-impl-trait/assoc-type-const.rs
+++ b/tests/ui/type-alias-impl-trait/assoc-type-const.rs
@@ -3,7 +3,7 @@
 
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 #![feature(impl_trait_in_assoc_type)]
 
 trait UnwrapItemsExt<'a, const C: usize> {
diff --git a/tests/ui/type-alias-impl-trait/cross_inference.rs b/tests/ui/type-alias-impl-trait/cross_inference.rs
index 5eaf0ddda99..c5ef75fee61 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
index 386b77d4d16..af1c18bbb59 100644
--- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
+++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
@@ -2,7 +2,7 @@
 // Tests that we don't ICE when we have a trait impl on a TAIT.
 
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/type-alias-impl-trait/issue-78450.rs b/tests/ui/type-alias-impl-trait/issue-78450.rs
index 236e9f4e88c..c51dfb6782b 100644
--- a/tests/ui/type-alias-impl-trait/issue-78450.rs
+++ b/tests/ui/type-alias-impl-trait/issue-78450.rs
@@ -1,6 +1,6 @@
 // check-pass
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(impl_trait_in_assoc_type)]
 
diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs
index 8d80546444a..371cac6da7c 100644
--- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs
+++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs
@@ -1,7 +1,7 @@
 // Regression test for #112691
 //
 // revisions: current next
-// [next] compile-flags: -Ztrait-solver=next
+// [next] compile-flags: -Znext-solver
 // [next] check-pass
 // [current]: known-bug: #112691
 
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
index 0f0002f7797..222841f3467 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
@@ -6,7 +6,7 @@
 //! have a situation where the RPIT gets constrained outside its anchor.
 
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 //[next] check-pass
 
 //[current] known-bug: #108498
diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs
index b966ca4bff0..22e2b0efd1f 100644
--- a/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs
+++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs
@@ -2,7 +2,7 @@
 //
 // revisions: pass pass_next fail
 // [pass] check-pass
-// [pass_next] compile-flags: -Ztrait-solver=next
+// [pass_next] compile-flags: -Znext-solver
 // [pass_next] check-pass
 // [fail] check-fail
 
diff --git a/tests/ui/unsized/issue-71659.rs b/tests/ui/unsized/issue-71659.rs
index db5c2e205aa..65a867caf8f 100644
--- a/tests/ui/unsized/issue-71659.rs
+++ b/tests/ui/unsized/issue-71659.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 
 #![feature(unsize)]
 
diff --git a/tests/ui/unsized/issue-75899.rs b/tests/ui/unsized/issue-75899.rs
index 71943103291..56c8a72bfcc 100644
--- a/tests/ui/unsized/issue-75899.rs
+++ b/tests/ui/unsized/issue-75899.rs
@@ -1,5 +1,5 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
+//[next] compile-flags: -Znext-solver
 // check-pass
 
 trait Trait {}
diff --git a/triagebot.toml b/triagebot.toml
index 30f049c79d6..2867bbc8171 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -441,6 +441,14 @@ cc = ["@rust-lang/miri"]
 message = "Some changes occurred in need_type_info.rs"
 cc = ["@lcnr"]
 
+[mentions."compiler/rustc_middle/src/ty/relate.rs"]
+message = "Type relation code was changed"
+cc = ["@compiler-errors", "@lcnr"]
+
+[mentions."compiler/rustc_infer/src/infer/relate"]
+message = "Type relation code was changed"
+cc = ["@compiler-errors", "@lcnr"]
+
 [mentions."compiler/rustc_middle/src/mir/interpret"]
 message = "Some changes occurred to the CTFE / Miri engine"
 cc = ["@rust-lang/miri"]
@@ -555,15 +563,15 @@ cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@davidtwco", "@celinval", "@vakar
 
 [mentions."compiler/rustc_error_messages"]
 message = "`rustc_error_messages` was changed"
-cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
+cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
 
 [mentions."compiler/rustc_errors/src/translation.rs"]
 message = "`rustc_errors::translation` was changed"
-cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
+cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
 
 [mentions."compiler/rustc_macros/src/diagnostics"]
 message = "`rustc_macros::diagnostics` was changed"
-cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
+cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
 
 [mentions."compiler/stable_mir"]
 message = "This PR changes Stable MIR"