about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--.gitmodules2
-rw-r--r--.mailmap8
-rw-r--r--Cargo.lock780
-rw-r--r--RELEASES.md123
-rw-r--r--bootstrap.example.toml5
-rw-r--r--compiler/rustc_abi/src/lib.rs3
-rw-r--r--compiler/rustc_ast/src/ast.rs178
-rw-r--r--compiler/rustc_ast/src/ast_traits.rs2
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs8
-rw-r--r--compiler/rustc_ast/src/expand/autodiff_attrs.rs13
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs86
-rw-r--r--compiler/rustc_ast/src/token.rs92
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs62
-rw-r--r--compiler/rustc_ast/src/util/parser.rs24
-rw-r--r--compiler/rustc_ast/src/visit.rs87
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs28
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs350
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs382
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs33
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs15
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs83
-rw-r--r--compiler/rustc_borrowck/messages.ftl7
-rw-r--r--compiler/rustc_borrowck/src/consumers.rs7
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs15
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/var_name.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs53
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs183
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs11
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl1
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs11
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs367
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs17
-rw-r--r--compiler/rustc_builtin_macros/src/edition_panic.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs20
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs40
-rw-r--r--compiler/rustc_builtin_macros/src/standard_library_imports.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs62
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs46
-rw-r--r--compiler/rustc_codegen_cranelift/.cirrus.yml41
-rw-r--r--compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md18
-rw-r--r--compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml13
-rw-r--r--compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js162
-rw-r--r--compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json571
-rw-r--r--compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json11
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml12
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/main.yml43
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml6
-rw-r--r--compiler/rustc_codegen_cranelift/.vscode/settings.json33
-rw-r--r--compiler/rustc_codegen_cranelift/.zed/settings.json25
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock87
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml24
-rw-r--r--compiler/rustc_codegen_cranelift/Readme.md2
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs80
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/utils.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/config.txt2
-rw-r--r--compiler/rustc_codegen_cranelift/docs/usage.md11
-rw-r--r--compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs16
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch (renamed from compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch)12
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch48
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch105
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch26
-rw-r--r--compiler/rustc_codegen_cranelift/patches/coretests-lock.toml35
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rw-r--r--compiler/rustc_codegen_cranelift/rustfmt.toml4
-rw-r--r--compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs14
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/filter_profile.rs2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/rustup.sh2
-rw-r--r--compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh23
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh58
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/src/config.rs34
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/types.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs225
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs48
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs123
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs26
-rw-r--r--compiler/rustc_codegen_cranelift/src/num.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl2
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs50
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs30
-rw-r--r--compiler/rustc_codegen_llvm/src/builder/autodiff.rs199
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs62
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs2
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/apple.rs131
-rw-r--r--compiler/rustc_codegen_ssa/src/back/apple/tests.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/back/mod.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath/tests.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs36
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs6
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs43
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs2
-rw-r--r--compiler/rustc_data_structures/src/fx.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs48
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs4
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs21
-rw-r--r--compiler/rustc_errors/src/json.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs39
-rw-r--r--compiler/rustc_expand/src/base.rs7
-rw-r--r--compiler/rustc_expand/src/build.rs17
-rw-r--r--compiler/rustc_expand/src/expand.rs13
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs35
-rw-r--r--compiler/rustc_expand/src/placeholders.rs7
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
-rw-r--r--compiler/rustc_feature/src/removed.rs3
-rw-r--r--compiler/rustc_feature/src/unstable.rs5
-rw-r--r--compiler/rustc_hir/src/def.rs2
-rw-r--r--compiler/rustc_hir/src/definitions.rs15
-rw-r--r--compiler/rustc_hir/src/hir.rs10
-rw-r--r--compiler/rustc_hir/src/hir_id.rs22
-rw-r--r--compiler/rustc_hir/src/lang_items.rs6
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/always_applicable.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs47
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs298
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs63
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs59
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs331
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs245
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs44
-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_pretty/src/lib.rs29
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs68
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs156
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs65
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs343
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs56
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs94
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs42
-rw-r--r--compiler/rustc_interface/messages.ftl6
-rw-r--r--compiler/rustc_interface/src/errors.rs14
-rw-r--r--compiler/rustc_interface/src/interface.rs8
-rw-r--r--compiler/rustc_interface/src/passes.rs44
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl22
-rw-r--r--compiler/rustc_lint/src/builtin.rs8
-rw-r--r--compiler/rustc_lint/src/context.rs15
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs2
-rw-r--r--compiler/rustc_lint/src/levels.rs124
-rw-r--r--compiler/rustc_lint/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/lints.rs26
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs9
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs22
-rw-r--r--compiler/rustc_lint/src/ptr_nulls.rs128
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs44
-rw-r--r--compiler/rustc_lint/src/types.rs53
-rw-r--r--compiler/rustc_lint/src/utils.rs55
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs57
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp71
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp91
-rw-r--r--compiler/rustc_metadata/messages.ftl4
-rw-r--r--compiler/rustc_metadata/src/creader.rs60
-rw-r--r--compiler/rustc_metadata/src/errors.rs9
-rw-r--r--compiler/rustc_metadata/src/fs.rs26
-rw-r--r--compiler/rustc_metadata/src/locator.rs67
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs10
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs103
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs14
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs1
-rw-r--r--compiler/rustc_middle/src/dep_graph/mod.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map.rs54
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs7
-rw-r--r--compiler/rustc_middle/src/hir/place.rs10
-rw-r--r--compiler/rustc_middle/src/lint.rs68
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs2
-rw-r--r--compiler/rustc_middle/src/middle/region.rs10
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs1
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs148
-rw-r--r--compiler/rustc_middle/src/query/keys.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs22
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs3
-rw-r--r--compiler/rustc_middle/src/thir.rs4
-rw-r--r--compiler/rustc_middle/src/traits/select.rs8
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs8
-rw-r--r--compiler/rustc_middle/src/ty/consts/valtree.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs54
-rw-r--r--compiler/rustc_middle/src/ty/erase_regions.rs24
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs49
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs36
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/rvalue_scopes.rs2
-rw-r--r--compiler/rustc_middle/src/ty/significant_drop_order.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs8
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs47
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs17
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs9
-rw-r--r--compiler/rustc_middle/src/ty/util.rs113
-rw-r--r--compiler/rustc_middle/src/util/bug.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_place.rs4
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/stmt.rs10
-rw-r--r--compiler/rustc_mir_build/src/builder/mod.rs14
-rw-r--r--compiler/rustc_mir_build/src/builder/scope.rs2
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs19
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs31
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs38
-rw-r--r--compiler/rustc_mir_transform/src/check_const_item_mutation.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs107
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs18
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs202
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs6
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs38
-rw-r--r--compiler/rustc_monomorphize/messages.ftl2
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs1
-rw-r--r--compiler/rustc_monomorphize/src/errors.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/delegate.rs16
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs3
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs13
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs40
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/search_graph.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs55
-rw-r--r--compiler/rustc_parse/messages.ftl4
-rw-r--r--compiler/rustc_parse/src/errors.rs21
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs309
-rw-r--r--compiler/rustc_parse/src/parser/item.rs315
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs97
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs16
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs11
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs15
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs2
-rw-r--r--compiler/rustc_parse/src/parser/token_type.rs4
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs6
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs37
-rw-r--r--compiler/rustc_passes/src/dead.rs22
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs4
-rw-r--r--compiler/rustc_passes/src/entry.rs2
-rw-r--r--compiler/rustc_passes/src/errors.rs5
-rw-r--r--compiler/rustc_passes/src/lang_items.rs14
-rw-r--r--compiler/rustc_passes/src/stability.rs6
-rw-r--r--compiler/rustc_pattern_analysis/src/lints.rs11
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs5
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs11
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs17
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs3
-rw-r--r--compiler/rustc_resolve/Cargo.toml1
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs136
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs4
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs38
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs26
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs4
-rw-r--r--compiler/rustc_resolve/src/imports.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs74
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs52
-rw-r--r--compiler/rustc_resolve/src/lib.rs2
-rw-r--r--compiler/rustc_resolve/src/macros.rs15
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs8
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs1
-rw-r--r--compiler/rustc_session/messages.ftl8
-rw-r--r--compiler/rustc_session/src/config.rs21
-rw-r--r--compiler/rustc_session/src/errors.rs14
-rw-r--r--compiler/rustc_session/src/options.rs13
-rw-r--r--compiler/rustc_session/src/session.rs50
-rw-r--r--compiler/rustc_session/src/utils.rs11
-rw-r--r--compiler/rustc_smir/Cargo.toml2
-rw-r--r--compiler/rustc_smir/src/lib.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs9
-rw-r--r--compiler/rustc_smir/src/rustc_internal/pretty.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/alloc.rs39
-rw-r--r--compiler/rustc_smir/src/rustc_smir/builder.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs16
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/abi.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/error.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mod.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs61
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs1
-rw-r--r--compiler/rustc_smir/src/stable_mir/abi.rs (renamed from compiler/stable_mir/src/abi.rs)13
-rw-r--r--compiler/rustc_smir/src/stable_mir/compiler_interface.rs (renamed from compiler/stable_mir/src/compiler_interface.rs)25
-rw-r--r--compiler/rustc_smir/src/stable_mir/crate_def.rs (renamed from compiler/stable_mir/src/crate_def.rs)19
-rw-r--r--compiler/rustc_smir/src/stable_mir/error.rs (renamed from compiler/stable_mir/src/error.rs)0
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir.rs (renamed from compiler/stable_mir/src/mir.rs)0
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/alloc.rs (renamed from compiler/stable_mir/src/mir/alloc.rs)9
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs (renamed from compiler/stable_mir/src/mir/body.rs)16
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/mono.rs (renamed from compiler/stable_mir/src/mir/mono.rs)43
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/pretty.rs (renamed from compiler/stable_mir/src/mir/pretty.rs)21
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/visit.rs (renamed from compiler/stable_mir/src/mir/visit.rs)10
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs239
-rw-r--r--compiler/rustc_smir/src/stable_mir/target.rs (renamed from compiler/stable_mir/src/target.rs)3
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs (renamed from compiler/stable_mir/src/ty.rs)82
-rw-r--r--compiler/rustc_smir/src/stable_mir/visitor.rs (renamed from compiler/stable_mir/src/visitor.rs)14
-rw-r--r--compiler/rustc_span/src/hygiene.rs281
-rw-r--r--compiler/rustc_span/src/lib.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs23
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs5
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs1
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs2
-rw-r--r--compiler/rustc_target/src/asm/arm.rs2
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs2
-rw-r--r--compiler/rustc_target/src/callconv/x86.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs1
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs111
-rw-r--r--compiler/rustc_target/src/spec/base/apple/tests.rs9
-rw-r--r--compiler/rustc_target/src/spec/base/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/json.rs4
-rw-r--r--compiler/rustc_target/src/spec/mod.rs19
-rw-r--r--compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/target_features.rs71
-rw-r--r--compiler/rustc_trait_selection/messages.ftl7
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs3
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs39
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs30
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs10
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs13
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs182
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs35
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs56
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs64
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs37
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs1
-rw-r--r--compiler/rustc_type_ir/src/fold.rs53
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs12
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs57
-rw-r--r--compiler/rustc_type_ir/src/interner.rs4
-rw-r--r--compiler/rustc_type_ir/src/relate/combine.rs1
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs62
-rw-r--r--compiler/stable_mir/Cargo.toml3
-rw-r--r--compiler/stable_mir/src/lib.rs231
-rw-r--r--library/Cargo.lock39
-rw-r--r--library/Cargo.toml3
-rw-r--r--library/alloc/Cargo.toml1
-rw-r--r--library/alloc/src/sync.rs412
-rw-r--r--library/alloc/src/vec/mod.rs8
-rw-r--r--library/alloctests/tests/arc.rs28
-rw-r--r--library/alloctests/tests/lib.rs1
-rw-r--r--library/alloctests/tests/num.rs69
-rw-r--r--library/core/src/bstr/mod.rs (renamed from library/core/src/bstr.rs)287
-rw-r--r--library/core/src/bstr/traits.rs277
-rw-r--r--library/core/src/cell.rs25
-rw-r--r--library/core/src/fmt/mod.rs5
-rw-r--r--library/core/src/fmt/rt.rs8
-rw-r--r--library/core/src/intrinsics/mod.rs10
-rw-r--r--library/core/src/iter/traits/accum.rs4
-rw-r--r--library/core/src/num/f128.rs50
-rw-r--r--library/core/src/num/f16.rs50
-rw-r--r--library/core/src/num/f32.rs50
-rw-r--r--library/core/src/num/f64.rs50
-rw-r--r--library/core/src/primitive_docs.rs53
-rw-r--r--library/core/src/ptr/const_ptr.rs3
-rw-r--r--library/core/src/ptr/mut_ptr.rs3
-rw-r--r--library/core/src/ptr/non_null.rs3
-rw-r--r--library/core/src/slice/iter.rs95
-rw-r--r--library/core/src/slice/mod.rs140
-rw-r--r--library/core/src/unicode/unicode_data.rs317
-rw-r--r--library/coretests/Cargo.toml1
-rw-r--r--library/coretests/tests/cell.rs4
-rw-r--r--library/coretests/tests/lib.rs10
-rw-r--r--library/coretests/tests/num/int_macros.rs697
-rw-r--r--library/coretests/tests/num/uint_macros.rs503
-rw-r--r--library/coretests/tests/pin.rs14
-rw-r--r--library/coretests/tests/pin_macro.rs28
-rw-r--r--library/coretests/tests/str.rs2
-rw-r--r--library/std/src/fs.rs16
-rw-r--r--library/std/src/io/buffered/bufreader/buffer.rs1
-rw-r--r--library/std/src/io/copy.rs5
-rw-r--r--library/std/src/io/mod.rs8
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/net/socket_addr.rs2
-rw-r--r--library/std/src/process.rs2
-rw-r--r--library/std/src/sync/mod.rs2
-rw-r--r--library/std/src/sys/fd/hermit.rs (renamed from library/std/src/sys/pal/hermit/fd.rs)2
-rw-r--r--library/std/src/sys/fd/mod.rs19
-rw-r--r--library/std/src/sys/fd/sgx.rs (renamed from library/std/src/sys/pal/sgx/fd.rs)2
-rw-r--r--library/std/src/sys/fd/unix.rs (renamed from library/std/src/sys/pal/unix/fd.rs)58
-rw-r--r--library/std/src/sys/fd/unix/tests.rs (renamed from library/std/src/sys/pal/unix/fd/tests.rs)3
-rw-r--r--library/std/src/sys/fd/wasi.rs (renamed from library/std/src/sys/pal/wasi/fd.rs)5
-rw-r--r--library/std/src/sys/fs/hermit.rs2
-rw-r--r--library/std/src/sys/fs/mod.rs101
-rw-r--r--library/std/src/sys/fs/unix.rs195
-rw-r--r--library/std/src/sys/fs/windows.rs2
-rw-r--r--library/std/src/sys/io/io_slice/iovec.rs2
-rw-r--r--library/std/src/sys/io/mod.rs2
-rw-r--r--library/std/src/sys/mod.rs1
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs1
-rw-r--r--library/std/src/sys/pal/sgx/mod.rs1
-rw-r--r--library/std/src/sys/pal/unix/kernel_copy.rs16
-rw-r--r--library/std/src/sys/pal/unix/linux/pidfd.rs2
-rw-r--r--library/std/src/sys/pal/unix/mod.rs1
-rw-r--r--library/std/src/sys/pal/unix/os.rs8
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs30
-rw-r--r--library/std/src/sys/pal/unix/thread.rs13
-rw-r--r--library/std/src/sys/pal/unix/time.rs7
-rw-r--r--library/std/src/sys/pal/unix/weak.rs51
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs2
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs5
-rw-r--r--library/std/src/sys/pal/wasm/atomics/thread.rs2
-rw-r--r--library/std/src/sys/pal/windows/pipe.rs1
-rw-r--r--library/std/src/sys/process/unix/unix.rs42
-rw-r--r--library/std/src/sys/random/linux.rs8
-rw-r--r--library/std/src/sys/stdio/trusty.rs83
-rw-r--r--library/std/src/sys/stdio/wasi.rs2
-rw-r--r--library/std/src/sys/thread_local/mod.rs7
-rw-r--r--library/std/src/sys/thread_local/no_threads.rs (renamed from library/std/src/sys/thread_local/statik.rs)0
-rw-r--r--library/std/tests/floats/f128.rs19
-rw-r--r--library/std/tests/floats/f16.rs21
-rw-r--r--library/std/tests/floats/f32.rs21
-rw-r--r--library/std/tests/floats/f64.rs19
-rw-r--r--library/std/tests/floats/lib.rs4
-rw-r--r--library/std/tests/thread_local/lib.rs2
-rw-r--r--library/std/tests/thread_local/tests.rs21
-rw-r--r--rustfmt.toml1
-rw-r--r--src/bootstrap/Cargo.lock8
-rw-r--r--src/bootstrap/Cargo.toml6
-rw-r--r--src/bootstrap/bootstrap.py27
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/mk/Makefile.in8
-rw-r--r--src/bootstrap/src/bin/main.rs80
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs47
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs19
-rw-r--r--src/bootstrap/src/core/config/config.rs37
-rw-r--r--src/bootstrap/src/core/config/tests.rs5
-rw-r--r--src/bootstrap/src/lib.rs2
-rw-r--r--src/bootstrap/src/utils/cc_detect/tests.rs2
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs27
-rw-r--r--src/bootstrap/src/utils/helpers.rs4
-rw-r--r--src/ci/docker/README.md8
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile69
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile1
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh1
-rw-r--r--src/ci/github-actions/jobs.yml57
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/ci.yml1
-rw-r--r--src/doc/rustc-dev-guide/book.toml4
-rw-r--r--src/doc/rustc-dev-guide/ci/date-check/src/main.rs155
-rw-r--r--src/doc/rustc-dev-guide/examples/rustc-driver-example.rs16
-rw-r--r--src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs10
-rw-r--r--src/doc/rustc-dev-guide/examples/rustc-interface-example.rs13
-rw-r--r--src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs8
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/rustfmt.toml7
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md18
-rw-r--r--src/doc/rustc-dev-guide/src/appendix/code-index.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/prerequisites.md2
-rw-r--r--src/doc/rustc-dev-guide/src/const-eval.md2
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics.md3
-rw-r--r--src/doc/rustc-dev-guide/src/name-resolution.md6
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/fuchsia.md12
-rw-r--r--src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md43
-rw-r--r--src/doc/rustc-dev-guide/src/param_env/param_env_construction_internals.md83
-rw-r--r--src/doc/rustc-dev-guide/src/param_env/param_env_summary.md18
-rw-r--r--src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md59
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md3
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md54
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md112
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc.md14
-rw-r--r--src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_clif.md3
-rw-r--r--src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md3
-rw-r--r--src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/intro.md13
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ecosystem-test-jobs/fuchsia.md (renamed from src/doc/rustc-dev-guide/src/tests/fuchsia.md)11
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ecosystem-test-jobs/rust-for-linux.md (renamed from src/doc/rustc-dev-guide/src/tests/rust-for-linux.md)42
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ecosystem.md4
-rw-r--r--src/doc/rustc-dev-guide/src/tests/intro.md8
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md26
-rw-r--r--src/doc/rustc-dev-guide/src/traits/caching.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/ty_module/binders.md2
-rw-r--r--src/doc/rustc-dev-guide/src/typing_parameter_envs.md206
-rw-r--r--src/doc/rustc/src/SUMMARY.md6
-rw-r--r--src/doc/rustc/src/platform-support.md10
-rw-r--r--src/doc/rustc/src/platform-support/netbsd.md2
-rw-r--r--src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md3
-rw-r--r--src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md3
-rw-r--r--src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md3
-rw-r--r--src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md3
-rw-r--r--src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md3
-rw-r--r--src/doc/rustc/src/platform-support/windows-gnu.md32
-rw-r--r--src/doc/rustc/src/platform-support/windows-gnullvm.md (renamed from src/doc/rustc/src/platform-support/pc-windows-gnullvm.md)8
-rw-r--r--src/doc/unstable-book/src/compiler-flags/embed-metadata.md3
-rw-r--r--src/doc/unstable-book/src/compiler-flags/print-crate-root-lint-levels.md23
-rw-r--r--src/doc/unstable-book/src/language-features/import-trait-associated-functions.md22
-rw-r--r--src/doc/unstable-book/src/language-features/inline-const-pat.md22
-rw-r--r--src/doc/unstable-book/src/language-features/type-alias-impl-trait.md159
-rw-r--r--src/doc/unstable-book/src/library-features/c-variadic.md26
-rw-r--r--src/etc/test-float-parse/Cargo.toml2
-rw-r--r--src/etc/test-float-parse/src/gen_/exhaustive.rs (renamed from src/etc/test-float-parse/src/gen/exhaustive.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/exponents.rs (renamed from src/etc/test-float-parse/src/gen/exponents.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/fuzz.rs (renamed from src/etc/test-float-parse/src/gen/fuzz.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/integers.rs (renamed from src/etc/test-float-parse/src/gen/integers.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/long_fractions.rs (renamed from src/etc/test-float-parse/src/gen/long_fractions.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/many_digits.rs (renamed from src/etc/test-float-parse/src/gen/many_digits.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/sparse.rs (renamed from src/etc/test-float-parse/src/gen/sparse.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/spot_checks.rs (renamed from src/etc/test-float-parse/src/gen/spot_checks.rs)0
-rw-r--r--src/etc/test-float-parse/src/gen_/subnorm.rs (renamed from src/etc/test-float-parse/src/gen/subnorm.rs)0
-rw-r--r--src/etc/test-float-parse/src/lib.rs38
-rw-r--r--src/etc/test-float-parse/src/ui.rs2
-rw-r--r--src/librustdoc/clean/types.rs5
-rw-r--r--src/librustdoc/doctest/make.rs548
-rw-r--r--src/librustdoc/doctest/runner.rs9
-rw-r--r--src/librustdoc/doctest/rust.rs2
-rw-r--r--src/librustdoc/doctest/tests.rs78
-rw-r--r--src/librustdoc/html/markdown.rs3
-rw-r--r--src/librustdoc/html/render/span_map.rs2
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css3
-rw-r--r--src/librustdoc/html/static/js/main.js5
-rw-r--r--src/librustdoc/html/static/js/rustdoc.d.ts30
-rw-r--r--src/librustdoc/html/static/js/search.js165
-rw-r--r--src/librustdoc/html/static/js/settings.js127
-rw-r--r--src/librustdoc/html/static/js/storage.js22
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs7
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs6
-rw-r--r--src/librustdoc/scrape_examples.rs3
m---------src/llvm-project0
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/deprecated_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/duplicate_mod.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_line_after.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_with_brackets.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/format_push_string.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/utils.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/module_style.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/partial_pub_fields.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs73
-rw-r--r--src/tools/clippy/clippy_lints/src/raw_strings.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/shadow.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/single_call_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/single_component_path_imports.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs93
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs13
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs5
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-1782.rs2
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed66
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs66
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr136
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed79
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs79
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr136
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed1
-rw-r--r--src/tools/clippy/tests/ui/rename.rs1
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr30
-rw-r--r--src/tools/compiletest/src/common.rs6
-rw-r--r--src/tools/compiletest/src/errors.rs8
-rw-r--r--src/tools/compiletest/src/executor.rs156
-rw-r--r--src/tools/compiletest/src/header.rs69
-rw-r--r--src/tools/compiletest/src/header/tests.rs20
-rw-r--r--src/tools/compiletest/src/lib.rs105
-rw-r--r--src/tools/compiletest/src/runtest/ui.rs16
-rw-r--r--src/tools/miri/.github/workflows/sysroots.yml1
-rw-r--r--src/tools/miri/Cargo.lock4
-rw-r--r--src/tools/miri/Cargo.toml2
-rw-r--r--src/tools/miri/README.md6
-rw-r--r--src/tools/miri/bench-cargo-miri/mse/src/main.rs2
-rw-r--r--src/tools/miri/cargo-miri/src/phases.rs2
-rwxr-xr-xsrc/tools/miri/ci/ci.sh2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs7
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs2
-rw-r--r--src/tools/miri/src/concurrency/thread.rs2
-rw-r--r--src/tools/miri/src/diagnostics.rs4
-rw-r--r--src/tools/miri/src/eval.rs1
-rw-r--r--src/tools/miri/src/helpers.rs94
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs8
-rw-r--r--src/tools/miri/src/machine.rs8
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs55
-rw-r--r--src/tools/miri/src/shims/panic.rs3
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs11
-rw-r--r--src/tools/miri/tests/fail/shims/input_arg_mismatch.rs21
-rw-r--r--src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr17
-rw-r--r--src/tools/miri/tests/fail/shims/return_type_mismatch.rs21
-rw-r--r--src/tools/miri/tests/fail/shims/return_type_mismatch.stderr17
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs6
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-pipe.rs8
-rw-r--r--src/tools/miri/tests/pass/float.rs1
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs14
-rw-r--r--src/tools/run-make-support/src/lib.rs3
-rw-r--r--src/tools/run-make-support/src/linker.rs36
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs4
-rw-r--r--src/tools/rustbook/Cargo.lock404
-rw-r--r--src/tools/rustbook/Cargo.toml2
-rw-r--r--src/tools/rustdoc-js/tester.js2
-rw-r--r--src/tools/rustfmt/src/expr.rs4
-rw-r--r--src/tools/rustfmt/src/items.rs102
-rw-r--r--src/tools/rustfmt/src/macros.rs34
-rw-r--r--src/tools/rustfmt/src/modules.rs10
-rw-r--r--src/tools/rustfmt/src/patterns.rs4
-rw-r--r--src/tools/rustfmt/src/reorder.rs17
-rw-r--r--src/tools/rustfmt/src/types.rs2
-rw-r--r--src/tools/rustfmt/src/visitor.rs81
-rw-r--r--src/tools/rustfmt/tests/source/pattern.rs2
-rw-r--r--src/tools/rustfmt/tests/target/pattern.rs2
-rw-r--r--src/tools/tidy/src/deps.rs9
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/unit_tests.rs51
-rw-r--r--src/tools/tidy/src/unstable_book.rs29
-rw-r--r--src/tools/unicode-table-generator/src/range_search.rs71
-rw-r--r--src/tools/unicode-table-generator/src/skiplist.rs66
-rw-r--r--src/version2
-rw-r--r--tests/assembly/aarch64-pointer-auth.rs1
-rw-r--r--tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs61
-rw-r--r--tests/assembly/static-relocation-model.rs2
-rw-r--r--tests/codegen/autodiff.rs4
-rw-r--r--tests/codegen/autodiffv.rs116
-rw-r--r--tests/codegen/branch-protection-old-llvm.rs46
-rw-r--r--tests/codegen/branch-protection.rs1
-rw-r--r--tests/codegen/call-metadata.rs18
-rw-r--r--tests/codegen/cast-target-abi.rs3
-rw-r--r--tests/codegen/cffi/ffi-const.rs3
-rw-r--r--tests/codegen/cffi/ffi-out-of-bounds-loads.rs3
-rw-r--r--tests/codegen/cffi/ffi-pure.rs3
-rw-r--r--tests/codegen/char-escape-debug-no-bounds-check.rs14
-rw-r--r--tests/codegen/clone_as_copy.rs2
-rw-r--r--tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs1
-rw-r--r--tests/codegen/dont-shuffle-bswaps.rs1
-rw-r--r--tests/codegen/enum/enum-two-variants-match.rs1
-rw-r--r--tests/codegen/float/algebraic.rs149
-rw-r--r--tests/codegen/float_math.rs71
-rw-r--r--tests/codegen/intrinsics/carrying_mul_add.rs1
-rw-r--r--tests/codegen/intrinsics/transmute.rs11
-rw-r--r--tests/codegen/issues/issue-107681-unwrap_unchecked.rs1
-rw-r--r--tests/codegen/issues/issue-118306.rs1
-rw-r--r--tests/codegen/issues/issue-122600-ptr-discriminant-update.rs3
-rw-r--r--tests/codegen/issues/issue-126585.rs1
-rw-r--r--tests/codegen/range-attribute.rs1
-rw-r--r--tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs19
-rw-r--r--tests/codegen/slice-last-elements-optimization.rs37
-rw-r--r--tests/codegen/slice-split-at.rs24
-rw-r--r--tests/codegen/tied-features-strength.rs12
-rw-r--r--tests/codegen/try_question_mark_nop.rs40
-rw-r--r--tests/codegen/unchecked_shifts.rs15
-rw-r--r--tests/codegen/vec_pop_push_noop.rs3
-rw-r--r--tests/coverage-run-rustdoc/doctest.coverage16
-rw-r--r--tests/coverage/abort.cov-map4
-rw-r--r--tests/coverage/assert-ne.cov-map4
-rw-r--r--tests/coverage/assert-ne.coverage2
-rw-r--r--tests/coverage/assert-ne.rs2
-rw-r--r--tests/coverage/assert_not.cov-map10
-rw-r--r--tests/coverage/async_block.cov-map8
-rw-r--r--tests/coverage/async_block.coverage2
-rw-r--r--tests/coverage/async_closure.cov-map22
-rw-r--r--tests/coverage/async_closure.coverage6
-rw-r--r--tests/coverage/attr/off-on-sandwich.cov-map12
-rw-r--r--tests/coverage/bad_counter_ids.cov-map16
-rw-r--r--tests/coverage/branch/guard.cov-map4
-rw-r--r--tests/coverage/branch/if-let.cov-map4
-rw-r--r--tests/coverage/branch/if.cov-map18
-rw-r--r--tests/coverage/branch/lazy-boolean.cov-map20
-rw-r--r--tests/coverage/branch/let-else.cov-map6
-rw-r--r--tests/coverage/branch/match-arms.cov-map34
-rw-r--r--tests/coverage/branch/match-trivial.cov-map8
-rw-r--r--tests/coverage/branch/while.cov-map16
-rw-r--r--tests/coverage/closure.cov-map12
-rw-r--r--tests/coverage/closure.coverage22
-rw-r--r--tests/coverage/closure_macro.cov-map6
-rw-r--r--tests/coverage/closure_macro_async.cov-map6
-rw-r--r--tests/coverage/condition/conditions.cov-map10
-rw-r--r--tests/coverage/coroutine.cov-map8
-rw-r--r--tests/coverage/holes.cov-map22
-rw-r--r--tests/coverage/holes.coverage20
-rw-r--r--tests/coverage/inline-dead.cov-map4
-rw-r--r--tests/coverage/inline.cov-map4
-rw-r--r--tests/coverage/issue-83601.cov-map6
-rw-r--r--tests/coverage/issue-84561.cov-map173
-rw-r--r--tests/coverage/issue-84561.coverage42
-rw-r--r--tests/coverage/loop-break.cov-map4
-rw-r--r--tests/coverage/loops_branches.cov-map12
-rw-r--r--tests/coverage/macro_name_span.cov-map4
-rw-r--r--tests/coverage/mcdc/condition-limit.cov-map4
-rw-r--r--tests/coverage/mcdc/condition-limit.coverage1
-rw-r--r--tests/coverage/mcdc/condition-limit.rs1
-rw-r--r--tests/coverage/mcdc/if.cov-map28
-rw-r--r--tests/coverage/mcdc/if.coverage1
-rw-r--r--tests/coverage/mcdc/if.rs1
-rw-r--r--tests/coverage/mcdc/inlined_expressions.cov-map4
-rw-r--r--tests/coverage/mcdc/inlined_expressions.coverage1
-rw-r--r--tests/coverage/mcdc/inlined_expressions.rs1
-rw-r--r--tests/coverage/mcdc/nested_if.cov-map16
-rw-r--r--tests/coverage/mcdc/nested_if.coverage1
-rw-r--r--tests/coverage/mcdc/nested_if.rs1
-rw-r--r--tests/coverage/mcdc/non_control_flow.cov-map34
-rw-r--r--tests/coverage/mcdc/non_control_flow.coverage1
-rw-r--r--tests/coverage/mcdc/non_control_flow.rs1
-rw-r--r--tests/coverage/no_cov_crate.cov-map8
-rw-r--r--tests/coverage/panic_unwind.cov-map4
-rw-r--r--tests/coverage/sort_groups.cov-map4
-rw-r--r--tests/coverage/try_error_result.cov-map50
-rw-r--r--tests/coverage/try_error_result.coverage2
-rw-r--r--tests/coverage/unicode.cov-map6
-rw-r--r--tests/coverage/unicode.coverage2
-rw-r--r--tests/coverage/unreachable.cov-map12
-rw-r--r--tests/coverage/yield.cov-map10
-rw-r--r--tests/crashes/112201.rs19
-rw-r--r--tests/crashes/134334.rs9
-rw-r--r--tests/crashes/134335.rs12
-rw-r--r--tests/crashes/137751.rs6
-rw-r--r--tests/crashes/137874.rs4
-rw-r--r--tests/incremental/delayed_span_bug.rs4
-rw-r--r--tests/incremental/user-written-closure-synthetic-closure-conflict.rs15
-rw-r--r--tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir (renamed from tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir)4
-rw-r--r--tests/mir-opt/async_closure_fake_read_for_by_move.rs2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir)4
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir)4
-rw-r--r--tests/mir-opt/async_closure_shims.rs4
-rw-r--r--tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff3
-rw-r--r--tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff3
-rw-r--r--tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff14
-rw-r--r--tests/mir-opt/const_prop/read_immutable_static.rs3
-rw-r--r--tests/mir-opt/const_prop/ref_deref.main.GVN.diff3
-rw-r--r--tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff3
-rw-r--r--tests/mir-opt/const_prop/ref_deref_project.rs3
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.rs5
-rw-r--r--tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff3
-rw-r--r--tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff3
-rw-r--r--tests/mir-opt/coroutine_drop_cleanup.rs2
-rw-r--r--tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff8
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff2
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff10
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff10
-rw-r--r--tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff3
-rw-r--r--tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff3
-rw-r--r--tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff18
-rw-r--r--tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff18
-rw-r--r--tests/mir-opt/gvn.rs31
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-abort.diff38
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-unwind.diff38
-rw-r--r--tests/mir-opt/gvn_clone.rs2
-rw-r--r--tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff6
-rw-r--r--tests/mir-opt/gvn_copy_aggregate.rs2
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff15
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff15
-rw-r--r--tests/mir-opt/pre-codegen/clone_as_copy.rs2
-rw-r--r--tests/mir-opt/pre-codegen/deref_nested_borrows.rs1
-rw-r--r--tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir6
-rw-r--r--tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir238
-rw-r--r--tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir54
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir80
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir24
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir56
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir56
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir26
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir26
-rw-r--r--tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir8
-rw-r--r--tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff62
-rw-r--r--tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs43
-rw-r--r--tests/mir-opt/simplify_aggregate_to_copy_miscompile.set_discriminant.GVN.diff20
-rw-r--r--tests/pretty/autodiff_forward.pp100
-rw-r--r--tests/pretty/autodiff_forward.rs18
-rw-r--r--tests/pretty/autodiff_reverse.pp22
-rw-r--r--tests/pretty/hir-lifetimes.pp6
-rw-r--r--tests/pretty/hir-struct-expr.pp28
-rw-r--r--tests/pretty/hir-struct-expr.rs24
-rw-r--r--tests/pretty/stmt_expr_attributes.rs5
-rw-r--r--tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs4
-rw-r--r--tests/run-make/apple-slow-tls/rmake.rs37
-rw-r--r--tests/run-make/apple-slow-tls/tls_test/Cargo.toml6
-rw-r--r--tests/run-make/apple-slow-tls/tls_test/src/main.rs10
-rw-r--r--tests/run-make/embed-metadata/dep1.rs1
-rw-r--r--tests/run-make/embed-metadata/foo.rs5
-rw-r--r--tests/run-make/embed-metadata/rmake.rs86
-rw-r--r--tests/run-make/issue-107495-archive-permissions/rmake.rs4
-rw-r--r--tests/run-make/print-crate-root-lint-levels/lib.rs5
-rw-r--r--tests/run-make/print-crate-root-lint-levels/rmake.rs118
-rw-r--r--tests/run-make/rust-lld-by-default-beta-stable/rmake.rs17
-rw-r--r--tests/run-make/rust-lld-by-default-nightly/rmake.rs27
-rw-r--r--tests/run-make/rust-lld-custom-target/rmake.rs39
-rw-r--r--tests/run-make/rust-lld/rmake.rs68
-rw-r--r--tests/run-make/rustc-help/help-v.stdout2
-rw-r--r--tests/run-make/rustc-help/help.stdout2
-rw-r--r--tests/run-make/rustdoc-error-lines/rmake.rs6
-rw-r--r--tests/run-make/target-specs/rmake.rs2
-rw-r--r--tests/rustdoc-json/attrs/automatically_derived.rs13
-rw-r--r--tests/rustdoc-ui/doctest/display-output.stdout6
-rw-r--r--tests/rustdoc-ui/doctest/edition-2024-error-output.rs14
-rw-r--r--tests/rustdoc-ui/doctest/edition-2024-error-output.stdout20
-rw-r--r--tests/rustdoc-ui/doctest/extern-crate.rs23
-rw-r--r--tests/rustdoc-ui/doctest/extern-crate.stdout6
-rw-r--r--tests/rustdoc-ui/doctest/no-run-flag-error.rs3
-rw-r--r--tests/rustdoc-ui/extract-doctests.stdout2
-rw-r--r--tests/rustdoc-ui/invalid-theme-name.rs3
-rw-r--r--tests/rustdoc-ui/issues/issue-91713.rs3
-rw-r--r--tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs3
-rw-r--r--tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr2
-rw-r--r--tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout4
-rw-r--r--tests/rustdoc-ui/track-diagnostics.rs2
-rw-r--r--tests/rustdoc/playground.rs2
-rw-r--r--tests/ui-fulldeps/missing-rustc-driver-error.rs2
-rw-r--r--tests/ui-fulldeps/stable-mir/check_assoc_items.rs145
-rw-r--r--tests/ui/abi/fixed_x18.rs2
-rw-r--r--tests/ui/abi/large-byval-align.rs1
-rw-r--r--tests/ui/abi/shadow-call-stack-without-fixed-x18.rs3
-rw-r--r--tests/ui/allocator/two-allocators2.rs3
-rw-r--r--tests/ui/allocator/two-allocators3.rs4
-rw-r--r--tests/ui/amdgpu-require-explicit-cpu.rs3
-rw-r--r--tests/ui/asm/aarch64/srcloc.old.stderr290
-rw-r--r--tests/ui/asm/aarch64/srcloc.rs3
-rw-r--r--tests/ui/asm/aarch64/srcloc.stderr (renamed from tests/ui/asm/aarch64/srcloc.new.stderr)48
-rw-r--r--tests/ui/asm/inline-syntax.arm.stderr12
-rw-r--r--tests/ui/asm/inline-syntax.arm_llvm_18.stderr90
-rw-r--r--tests/ui/asm/inline-syntax.rs15
-rw-r--r--tests/ui/asm/inline-syntax.x86_64.stderr14
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr32
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr194
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr32
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr194
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr32
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr194
-rw-r--r--tests/ui/asm/riscv/riscv32e-registers.rs14
-rw-r--r--tests/ui/asm/x86_64/srcloc.old.stderr302
-rw-r--r--tests/ui/asm/x86_64/srcloc.rs3
-rw-r--r--tests/ui/asm/x86_64/srcloc.stderr (renamed from tests/ui/asm/x86_64/srcloc.new.stderr)50
-rw-r--r--tests/ui/associated-consts/issue-93835.rs3
-rw-r--r--tests/ui/associated-consts/issue-93835.stderr32
-rw-r--r--tests/ui/associated-types/bound-lifetime-constrained.ok.stderr8
-rw-r--r--tests/ui/associated-types/bound-lifetime-constrained.rs5
-rw-r--r--tests/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr8
-rw-r--r--tests/ui/associated-types/bound-lifetime-in-binding-only.rs5
-rw-r--r--tests/ui/associated-types/bound-lifetime-in-return-only.ok.stderr8
-rw-r--r--tests/ui/associated-types/bound-lifetime-in-return-only.rs5
-rw-r--r--tests/ui/associated-types/issue-36499.rs2
-rw-r--r--tests/ui/associated-types/issue-59324.stderr26
-rw-r--r--tests/ui/async-await/async-closures/by-move-body-inlined-attrs.rs28
-rw-r--r--tests/ui/attributes/attr-bad-crate-attr.rs3
-rw-r--r--tests/ui/attributes/attr-bad-crate-attr.stderr2
-rw-r--r--tests/ui/attributes/dont-dup-expr-attrs.rs133
-rw-r--r--tests/ui/attributes/inner-attr-metavar.rs14
-rw-r--r--tests/ui/attributes/nonterminal-expansion.rs4
-rw-r--r--tests/ui/attributes/nonterminal-expansion.stderr11
-rw-r--r--tests/ui/attributes/z-crate-attr/garbage.rs5
-rw-r--r--tests/ui/attributes/z-crate-attr/injection.rs4
-rw-r--r--tests/ui/attributes/z-crate-attr/inner-attr.rs3
-rw-r--r--tests/ui/attributes/z-crate-attr/multiple.rs4
-rw-r--r--tests/ui/attributes/z-crate-attr/unbalanced-paren.rs4
-rw-r--r--tests/ui/autodiff/autodiff_illegal.rs7
-rw-r--r--tests/ui/autodiff/autodiff_illegal.stderr38
-rw-r--r--tests/ui/binop/binop-bitxor-str.rs3
-rw-r--r--tests/ui/binop/binop-bitxor-str.stderr2
-rw-r--r--tests/ui/binop/binop-mul-bool.rs4
-rw-r--r--tests/ui/binop/binop-mul-bool.stderr2
-rw-r--r--tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs3
-rw-r--r--tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr6
-rw-r--r--tests/ui/borrowck/mut-borrow-in-loop-2.stderr4
-rw-r--r--tests/ui/borrowck/mut-borrow-outside-loop.rs4
-rw-r--r--tests/ui/c-variadic/issue-86053-1.rs14
-rw-r--r--tests/ui/c-variadic/issue-86053-1.stderr8
-rw-r--r--tests/ui/capture1.rs4
-rw-r--r--tests/ui/capture1.stderr2
-rw-r--r--tests/ui/cast/cast-from-nil.rs3
-rw-r--r--tests/ui/cast/cast-from-nil.stderr2
-rw-r--r--tests/ui/cast/cast-to-nil.rs3
-rw-r--r--tests/ui/cast/cast-to-nil.stderr2
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs36
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr48
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs36
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr43
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs41
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr140
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap.rs32
-rw-r--r--tests/ui/cfg/cfg_false_no_std-2.rs7
-rw-r--r--tests/ui/cfg/raw-true-false.rs24
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.feature.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.full.stderr2
-rw-r--r--tests/ui/check-cfg/invalid-arguments.boolean.stderr6
-rw-r--r--tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr5
-rw-r--r--tests/ui/check-cfg/invalid-arguments.rs4
-rw-r--r--tests/ui/check-cfg/target_feature.stderr49
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs23
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs25
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs25
-rw-r--r--tests/ui/codegen/mismatched-data-layouts.rs3
-rw-r--r--tests/ui/codegen/mono-impossible-drop.rs3
-rw-r--r--tests/ui/codemap_tests/issue-11715.rs3
-rw-r--r--tests/ui/codemap_tests/issue-11715.stderr2
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-3.rs4
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-5.rs4
-rw-r--r--tests/ui/conditional-compilation/cfg-attr-cfg-2.rs3
-rw-r--r--tests/ui/conditional-compilation/cfg-attr-cfg-2.stderr2
-rw-r--r--tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr2
-rw-r--r--tests/ui/conditional-compilation/cfg-in-crate-1.rs4
-rw-r--r--tests/ui/conditional-compilation/cfg-in-crate-1.stderr2
-rw-r--r--tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.rs41
-rw-r--r--tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.stderr23
-rw-r--r--tests/ui/const-ptr/out_of_bounds_read.rs5
-rw-r--r--tests/ui/const-ptr/out_of_bounds_read.stderr4
-rw-r--r--tests/ui/consts/async-block.rs5
-rw-r--r--tests/ui/consts/async-block.with_feature.stderr8
-rw-r--r--tests/ui/consts/const-block-const-bound.stderr2
-rw-r--r--tests/ui/consts/const-size_of-cycle.rs3
-rw-r--r--tests/ui/consts/const-size_of-cycle.stderr6
-rw-r--r--tests/ui/consts/const_in_pattern/arrays-and-slices.rs53
-rw-r--r--tests/ui/consts/const_in_pattern/arrays-and-slices.stderr84
-rw-r--r--tests/ui/consts/invalid-inline-const-in-match-arm.rs9
-rw-r--r--tests/ui/consts/invalid-inline-const-in-match-arm.stderr18
-rw-r--r--tests/ui/consts/miri_unleashed/drop.rs4
-rw-r--r--tests/ui/consts/static-default-lifetime/static-trait-impl.rs13
-rw-r--r--tests/ui/consts/timeout.rs3
-rw-r--r--tests/ui/consts/timeout.stderr2
-rw-r--r--tests/ui/coroutine/clone-rpit.next.stderr6
-rw-r--r--tests/ui/coverage-attr/name-value.stderr34
-rw-r--r--tests/ui/coverage-attr/word-only.stderr30
-rw-r--r--tests/ui/crate_type_flag.rs3
-rw-r--r--tests/ui/custom_test_frameworks/full.rs15
-rw-r--r--tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs2
-rw-r--r--tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs8
-rw-r--r--tests/ui/debuginfo/dwarf-versions.rs6
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs3
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs3
-rw-r--r--tests/ui/deprecation/deprecation-lint-2.rs3
-rw-r--r--tests/ui/deprecation/deprecation-lint-2.stderr4
-rw-r--r--tests/ui/deprecation/deprecation-lint-3.rs2
-rw-r--r--tests/ui/deprecation/deprecation-lint-3.stderr4
-rw-r--r--tests/ui/diagnostic-flags/allow-non-lint-warnings.rs10
-rw-r--r--tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr10
-rw-r--r--tests/ui/drop/nonsense-drop-impl-issue-139278.rs10
-rw-r--r--tests/ui/drop/nonsense-drop-impl-issue-139278.stderr18
-rw-r--r--tests/ui/duplicate/dupe-symbols-4.rs4
-rw-r--r--tests/ui/duplicate/dupe-symbols-4.stderr2
-rw-r--r--tests/ui/duplicate/dupe-symbols-7.rs5
-rw-r--r--tests/ui/duplicate/dupe-symbols-7.stderr2
-rw-r--r--tests/ui/duplicate/dupe-symbols-8.rs3
-rw-r--r--tests/ui/duplicate/dupe-symbols-8.stderr2
-rw-r--r--tests/ui/elided-test.rs4
-rw-r--r--tests/ui/elided-test.stderr2
-rw-r--r--tests/ui/error-codes/E0602.rs5
-rw-r--r--tests/ui/errors/remap-path-prefix-reverse.local-self.stderr2
-rw-r--r--tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr2
-rw-r--r--tests/ui/errors/remap-path-prefix-reverse.rs3
-rw-r--r--tests/ui/errors/remap-path-prefix-sysroot.rs4
-rw-r--r--tests/ui/errors/remap-path-prefix.normal.stderr2
-rw-r--r--tests/ui/errors/remap-path-prefix.rs9
-rw-r--r--tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr2
-rw-r--r--tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr2
-rw-r--r--tests/ui/errors/wrong-target-spec.rs2
-rw-r--r--tests/ui/errors/wrong-target-spec.stderr4
-rw-r--r--tests/ui/expr/if/if-typeck.rs3
-rw-r--r--tests/ui/expr/if/if-typeck.stderr2
-rw-r--r--tests/ui/ext-nonexistent.rs2
-rw-r--r--tests/ui/ext-nonexistent.stderr2
-rw-r--r--tests/ui/extern-flag/empty-extern-arg.rs5
-rw-r--r--tests/ui/extern-flag/invalid-crate-name-dashed.rs3
-rw-r--r--tests/ui/extern-flag/invalid-crate-name-non-ascii.rs3
-rw-r--r--tests/ui/extern-flag/invalid-crate-name.rs3
-rw-r--r--tests/ui/extern-flag/no-force-extern.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-f128.e2015.stderr16
-rw-r--r--tests/ui/feature-gates/feature-gate-f128.e2018.stderr16
-rw-r--r--tests/ui/feature-gates/feature-gate-f128.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-f16.e2015.stderr16
-rw-r--r--tests/ui/feature-gates/feature-gate-f16.e2018.stderr16
-rw-r--r--tests/ui/feature-gates/feature-gate-f16.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs9
-rw-r--r--tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr20
-rw-r--r--tests/ui/feature-gates/feature-gate-inline_const_pat.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-inline_const_pat.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-movrs_target_feature.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-movrs_target_feature.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-rustc-attrs-1.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-super-let.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-super-let.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs26
-rw-r--r--tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr111
-rw-r--r--tests/ui/fn/bad-turbofish-hints-issue-121901.rs8
-rw-r--r--tests/ui/fn/bad-turbofish-hints-issue-121901.stderr25
-rw-r--r--tests/ui/fn/fn-bad-block-type.rs4
-rw-r--r--tests/ui/fn/fn-bad-block-type.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-87258_a.rs2
-rw-r--r--tests/ui/generic-associated-types/issue-87258_a.stderr11
-rw-r--r--tests/ui/generic-associated-types/issue-87258_b.rs2
-rw-r--r--tests/ui/generic-associated-types/issue-87258_b.stderr11
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions0.rs5
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.rs2
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.stderr19
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.rs22
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.stderr43
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions3.rs19
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions3.stderr13
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr17
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs1
-rw-r--r--tests/ui/impl-trait/impl_trait_projections.rs5
-rw-r--r--tests/ui/impl-trait/impl_trait_projections.stderr10
-rw-r--r--tests/ui/impl-trait/inside-item-nested-in-anon-const.rs25
-rw-r--r--tests/ui/impl-trait/issue-55872-1.rs1
-rw-r--r--tests/ui/impl-trait/issue-55872-1.stderr8
-rw-r--r--tests/ui/impl-trait/issue-55872-2.rs2
-rw-r--r--tests/ui/impl-trait/issue-55872-2.stderr12
-rw-r--r--tests/ui/impl-trait/issue-55872-3.rs1
-rw-r--r--tests/ui/impl-trait/issue-55872-3.stderr16
-rw-r--r--tests/ui/impl-trait/issue-55872.rs2
-rw-r--r--tests/ui/impl-trait/issue-55872.stderr6
-rw-r--r--tests/ui/impl-trait/issue-99073-2.rs3
-rw-r--r--tests/ui/impl-trait/issue-99073-2.stderr14
-rw-r--r--tests/ui/impl-trait/issue-99073.rs3
-rw-r--r--tests/ui/impl-trait/issue-99073.stderr18
-rw-r--r--tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs17
-rw-r--r--tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr18
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.rs2
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.stderr29
-rw-r--r--tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr12
-rw-r--r--tests/ui/impl-trait/non-defining-uses/as-projection-term.rs17
-rw-r--r--tests/ui/impl-trait/recursive-ice-101862.stderr18
-rw-r--r--tests/ui/impl-trait/rpit/early_bound.rs3
-rw-r--r--tests/ui/impl-trait/rpit/early_bound.stderr22
-rw-r--r--tests/ui/impl-trait/rpit/non-defining-use.rs3
-rw-r--r--tests/ui/impl-trait/rpit/non-defining-use.stderr22
-rw-r--r--tests/ui/impl-trait/transmute/in-defining-scope.stderr25
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr17
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.rs3
-rw-r--r--tests/ui/imports/glob-resolve1.stderr5
-rw-r--r--tests/ui/imports/import-loop-2.rs4
-rw-r--r--tests/ui/imports/import-loop-2.stderr2
-rw-r--r--tests/ui/imports/import-loop.rs4
-rw-r--r--tests/ui/imports/import-loop.stderr2
-rw-r--r--tests/ui/imports/import3.rs3
-rw-r--r--tests/ui/imports/import3.stderr2
-rw-r--r--tests/ui/imports/import4.rs5
-rw-r--r--tests/ui/imports/import4.stderr2
-rw-r--r--tests/ui/imports/issue-4366-2.stderr5
-rw-r--r--tests/ui/imports/issue-4366.stderr5
-rw-r--r--tests/ui/imports/show-private-items-issue-138626.rs19
-rw-r--r--tests/ui/imports/show-private-items-issue-138626.stderr20
-rw-r--r--tests/ui/indexing/index-help.stderr5
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.stderr5
-rw-r--r--tests/ui/infinite/infinite-autoderef.stderr4
-rw-r--r--tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs17
-rw-r--r--tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr8
-rw-r--r--tests/ui/inline-const/collect-scopes-in-pat.rs16
-rw-r--r--tests/ui/inline-const/const-block-pat-liveness.rs18
-rw-r--r--tests/ui/inline-const/const-match-pat-generic.rs28
-rw-r--r--tests/ui/inline-const/const-match-pat-generic.stderr15
-rw-r--r--tests/ui/inline-const/const-match-pat-inference.rs11
-rw-r--r--tests/ui/inline-const/const-match-pat-lifetime-err.rs47
-rw-r--r--tests/ui/inline-const/const-match-pat-lifetime-err.stderr28
-rw-r--r--tests/ui/inline-const/const-match-pat-lifetime.rs34
-rw-r--r--tests/ui/inline-const/const-match-pat-range.rs38
-rw-r--r--tests/ui/inline-const/const-match-pat.rs20
-rw-r--r--tests/ui/inline-const/in-pat-recovery.rs11
-rw-r--r--tests/ui/inline-const/in-pat-recovery.stderr10
-rw-r--r--tests/ui/inline-const/pat-match-fndef.rs12
-rw-r--r--tests/ui/inline-const/pat-match-fndef.stderr8
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.rs22
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.stderr19
-rw-r--r--tests/ui/inline-const/pat-unsafe.rs29
-rw-r--r--tests/ui/inline-const/pat-unsafe.stderr20
-rw-r--r--tests/ui/instrument-coverage/mcdc-condition-limit.rs1
-rw-r--r--tests/ui/instrument-xray/flags-always-never-1.rs3
-rw-r--r--tests/ui/instrument-xray/flags-dupe-always.rs3
-rw-r--r--tests/ui/instrument-xray/flags-dupe-ignore-loops.rs3
-rw-r--r--tests/ui/instrument-xray/target-not-supported.rs3
-rw-r--r--tests/ui/integral-indexing.stderr40
-rw-r--r--tests/ui/internal/internal-unstable-noallow.rs10
-rw-r--r--tests/ui/internal/internal-unstable-noallow.stderr8
-rw-r--r--tests/ui/invalid-compile-flags/crate-type-flag.rs7
-rw-r--r--tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs3
-rw-r--r--tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs3
-rw-r--r--tests/ui/invalid-compile-flags/print-without-arg.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/print.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs5
-rw-r--r--tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs3
-rw-r--r--tests/ui/invalid-compile-flags/regparm/requires-x86.rs5
-rw-r--r--tests/ui/invalid/issue-114435-layout-type-err.rs3
-rw-r--r--tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs4
-rw-r--r--tests/ui/issues/issue-37131.rs1
-rw-r--r--tests/ui/lang-items/lang-item-missing.rs4
-rw-r--r--tests/ui/lang-items/lang-item-missing.stderr2
-rw-r--r--tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs4
-rw-r--r--tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr2
-rw-r--r--tests/ui/layout/reprc-power-alignment.rs26
-rw-r--r--tests/ui/layout/size-of-val-raw-too-big.rs3
-rw-r--r--tests/ui/layout/unknown-when-no-type-parameter.rs3
-rw-r--r--tests/ui/layout/unknown-when-no-type-parameter.stderr2
-rw-r--r--tests/ui/limits/issue-17913.rs3
-rw-r--r--tests/ui/limits/issue-55878.rs2
-rw-r--r--tests/ui/limits/issue-55878.stderr2
-rw-r--r--tests/ui/link-native-libs/empty-kind-1.rs3
-rw-r--r--tests/ui/link-native-libs/empty-kind-2.rs3
-rw-r--r--tests/ui/link-native-libs/link-arg-error.rs3
-rw-r--r--tests/ui/link-native-libs/manual-link-bad-form.rs3
-rw-r--r--tests/ui/link-native-libs/manual-link-bad-kind.rs3
-rw-r--r--tests/ui/link-native-libs/manual-link-bad-search-path.rs3
-rw-r--r--tests/ui/link-native-libs/manual-link-framework.rs3
-rw-r--r--tests/ui/link-native-libs/manual-link-unsupported-kind.rs3
-rw-r--r--tests/ui/link-native-libs/modifiers-override-3.rs3
-rw-r--r--tests/ui/link-native-libs/suggest-libname-only-1.rs5
-rw-r--r--tests/ui/link-native-libs/suggest-libname-only-1.stderr2
-rw-r--r--tests/ui/link-native-libs/suggest-libname-only-2.rs5
-rw-r--r--tests/ui/link-native-libs/suggest-libname-only-2.stderr2
-rw-r--r--tests/ui/linkage-attr/incompatible-flavor.rs3
-rw-r--r--tests/ui/linkage-attr/issue-10755.rs3
-rw-r--r--tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs2
-rw-r--r--tests/ui/linkage-attr/unstable-flavor.rs5
-rw-r--r--tests/ui/linking/link-self-contained-consistency.many.stderr (renamed from tests/ui/linkage-attr/link-self-contained-consistency.many.stderr)0
-rw-r--r--tests/ui/linking/link-self-contained-consistency.one.stderr (renamed from tests/ui/linkage-attr/link-self-contained-consistency.one.stderr)0
-rw-r--r--tests/ui/linking/link-self-contained-consistency.rs (renamed from tests/ui/linkage-attr/link-self-contained-consistency.rs)0
-rw-r--r--tests/ui/lint/bad-lint-cap.rs3
-rw-r--r--tests/ui/lint/cli-unknown-force-warn.rs5
-rw-r--r--tests/ui/lint/command-line-register-unknown-lint-tool.rs5
-rw-r--r--tests/ui/lint/dead-code/anon-const-in-pat.rs44
-rw-r--r--tests/ui/lint/force-warn/warnings-lint-group.rs5
-rw-r--r--tests/ui/lint/inline-exported.rs30
-rw-r--r--tests/ui/lint/inline-exported.stderr31
-rw-r--r--tests/ui/lint/invalid_null_args.rs136
-rw-r--r--tests/ui/lint/invalid_null_args.stderr330
-rw-r--r--tests/ui/lint/issue-104897.rs5
-rw-r--r--tests/ui/lint/issue-104897.stderr2
-rw-r--r--tests/ui/lint/lint-pre-expansion-extern-module.rs4
-rw-r--r--tests/ui/lint/lint-removed-cmdline-deny.rs7
-rw-r--r--tests/ui/lint/lint-removed-cmdline-deny.stderr4
-rw-r--r--tests/ui/lint/lint-removed-cmdline.rs7
-rw-r--r--tests/ui/lint/lint-removed-cmdline.stderr4
-rw-r--r--tests/ui/lint/lint-renamed-cmdline-deny.rs8
-rw-r--r--tests/ui/lint/lint-renamed-cmdline-deny.stderr4
-rw-r--r--tests/ui/lint/lint-renamed-cmdline.rs8
-rw-r--r--tests/ui/lint/lint-renamed-cmdline.stderr4
-rw-r--r--tests/ui/lint/lint-stability2.rs3
-rw-r--r--tests/ui/lint/lint-stability2.stderr4
-rw-r--r--tests/ui/lint/lint-stability3.rs2
-rw-r--r--tests/ui/lint/lint-stability3.stderr4
-rw-r--r--tests/ui/lint/lint-unknown-lint-cmdline-deny.rs8
-rw-r--r--tests/ui/lint/lint-unknown-lint-cmdline.rs9
-rw-r--r--tests/ui/lint/unused_parens_multibyte_recovery.rs7
-rw-r--r--tests/ui/lint/unused_parens_multibyte_recovery.stderr2
-rw-r--r--tests/ui/lto/issue-11154.rs4
-rw-r--r--tests/ui/lto/lto-duplicate-symbols.rs4
-rw-r--r--tests/ui/macros/failed-to-reparse-issue-137874.rs12
-rw-r--r--tests/ui/macros/failed-to-reparse-issue-137874.stderr10
-rw-r--r--tests/ui/macros/nonterminal-matching.rs4
-rw-r--r--tests/ui/macros/nonterminal-matching.stderr4
-rw-r--r--tests/ui/macros/not-utf8.rs2
-rw-r--r--tests/ui/macros/not-utf8.stderr2
-rw-r--r--tests/ui/macros/unreachable-arg.edition_2021.stderr2
-rw-r--r--tests/ui/macros/unreachable-arg.rs3
-rw-r--r--tests/ui/macros/unreachable-format-args.edition_2015.stderr2
-rw-r--r--tests/ui/macros/unreachable-format-args.rs2
-rw-r--r--tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.rs5
-rw-r--r--tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.stderr2
-rw-r--r--tests/ui/match/issue-112438.rs10
-rw-r--r--tests/ui/match/validate-range-endpoints.rs3
-rw-r--r--tests/ui/match/validate-range-endpoints.stderr28
-rw-r--r--tests/ui/minus-string.rs4
-rw-r--r--tests/ui/minus-string.stderr2
-rw-r--r--tests/ui/mir/enable_passes_validation.rs11
-rw-r--r--tests/ui/mir/issue-75053.rs5
-rw-r--r--tests/ui/mir/issue-75053.stderr8
-rw-r--r--tests/ui/mir/lint/assignment-overlap.rs2
-rw-r--r--tests/ui/mir/lint/call-overlap.rs2
-rw-r--r--tests/ui/mir/lint/no-storage.rs2
-rw-r--r--tests/ui/mir/lint/storage-live.rs2
-rw-r--r--tests/ui/mir/lint/storage-return.rs2
-rw-r--r--tests/ui/mir/validate/noncleanup-cleanup.rs6
-rw-r--r--tests/ui/mir/validate/noncleanup-resume.rs4
-rw-r--r--tests/ui/mir/validate/noncleanup-terminate.rs4
-rw-r--r--tests/ui/missing/missing-main.rs3
-rw-r--r--tests/ui/missing/missing-main.stderr2
-rw-r--r--tests/ui/missing/missing-return.rs2
-rw-r--r--tests/ui/nested-ty-params.rs2
-rw-r--r--tests/ui/nll/ty-outlives/impl-trait-captures.stderr8
-rw-r--r--tests/ui/no-capture-arc.rs4
-rw-r--r--tests/ui/no-capture-arc.stderr2
-rw-r--r--tests/ui/no_std/no-std-no-start-binary.rs2
-rw-r--r--tests/ui/no_std/no-std-unwind-binary.rs3
-rw-r--r--tests/ui/occurs-check-2.rs2
-rw-r--r--tests/ui/occurs-check-2.stderr6
-rw-r--r--tests/ui/occurs-check-3.stderr4
-rw-r--r--tests/ui/occurs-check.stderr4
-rw-r--r--tests/ui/on-unimplemented/slice-index.stderr6
-rw-r--r--tests/ui/packed/packed-struct-generic-transmute.rs1
-rw-r--r--tests/ui/packed/packed-struct-transmute.rs1
-rw-r--r--tests/ui/panic-handler/panic-handler-missing.rs3
-rw-r--r--tests/ui/panic-handler/panic-handler-std.rs3
-rw-r--r--tests/ui/panic-handler/panic-handler-std.stderr2
-rw-r--r--tests/ui/panic-handler/weak-lang-item.rs7
-rw-r--r--tests/ui/panic-handler/weak-lang-item.stderr2
-rw-r--r--tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs3
-rw-r--r--tests/ui/panic-runtime/bad-panic-flag1.rs3
-rw-r--r--tests/ui/panic-runtime/bad-panic-flag2.rs3
-rw-r--r--tests/ui/panic-runtime/need-abort-got-unwind.rs3
-rw-r--r--tests/ui/panic-runtime/need-unwind-got-abort.rs3
-rw-r--r--tests/ui/panic-runtime/runtime-depend-on-needs-runtime.rs3
-rw-r--r--tests/ui/panic-runtime/transitive-link-a-bunch.rs5
-rw-r--r--tests/ui/panic-runtime/two-panic-runtimes.rs9
-rw-r--r--tests/ui/panic-runtime/unwind-tables-target-required.rs3
-rw-r--r--tests/ui/panic-runtime/want-abort-got-unwind.rs9
-rw-r--r--tests/ui/panic-runtime/want-abort-got-unwind2.rs9
-rw-r--r--tests/ui/panic-runtime/want-unwind-got-abort.rs3
-rw-r--r--tests/ui/panic-runtime/want-unwind-got-abort2.rs4
-rw-r--r--tests/ui/panics/default-backtrace-ice.rs2
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-fn.rs4
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-fn.stderr2
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-mod.rs4
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-mod.stderr2
-rw-r--r--tests/ui/parser/circular_modules_main.rs4
-rw-r--r--tests/ui/parser/class-implements-bad-trait.rs3
-rw-r--r--tests/ui/parser/class-implements-bad-trait.stderr2
-rw-r--r--tests/ui/parser/closure-return-syntax.rs16
-rw-r--r--tests/ui/parser/closure-return-syntax.stderr34
-rw-r--r--tests/ui/parser/extern-abi-from-mac-literal-frag.rs4
-rw-r--r--tests/ui/parser/float-field-interpolated.rs8
-rw-r--r--tests/ui/parser/float-field-interpolated.stderr8
-rw-r--r--tests/ui/parser/import-from-path.rs3
-rw-r--r--tests/ui/parser/import-from-path.stderr2
-rw-r--r--tests/ui/parser/import-from-rename.rs4
-rw-r--r--tests/ui/parser/import-from-rename.stderr2
-rw-r--r--tests/ui/parser/import-glob-path.rs3
-rw-r--r--tests/ui/parser/import-glob-path.stderr2
-rw-r--r--tests/ui/parser/import-glob-rename.rs4
-rw-r--r--tests/ui/parser/import-glob-rename.stderr2
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs3
-rw-r--r--tests/ui/parser/issues/issue-103451.rs2
-rw-r--r--tests/ui/parser/issues/issue-10636-2.rs2
-rw-r--r--tests/ui/parser/issues/issue-21146.rs3
-rw-r--r--tests/ui/parser/issues/issue-24375.stderr4
-rw-r--r--tests/ui/parser/issues/issue-58094-missing-right-square-bracket.rs3
-rw-r--r--tests/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr2
-rw-r--r--tests/ui/parser/issues/issue-62524.rs3
-rw-r--r--tests/ui/parser/issues/issue-62524.stderr2
-rw-r--r--tests/ui/parser/issues/issue-62554.rs3
-rw-r--r--tests/ui/parser/issues/issue-62554.stderr2
-rw-r--r--tests/ui/parser/issues/issue-62894.rs2
-rw-r--r--tests/ui/parser/issues/issue-62973.rs4
-rw-r--r--tests/ui/parser/issues/issue-62973.stderr6
-rw-r--r--tests/ui/parser/issues/issue-63116.rs3
-rw-r--r--tests/ui/parser/issues/issue-63116.stderr4
-rw-r--r--tests/ui/parser/issues/issue-63135.rs3
-rw-r--r--tests/ui/parser/issues/issue-63135.stderr2
-rw-r--r--tests/ui/parser/issues/issue-66473.rsbin129 -> 287 bytes
-rw-r--r--tests/ui/parser/issues/issue-66473.stderr13
-rw-r--r--tests/ui/parser/issues/issue-68629.rsbin131 -> 258 bytes
-rw-r--r--tests/ui/parser/issues/issue-68629.stderr10
-rw-r--r--tests/ui/parser/issues/issue-68730.rsbin177 -> 305 bytes
-rw-r--r--tests/ui/parser/issues/issue-68730.stderr10
-rw-r--r--tests/ui/parser/issues/issue-81804.rs5
-rw-r--r--tests/ui/parser/issues/issue-81804.stderr4
-rw-r--r--tests/ui/parser/issues/issue-81827.rs7
-rw-r--r--tests/ui/parser/issues/issue-81827.stderr4
-rw-r--r--tests/ui/parser/issues/issue-84104.rs2
-rw-r--r--tests/ui/parser/issues/issue-84148-2.rs2
-rw-r--r--tests/ui/parser/issues/issue-88770.rs3
-rw-r--r--tests/ui/parser/issues/issue-88770.stderr2
-rw-r--r--tests/ui/parser/macro/trait-non-item-macros.rs2
-rw-r--r--tests/ui/parser/macro/trait-non-item-macros.stderr2
-rw-r--r--tests/ui/parser/mbe_missing_right_paren.rs2
-rw-r--r--tests/ui/parser/missing_right_paren.rs3
-rw-r--r--tests/ui/parser/missing_right_paren.stderr2
-rw-r--r--tests/ui/parser/recover/recover-pat-exprs.stderr116
-rw-r--r--tests/ui/parser/recover/recover-pat-issues.stderr24
-rw-r--r--tests/ui/parser/recover/recover-pat-lets.stderr8
-rw-r--r--tests/ui/parser/recover/recover-pat-ranges.stderr24
-rw-r--r--tests/ui/parser/recover/recover-pat-wildcards.stderr4
-rw-r--r--tests/ui/parser/shebang/shebang-split.rs3
-rw-r--r--tests/ui/parser/unbalanced-doublequote.rs4
-rw-r--r--tests/ui/parser/unbalanced-doublequote.stderr2
-rw-r--r--tests/ui/parser/use-unclosed-brace.rs2
-rw-r--r--tests/ui/parser/utf16-be-without-bom.rsbin162 -> 202 bytes
-rw-r--r--tests/ui/parser/utf16-be-without-bom.stderr28
-rw-r--r--tests/ui/parser/utf16-le-without-bom.rsbin163 -> 203 bytes
-rw-r--r--tests/ui/parser/utf16-le-without-bom.stderr28
-rw-r--r--tests/ui/pattern/non-structural-match-types.rs31
-rw-r--r--tests/ui/pattern/non-structural-match-types.stderr46
-rw-r--r--tests/ui/pin-macro/pin_move.rs26
-rw-r--r--tests/ui/pin-macro/pin_move.stderr38
-rw-r--r--tests/ui/precondition-checks/copy-nonoverlapping.rs2
-rw-r--r--tests/ui/precondition-checks/copy.rs2
-rw-r--r--tests/ui/precondition-checks/read_volatile.rs2
-rw-r--r--tests/ui/precondition-checks/replace.rs2
-rw-r--r--tests/ui/precondition-checks/slice-from-raw-parts-mut.rs2
-rw-r--r--tests/ui/precondition-checks/slice-from-raw-parts.rs2
-rw-r--r--tests/ui/precondition-checks/swap-nonoverlapping.rs2
-rw-r--r--tests/ui/precondition-checks/write_volatile.rs2
-rw-r--r--tests/ui/precondition-checks/zero-size-null.rs2
-rw-r--r--tests/ui/print-request/print-lints-help.rs3
-rw-r--r--tests/ui/print-request/print-lints-help.stderr2
-rw-r--r--tests/ui/print-request/stability.rs13
-rw-r--r--tests/ui/privacy/privacy-ns1.stderr24
-rw-r--r--tests/ui/privacy/privacy-ns2.stderr24
-rw-r--r--tests/ui/privacy/private-inferred-type-3.rs15
-rw-r--r--tests/ui/privacy/private-inferred-type-3.stderr14
-rw-r--r--tests/ui/proc-macro/export-macro.rs4
-rw-r--r--tests/ui/proc-macro/export-macro.stderr2
-rw-r--r--tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs4
-rw-r--r--tests/ui/proc-macro/macro-rules-derive-cfg.stdout129
-rw-r--r--tests/ui/proc-macro/no-macro-use-attr.rs5
-rw-r--r--tests/ui/proc-macro/no-macro-use-attr.stderr8
-rw-r--r--tests/ui/proc-macro/nonterminal-token-hygiene.stdout20
-rw-r--r--tests/ui/proc-macro/panic-abort.rs3
-rw-r--r--tests/ui/proc-macro/two-crate-types-1.rs4
-rw-r--r--tests/ui/proc-macro/two-crate-types-2.rs3
-rw-r--r--tests/ui/reachable/unreachable-code-ret.rs4
-rw-r--r--tests/ui/reachable/unreachable-code-ret.stderr4
-rw-r--r--tests/ui/resolve/auxiliary/macro_helpers.rs16
-rw-r--r--tests/ui/resolve/bad-env-capture.rs4
-rw-r--r--tests/ui/resolve/bad-env-capture.stderr6
-rw-r--r--tests/ui/resolve/bad-env-capture2.rs4
-rw-r--r--tests/ui/resolve/bad-env-capture2.stderr6
-rw-r--r--tests/ui/resolve/bad-env-capture3.rs4
-rw-r--r--tests/ui/resolve/bad-env-capture3.stderr6
-rw-r--r--tests/ui/resolve/issue-21221-1.stderr11
-rw-r--r--tests/ui/resolve/prelude-order.rs89
-rw-r--r--tests/ui/resolve/prelude-order.stderr47
-rw-r--r--tests/ui/return/ret-non-nil.rs4
-rw-r--r--tests/ui/return/ret-non-nil.stderr2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.no_gate.stderr2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.rs6
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.with_gate.stderr8
-rw-r--r--tests/ui/rfcs/rfc-1717-dllimport/missing-link-attr.rs3
-rw-r--r--tests/ui/rfcs/rfc-1717-dllimport/multiple-renames.rs3
-rw-r--r--tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.rs2
-rw-r--r--tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.stderr2
-rw-r--r--tests/ui/rfcs/rfc-1717-dllimport/rename-to-empty.rs3
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs2
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr26
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr264
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr274
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr196
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs4
-rw-r--r--tests/ui/rmeta/no_optitimized_mir.rs2
-rw-r--r--tests/ui/rmeta/no_optitimized_mir.stderr2
-rw-r--r--tests/ui/rmeta/rmeta_bin.rs3
-rw-r--r--tests/ui/rmeta/rmeta_lib.rs3
-rw-r--r--tests/ui/rustc-error.rs6
-rw-r--r--tests/ui/rustc-error.stderr8
-rw-r--r--tests/ui/sanitizer/incompatible.rs3
-rw-r--r--tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs9
-rw-r--r--tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr4
-rw-r--r--tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs11
-rw-r--r--tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr4
-rw-r--r--tests/ui/sanitizer/unsupported-target.rs4
-rw-r--r--tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs26
-rw-r--r--tests/ui/simd/empty-simd-vector-in-operand.rs15
-rw-r--r--tests/ui/simd/empty-simd-vector-in-operand.stderr15
-rw-r--r--tests/ui/simd/monomorphize-too-long.rs3
-rw-r--r--tests/ui/simd/monomorphize-zero-length.rs3
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-empty.rs4
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-non-primitive.rs4
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-oversized.rs4
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs4
-rw-r--r--tests/ui/simd/type-generic-monomorphisation.rs5
-rw-r--r--tests/ui/simd/type-wide-ptr.rs4
-rw-r--r--tests/ui/sized/dont-incompletely-prefer-built-in.rs21
-rw-r--r--tests/ui/span/range-2.rs4
-rw-r--r--tests/ui/span/regionck-unboxed-closure-lifetimes.rs3
-rw-r--r--tests/ui/span/regionck-unboxed-closure-lifetimes.stderr2
-rw-r--r--tests/ui/stable-mir-print/async-closure.stdout2
-rw-r--r--tests/ui/stats/input-stats.stderr78
-rw-r--r--tests/ui/str/str-idx.stderr21
-rw-r--r--tests/ui/str/str-mut-idx.stderr19
-rw-r--r--tests/ui/suggestions/attribute-typos.rs4
-rw-r--r--tests/ui/suggestions/attribute-typos.stderr10
-rw-r--r--tests/ui/suggestions/suggest-dereferencing-index.stderr7
-rw-r--r--tests/ui/tail-typeck.rs4
-rw-r--r--tests/ui/tail-typeck.stderr2
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs4
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs4
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs5
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs5
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag-disable.rs2
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag.rs4
-rw-r--r--tests/ui/target-feature/invalid-attribute.stderr12
-rw-r--r--tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs3
-rw-r--r--tests/ui/target-feature/tied-features-no-implication.pacg.stderr4
-rw-r--r--tests/ui/target-feature/tied-features-no-implication.rs8
-rw-r--r--tests/ui/test-attrs/test-panic-abort-disabled.rs3
-rw-r--r--tests/ui/track-diagnostics/track.rs3
-rw-r--r--tests/ui/track-diagnostics/track2.rs2
-rw-r--r--tests/ui/track-diagnostics/track3.rs2
-rw-r--r--tests/ui/track-diagnostics/track4.rs2
-rw-r--r--tests/ui/track-diagnostics/track5.rs2
-rw-r--r--tests/ui/track-diagnostics/track6.rs2
-rw-r--r--tests/ui/traits/const-traits/assoc-type.current.stderr2
-rw-r--r--tests/ui/traits/const-traits/assoc-type.next.stderr2
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst.stderr2
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-opaque.no.stderr2
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr2
-rw-r--r--tests/ui/traits/const-traits/feature-gate.gated.stderr8
-rw-r--r--tests/ui/traits/const-traits/feature-gate.rs5
-rw-r--r--tests/ui/traits/const-traits/item-bound-entailment-fails.stderr6
-rw-r--r--tests/ui/traits/const-traits/minicore-fn-fail.stderr2
-rw-r--r--tests/ui/traits/const-traits/predicate-entailment-fails.stderr12
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.stderr4
-rw-r--r--tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr2
-rw-r--r--tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs25
-rw-r--r--tests/ui/traits/default_auto_traits/default-bounds.rs41
-rw-r--r--tests/ui/traits/default_auto_traits/default-bounds.stderr31
-rw-r--r--tests/ui/traits/default_auto_traits/extern-types.current.stderr17
-rw-r--r--tests/ui/traits/default_auto_traits/extern-types.next.stderr17
-rw-r--r--tests/ui/traits/default_auto_traits/extern-types.rs49
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs61
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr23
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs115
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr71
-rw-r--r--tests/ui/traits/incomplete-infer-via-sized-wc.current.stderr9
-rw-r--r--tests/ui/traits/incomplete-infer-via-sized-wc.next.stderr9
-rw-r--r--tests/ui/traits/incomplete-infer-via-sized-wc.rs19
-rw-r--r--tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc-2.rs28
-rw-r--r--tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr27
-rw-r--r--tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr25
-rw-r--r--tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs26
-rw-r--r--tests/ui/traits/mutual-recursion-issue-75860.stderr2
-rw-r--r--tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs (renamed from tests/crashes/132335.rs)5
-rw-r--r--tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr44
-rw-r--r--tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs8
-rw-r--r--tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs11
-rw-r--r--tests/ui/traits/object/suggestion-trait-object-issue-139174.rs24
-rw-r--r--tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr40
-rw-r--r--tests/ui/traits/solver-cycles/129541-recursive-struct.rs3
-rw-r--r--tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs2
-rw-r--r--tests/ui/treat-err-as-bug/span_delayed_bug.rs4
-rw-r--r--tests/ui/treat-err-as-bug/span_delayed_bug.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr17
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction2.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/different_args_considered_equal.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr20
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_not_used.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_not_used.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden4.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr35
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.stderr35
-rw-r--r--tests/ui/type-alias-impl-trait/issue-109054.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-109054.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53096.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53096.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53598.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53598.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60407.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60407.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60564.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60564.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/multi-error.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/multi-error.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/non-defining-method.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr34
-rw-r--r--tests/ui/type-alias-impl-trait/not_a_defining_use.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/not_a_defining_use.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-fn-tait.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr11
-rw-r--r--tests/ui/type/issue-91268.rs3
-rw-r--r--tests/ui/type/issue-91268.stderr2
-rw-r--r--tests/ui/type/pattern_types/const_block.rs10
-rw-r--r--tests/ui/type/type-arg-out-of-scope.rs3
-rw-r--r--tests/ui/type/type-arg-out-of-scope.stderr4
-rw-r--r--tests/ui/typeck/issue-91334.rs4
-rw-r--r--tests/ui/typeck/output-type-mismatch.rs4
-rw-r--r--tests/ui/typeck/output-type-mismatch.stderr2
-rw-r--r--tests/ui/typeck/while-type-error.rs4
-rw-r--r--tests/ui/typeck/while-type-error.stderr2
-rw-r--r--tests/ui/typeck/wrong-ret-type.rs3
-rw-r--r--tests/ui/typeck/wrong-ret-type.stderr2
-rw-r--r--tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.rs2
-rw-r--r--tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.rs2
-rw-r--r--tests/ui/unresolved/unresolved-import.rs2
-rw-r--r--tests/ui/unresolved/unresolved-import.stderr10
-rw-r--r--tests/ui/unsafe/const_pat_in_layout_restricted.rs23
-rw-r--r--tests/ui/use/use-meta-mismatch.rs4
-rw-r--r--tests/ui/use/use-meta-mismatch.stderr2
-rw-r--r--tests/ui/variance/variance-uniquearc.rs27
-rw-r--r--tests/ui/variance/variance-uniquearc.stderr15
-rw-r--r--tests/ui/variance/variance-uniquerc.rs2
-rw-r--r--tests/ui/windows-subsystem/windows-subsystem-invalid.rs4
-rw-r--r--triagebot.toml45
1650 files changed, 20077 insertions, 16880 deletions
diff --git a/.gitattributes b/.gitattributes
index d29c15fe712..8700d5d6dcf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,6 +5,7 @@
 *.h rust
 *.rs rust diff=rust
 *.fixed linguist-language=Rust
+*.pp linguist-language=Rust
 *.mir linguist-language=Rust
 src/etc/installer/gfx/* binary
 src/vendor/** -text
diff --git a/.gitmodules b/.gitmodules
index 97a0c0c54cf..d09d81ccadc 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -45,7 +45,7 @@
 	shallow = true
 [submodule "src/tools/enzyme"]
 	path = src/tools/enzyme
-	url = https://github.com/EnzymeAD/Enzyme.git
+	url = https://github.com/rust-lang/Enzyme.git
 	shallow = true
 [submodule "src/gcc"]
 	path = src/gcc
diff --git a/.mailmap b/.mailmap
index a791daa681d..b09aebd12dd 100644
--- a/.mailmap
+++ b/.mailmap
@@ -276,7 +276,7 @@ Jacob Greenfield <xales@naveria.com>
 Jacob Pratt <jacob@jhpratt.dev> <the.z.cuber@gmail.com>
 Jacob Pratt <jacob@jhpratt.dev> <jacopratt@tesla.com>
 Jake Goulding <jake.goulding@integer32.com>
-Jake Goulding <jake.goulding@integer32.com> <jake.goulding@gmail.com> 
+Jake Goulding <jake.goulding@integer32.com> <jake.goulding@gmail.com>
 Jake Goulding <jake.goulding@integer32.com> <shepmaster@mac.com>
 Jake Vossen <jake@vossen.dev>
 Jakob Degen <jakob.e.degen@gmail.com> <jakob@degen.com>
@@ -408,10 +408,13 @@ Luqman Aden <me@luqman.ca> <laden@mozilla.com>
 Luqman Aden <me@luqman.ca> <rust@luqman.ca>
 Lzu Tao <taolzu@gmail.com>
 Maik Klein <maikklein@googlemail.com>
+Maja Kądziołka <maya@compilercrim.es> <github@compilercrim.es>
+Maja Kądziołka <maya@compilercrim.es> <kuba@kadziolka.net>
 Malo Jaffré <jaffre.malo@gmail.com>
 Manish Goregaokar <manishsmail@gmail.com>
 Mara Bos <m-ou.se@m-ou.se>
 Marcell Pardavi <marcell.pardavi@gmail.com>
+Marco Ieni <11428655+MarcoIeni@users.noreply.github.com>
 Marcus Klaas de Vries <mail@marcusklaas.nl>
 Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> <mmeyerho@andrew>
 Mark Mansi <markm@cs.wisc.edu>
@@ -565,6 +568,9 @@ Robert Habermeier <rphmeier@gmail.com>
 Robert Millar <robert.millar@cantab.net>
 Roc Yu <rocyu@protonmail.com>
 Rohit Joshi <rohitjoshi@users.noreply.github.com> Rohit Joshi <rohit.joshi@capitalone.com>
+Ross Smyth <18294397+RossSmyth@users.noreply.github.com>
+Ross Smyth <18294397+RossSmyth@users.noreply.github.com> <crs2017@gmail.com>
+Ross Smyth <18294397+RossSmyth@users.noreply.github.com> <rsmyth@electrocraft.com>
 Roxane Fruytier <roxane.fruytier@hotmail.com>
 Rui <xiongmao86dev@sina.com>
 Russell Johnston <rpjohnst@gmail.com>
diff --git a/Cargo.lock b/Cargo.lock
index 01d7e0beea6..99bd1bff020 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -158,9 +158,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.95"
+version = "1.0.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
 dependencies = [
  "backtrace",
 ]
@@ -215,9 +215,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
 
 [[package]]
 name = "basic-toml"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8"
+checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
 dependencies = [
  "serde",
 ]
@@ -233,15 +233,15 @@ dependencies = [
 
 [[package]]
 name = "bitflags"
-version = "2.8.0"
+version = "2.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
 
 [[package]]
 name = "blake3"
-version = "1.5.5"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e"
+checksum = "34a796731680be7931955498a16a10b2270c7762963d5d570fdbfe02dcbf314f"
 dependencies = [
  "arrayref",
  "arrayvec",
@@ -308,9 +308,9 @@ dependencies = [
 
 [[package]]
 name = "bumpalo"
-version = "3.16.0"
+version = "3.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
 
 [[package]]
 name = "bytecount"
@@ -319,16 +319,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce"
 
 [[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
-[[package]]
 name = "bytes"
-version = "1.9.0"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
 
 [[package]]
 name = "camino"
@@ -346,7 +340,7 @@ dependencies = [
  "cargo_metadata 0.18.1",
  "directories",
  "rustc-build-sysroot",
- "rustc_tools_util 0.4.0",
+ "rustc_tools_util 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version",
  "serde",
  "serde_json",
@@ -377,16 +371,16 @@ dependencies = [
 
 [[package]]
 name = "cargo_metadata"
-version = "0.19.1"
+version = "0.19.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8769706aad5d996120af43197bf46ef6ad0fda35216b4505f926a365a232d924"
+checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
 dependencies = [
  "camino",
  "cargo-platform",
  "semver",
  "serde",
  "serde_json",
- "thiserror 2.0.11",
+ "thiserror 2.0.12",
 ]
 
 [[package]]
@@ -416,22 +410,22 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
 
 [[package]]
 name = "chrono"
-version = "0.4.39"
+version = "0.4.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
+checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
  "num-traits",
  "serde",
- "windows-targets 0.52.6",
+ "windows-link",
 ]
 
 [[package]]
 name = "chrono-tz"
-version = "0.10.1"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c6ac4f2c0bf0f44e9161aec9675e1050aa4a530663c4a9e37e108fa948bca9f"
+checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3"
 dependencies = [
  "chrono",
  "chrono-tz-build",
@@ -440,9 +434,9 @@ dependencies = [
 
 [[package]]
 name = "chrono-tz-build"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e94fea34d77a245229e7746bd2beb786cd2a896f306ff491fb8cecb3074b10a7"
+checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402"
 dependencies = [
  "parse-zoneinfo",
  "phf_codegen",
@@ -460,9 +454,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.26"
+version = "4.5.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
+checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -480,9 +474,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.26"
+version = "4.5.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
+checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9"
 dependencies = [
  "anstream",
  "anstyle",
@@ -492,14 +486,14 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.5.24"
+version = "4.5.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
+checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
 dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -530,12 +524,12 @@ dependencies = [
  "rustc_tools_util 0.4.2",
  "serde",
  "serde_json",
- "syn 2.0.96",
+ "syn 2.0.100",
  "tempfile",
  "termize",
  "tokio",
  "toml 0.7.8",
- "ui_test 0.29.2",
+ "ui_test",
  "walkdir",
 ]
 
@@ -640,7 +634,7 @@ dependencies = [
  "nom",
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -707,9 +701,9 @@ dependencies = [
 
 [[package]]
 name = "console"
-version = "0.15.10"
+version = "0.15.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b"
+checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
 dependencies = [
  "encode_unicode",
  "libc",
@@ -744,9 +738,9 @@ dependencies = [
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.16"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
 dependencies = [
  "libc",
 ]
@@ -831,9 +825,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.78+curl-8.11.0"
+version = "0.4.80+curl-8.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8eec768341c5c7789611ae51cf6c459099f22e64a5d5d0ce4892434e33821eaf"
+checksum = "55f7df2eac63200c3ab25bde3b2268ef2ee56af3d238e76d61f01c3c49bff734"
 dependencies = [
  "cc",
  "libc",
@@ -846,9 +840,9 @@ dependencies = [
 
 [[package]]
 name = "darling"
-version = "0.20.10"
+version = "0.20.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
+checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
 dependencies = [
  "darling_core",
  "darling_macro",
@@ -856,27 +850,27 @@ dependencies = [
 
 [[package]]
 name = "darling_core"
-version = "0.20.10"
+version = "0.20.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
+checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
 dependencies = [
  "fnv",
  "ident_case",
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
 name = "darling_macro"
-version = "0.20.10"
+version = "0.20.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
+checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -898,9 +892,9 @@ dependencies = [
 
 [[package]]
 name = "deranged"
-version = "0.3.11"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
 dependencies = [
  "powerfmt",
 ]
@@ -913,7 +907,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -934,7 +928,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -944,7 +938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
 dependencies = [
  "derive_builder_core",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -956,7 +950,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -1034,26 +1028,26 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
 name = "dissimilar"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d"
+checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921"
 
 [[package]]
 name = "either"
-version = "1.13.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
 
 [[package]]
 name = "elsa"
-version = "1.11.0"
+version = "1.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2343daaeabe09879d4ea058bb4f1e63da3fc07dadc6634e01bda1b3d6a9d9d2b"
+checksum = "9abf33c656a7256451ebb7d0082c5a471820c31269e49d807c538c252352186e"
 dependencies = [
  "stable_deref_trait",
 ]
@@ -1085,22 +1079,22 @@ dependencies = [
 
 [[package]]
 name = "env_logger"
-version = "0.11.6"
+version = "0.11.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0"
+checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697"
 dependencies = [
  "anstream",
  "anstyle",
  "env_filter",
- "humantime",
+ "jiff",
  "log",
 ]
 
 [[package]]
 name = "equivalent"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
 
 [[package]]
 name = "errno"
@@ -1169,12 +1163,12 @@ dependencies = [
 
 [[package]]
 name = "flate2"
-version = "1.0.35"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
+checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
 dependencies = [
  "crc32fast",
- "miniz_oxide 0.8.3",
+ "miniz_oxide 0.8.5",
 ]
 
 [[package]]
@@ -1219,9 +1213,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
 name = "foldhash"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
 
 [[package]]
 name = "form_urlencoded"
@@ -1313,7 +1307,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -1397,14 +1391,14 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi 0.13.3+wasi-0.2.2",
- "windows-targets 0.52.6",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
 ]
 
 [[package]]
@@ -1432,9 +1426,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
 
 [[package]]
 name = "globset"
-version = "0.4.15"
+version = "0.4.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19"
+checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5"
 dependencies = [
  "aho-corasick",
  "bstr",
@@ -1516,9 +1510,9 @@ dependencies = [
 
 [[package]]
 name = "html5ever"
-version = "0.29.2"
+version = "0.29.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b958f80f0fde8601dc6c08685adc743eecaa046181cebd5a57551468dfc2ddc"
+checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c"
 dependencies = [
  "log",
  "mac",
@@ -1537,22 +1531,23 @@ dependencies = [
 
 [[package]]
 name = "humantime"
-version = "2.1.0"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f"
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.61"
+version = "0.1.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
+checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
  "iana-time-zone-haiku",
  "js-sys",
+ "log",
  "wasm-bindgen",
- "windows-core 0.52.0",
+ "windows-core 0.61.0",
 ]
 
 [[package]]
@@ -1592,9 +1587,9 @@ dependencies = [
 
 [[package]]
 name = "icu_list_data"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1825170d2c6679cb20dbd96a589d034e49f698aed9a2ef4fafc9a0101ed298f"
+checksum = "52b1a7fbdbf3958f1be8354cb59ac73f165b7b7082d447ff2090355c9a069120"
 
 [[package]]
 name = "icu_locid"
@@ -1625,9 +1620,9 @@ dependencies = [
 
 [[package]]
 name = "icu_locid_transform_data"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
+checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
 
 [[package]]
 name = "icu_normalizer"
@@ -1649,9 +1644,9 @@ dependencies = [
 
 [[package]]
 name = "icu_normalizer_data"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
 
 [[package]]
 name = "icu_properties"
@@ -1670,9 +1665,9 @@ dependencies = [
 
 [[package]]
 name = "icu_properties_data"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
 
 [[package]]
 name = "icu_provider"
@@ -1712,7 +1707,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -1778,9 +1773,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
 
 [[package]]
 name = "indexmap"
-version = "2.7.0"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
+checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -1789,9 +1784,9 @@ dependencies = [
 
 [[package]]
 name = "indicatif"
-version = "0.17.9"
+version = "0.17.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281"
+checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235"
 dependencies = [
  "console",
  "number_prefix",
@@ -1808,9 +1803,9 @@ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
 
 [[package]]
 name = "inout"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
 dependencies = [
  "generic-array",
 ]
@@ -1864,16 +1859,41 @@ dependencies = [
 
 [[package]]
 name = "itoa"
-version = "1.0.14"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "jiff"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260"
+dependencies = [
+ "jiff-static",
+ "log",
+ "portable-atomic",
+ "portable-atomic-util",
+ "serde",
+]
+
+[[package]]
+name = "jiff-static"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
+checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.100",
+]
 
 [[package]]
 name = "jobserver"
-version = "0.1.32"
+version = "0.1.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
+checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
 dependencies = [
+ "getrandom 0.3.2",
  "libc",
 ]
 
@@ -1922,7 +1942,7 @@ dependencies = [
  "pest_derive",
  "regex",
  "serde_json",
- "thiserror 2.0.11",
+ "thiserror 2.0.12",
 ]
 
 [[package]]
@@ -1938,6 +1958,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
 
 [[package]]
+name = "leb128fmt"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
+
+[[package]]
 name = "levenshtein"
 version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1945,15 +1971,15 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
 
 [[package]]
 name = "lexopt"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
+checksum = "9fa0e2a1fcbe2f6be6c42e342259976206b383122fc152e872795338b5a3f3a7"
 
 [[package]]
 name = "libc"
-version = "0.2.169"
+version = "0.2.171"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
 
 [[package]]
 name = "libdbus-sys"
@@ -2013,9 +2039,9 @@ dependencies = [
 
 [[package]]
 name = "libz-sys"
-version = "1.1.21"
+version = "1.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa"
+checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
 dependencies = [
  "cc",
  "libc",
@@ -2042,15 +2068,15 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.15"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
 
 [[package]]
 name = "litemap"
-version = "0.7.4"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
+checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
 
 [[package]]
 name = "lld-wrapper"
@@ -2079,9 +2105,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.25"
+version = "0.4.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
 
 [[package]]
 name = "lzma-sys"
@@ -2102,9 +2128,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
 
 [[package]]
 name = "markup5ever"
-version = "0.15.0"
+version = "0.14.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03a7b81dfb91586d0677086d40a6d755070e0799b71bb897485bac408dfd5c69"
+checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18"
 dependencies = [
  "log",
  "phf",
@@ -2122,7 +2148,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -2226,9 +2252,9 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.3"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
+checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
 dependencies = [
  "adler2",
 ]
@@ -2251,7 +2277,7 @@ dependencies = [
  "chrono-tz",
  "colored",
  "directories",
- "getrandom 0.3.1",
+ "getrandom 0.3.2",
  "libc",
  "libffi",
  "libloading",
@@ -2262,7 +2288,7 @@ dependencies = [
  "smallvec",
  "tempfile",
  "tikv-jemalloc-sys",
- "ui_test 0.28.0",
+ "ui_test",
  "windows-sys 0.52.0",
 ]
 
@@ -2442,7 +2468,7 @@ dependencies = [
  "indexmap",
  "memchr",
  "ruzstd",
- "wasmparser 0.222.0",
+ "wasmparser 0.222.1",
 ]
 
 [[package]]
@@ -2456,9 +2482,9 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.20.2"
+version = "1.21.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
 name = "opener"
@@ -2474,15 +2500,15 @@ dependencies = [
 
 [[package]]
 name = "openssl-probe"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.104"
+version = "0.9.106"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
+checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd"
 dependencies = [
  "cc",
  "libc",
@@ -2617,20 +2643,20 @@ dependencies = [
 
 [[package]]
 name = "pest"
-version = "2.7.15"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
+checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6"
 dependencies = [
  "memchr",
- "thiserror 2.0.11",
+ "thiserror 2.0.12",
  "ucd-trie",
 ]
 
 [[package]]
 name = "pest_derive"
-version = "2.7.15"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e"
+checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5"
 dependencies = [
  "pest",
  "pest_generator",
@@ -2638,22 +2664,22 @@ dependencies = [
 
 [[package]]
 name = "pest_generator"
-version = "2.7.15"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b"
+checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841"
 dependencies = [
  "pest",
  "pest_meta",
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
 name = "pest_meta"
-version = "2.7.15"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea"
+checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0"
 dependencies = [
  "once_cell",
  "pest",
@@ -2712,9 +2738,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.31"
+version = "0.3.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
 
 [[package]]
 name = "polonius-engine"
@@ -2729,9 +2755,18 @@ dependencies = [
 
 [[package]]
 name = "portable-atomic"
-version = "1.10.0"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
+checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
+
+[[package]]
+name = "portable-atomic-util"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
+dependencies = [
+ "portable-atomic",
+]
 
 [[package]]
 name = "powerfmt"
@@ -2741,11 +2776,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.20"
+version = "0.2.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
 dependencies = [
- "zerocopy 0.7.35",
+ "zerocopy",
 ]
 
 [[package]]
@@ -2772,9 +2807,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.93"
+version = "1.0.94"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
 dependencies = [
  "unicode-ident",
 ]
@@ -2831,14 +2866,20 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
 
 [[package]]
 name = "quote"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
+name = "r-efi"
+version = "5.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
 name = "rand"
 version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2856,8 +2897,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
 dependencies = [
  "rand_chacha 0.9.0",
- "rand_core 0.9.0",
- "zerocopy 0.8.14",
+ "rand_core 0.9.3",
+ "zerocopy",
 ]
 
 [[package]]
@@ -2877,7 +2918,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
 dependencies = [
  "ppv-lite86",
- "rand_core 0.9.0",
+ "rand_core 0.9.3",
 ]
 
 [[package]]
@@ -2891,12 +2932,11 @@ dependencies = [
 
 [[package]]
 name = "rand_core"
-version = "0.9.0"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
 dependencies = [
- "getrandom 0.3.1",
- "zerocopy 0.8.14",
+ "getrandom 0.3.2",
 ]
 
 [[package]]
@@ -2905,7 +2945,7 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41"
 dependencies = [
- "rand_core 0.9.0",
+ "rand_core 0.9.3",
 ]
 
 [[package]]
@@ -2930,9 +2970,9 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.8"
+version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
+checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
 dependencies = [
  "bitflags",
 ]
@@ -3050,7 +3090,7 @@ dependencies = [
  "rinja_parser",
  "rustc-hash 2.1.1",
  "serde",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -3077,7 +3117,7 @@ dependencies = [
  "regex",
  "serde_json",
  "similar",
- "wasmparser 0.219.1",
+ "wasmparser 0.219.2",
 ]
 
 [[package]]
@@ -3147,9 +3187,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-stable-hash"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2febf9acc5ee5e99d1ad0afcdbccc02d87aa3f857a1f01f825b80eacf8edfcd1"
+checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08"
 
 [[package]]
 name = "rustc-std-workspace-alloc"
@@ -3457,7 +3497,7 @@ dependencies = [
  "thin-vec",
  "thorin-dwp",
  "tracing",
- "wasm-encoder 0.219.1",
+ "wasm-encoder 0.219.2",
  "windows 0.59.0",
 ]
 
@@ -3682,7 +3722,7 @@ dependencies = [
  "fluent-syntax",
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "unic-langid",
 ]
 
@@ -3825,7 +3865,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -3972,7 +4012,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "synstructure",
 ]
 
@@ -4300,6 +4340,7 @@ name = "rustc_resolve"
 version = "0.0.0"
 dependencies = [
  "bitflags",
+ "itertools",
  "pulldown-cmark 0.11.3",
  "rustc_arena",
  "rustc_ast",
@@ -4391,7 +4432,7 @@ dependencies = [
  "rustc_span",
  "rustc_target",
  "scoped-tls",
- "stable_mir",
+ "serde",
  "tracing",
 ]
 
@@ -4452,13 +4493,13 @@ dependencies = [
 
 [[package]]
 name = "rustc_tools_util"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3316159ab19e19d1065ecc49278e87f767a9dae9fae80348d2b4d4fa4ae02d4d"
+version = "0.4.2"
 
 [[package]]
 name = "rustc_tools_util"
 version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3b75158011a63889ba12084cf1224baad7bcad50f6ee7c842f772b74aa148ed"
 
 [[package]]
 name = "rustc_trait_selection"
@@ -4560,7 +4601,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "synstructure",
 ]
 
@@ -4650,7 +4691,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -4684,9 +4725,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.43"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
+checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
 dependencies = [
  "bitflags",
  "errno",
@@ -4697,9 +4738,9 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.19"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
+checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
 
 [[package]]
 name = "ruzstd"
@@ -4712,9 +4753,9 @@ dependencies = [
 
 [[package]]
 name = "ryu"
-version = "1.0.18"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
 [[package]]
 name = "same-file"
@@ -4763,38 +4804,38 @@ checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe"
 
 [[package]]
 name = "semver"
-version = "1.0.24"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
+checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "serde"
-version = "1.0.217"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.217"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.135"
+version = "1.0.140"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
 dependencies = [
  "itoa",
  "memchr",
@@ -4856,9 +4897,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
 name = "similar"
-version = "2.6.0"
+version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e"
+checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
 
 [[package]]
 name = "siphasher"
@@ -4877,15 +4918,15 @@ dependencies = [
 
 [[package]]
 name = "smallvec"
-version = "1.13.2"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
 
 [[package]]
 name = "socket2"
-version = "0.5.8"
+version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
+checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
 dependencies = [
  "libc",
  "windows-sys 0.52.0",
@@ -4949,15 +4990,14 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 name = "stable_mir"
 version = "0.1.0-preview"
 dependencies = [
- "scoped-tls",
- "serde",
+ "rustc_smir",
 ]
 
 [[package]]
 name = "stacker"
-version = "0.1.18"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d08feb8f695b465baed819b03c128dc23f57a694510ab1f06c77f763975685e"
+checksum = "601f9201feb9b09c00266478bf459952b9ef9a6b94edb2f21eba14ab681a60a9"
 dependencies = [
  "cc",
  "cfg-if",
@@ -4974,9 +5014,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 
 [[package]]
 name = "string_cache"
-version = "0.8.8"
+version = "0.8.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "938d512196766101d333398efde81bc1f37b00cb42c2f8350e5df639f040bbbe"
+checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f"
 dependencies = [
  "new_debug_unreachable",
  "parking_lot",
@@ -5043,9 +5083,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.96"
+version = "2.0.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5060,7 +5100,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -5086,9 +5126,9 @@ dependencies = [
 
 [[package]]
 name = "tar"
-version = "0.4.43"
+version = "0.4.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6"
+checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a"
 dependencies = [
  "filetime",
  "libc",
@@ -5097,13 +5137,12 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.15.0"
+version = "3.19.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
 dependencies = [
- "cfg-if",
  "fastrand",
- "getrandom 0.2.15",
+ "getrandom 0.3.2",
  "once_cell",
  "rustix",
  "windows-sys 0.59.0",
@@ -5163,9 +5202,9 @@ dependencies = [
 
 [[package]]
 name = "thin-vec"
-version = "0.2.13"
+version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b"
+checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d"
 
 [[package]]
 name = "thiserror"
@@ -5178,11 +5217,11 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "2.0.11"
+version = "2.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
 dependencies = [
- "thiserror-impl 2.0.11",
+ "thiserror-impl 2.0.12",
 ]
 
 [[package]]
@@ -5193,18 +5232,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "2.0.11"
+version = "2.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -5243,7 +5282,7 @@ name = "tidy"
 version = "0.1.0"
 dependencies = [
  "build_helper",
- "cargo_metadata 0.19.1",
+ "cargo_metadata 0.19.2",
  "fluent-syntax",
  "ignore",
  "miropt-test-tools",
@@ -5273,9 +5312,9 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.37"
+version = "0.3.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
+checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
 dependencies = [
  "deranged",
  "itoa",
@@ -5288,15 +5327,15 @@ dependencies = [
 
 [[package]]
 name = "time-core"
-version = "0.1.2"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
 
 [[package]]
 name = "time-macros"
-version = "0.2.19"
+version = "0.2.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
+checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
 dependencies = [
  "num-conv",
  "time-core",
@@ -5314,9 +5353,9 @@ dependencies = [
 
 [[package]]
 name = "tinyvec"
-version = "1.8.1"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
+checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71"
 dependencies = [
  "tinyvec_macros",
 ]
@@ -5329,9 +5368,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.43.0"
+version = "1.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
+checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
 dependencies = [
  "backtrace",
  "bytes",
@@ -5401,7 +5440,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -5488,9 +5527,9 @@ dependencies = [
 
 [[package]]
 name = "typenum"
-version = "1.17.0"
+version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
 
 [[package]]
 name = "ucd-parse"
@@ -5509,32 +5548,6 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
 
 [[package]]
 name = "ui_test"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
-dependencies = [
- "annotate-snippets 0.11.5",
- "anyhow",
- "bstr",
- "cargo-platform",
- "cargo_metadata 0.18.1",
- "color-eyre",
- "colored",
- "comma",
- "crossbeam-channel",
- "indicatif",
- "levenshtein",
- "prettydiff",
- "regex",
- "rustc_version",
- "rustfix",
- "serde",
- "serde_json",
- "spanned",
-]
-
-[[package]]
-name = "ui_test"
 version = "0.29.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1211b1111c752c73b33073d2958072be08825fd97c9ab4d83444da361a06634b"
@@ -5598,7 +5611,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "unic-langid-impl",
 ]
 
@@ -5610,9 +5623,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.14"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "unicode-normalization"
@@ -5736,11 +5749,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
 name = "uuid"
-version = "1.12.0"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4"
+checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
 dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.3.2",
 ]
 
 [[package]]
@@ -5779,9 +5792,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasi"
-version = "0.13.3+wasi-0.2.2"
+version = "0.14.2+wasi-0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
 dependencies = [
  "wit-bindgen-rt",
 ]
@@ -5814,7 +5827,7 @@ dependencies = [
  "log",
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "wasm-bindgen-shared",
 ]
 
@@ -5836,7 +5849,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -5862,7 +5875,7 @@ dependencies = [
  "libc",
  "tempfile",
  "wasi-preview1-component-adapter-provider",
- "wasmparser 0.223.0",
+ "wasmparser 0.223.1",
  "wat",
  "windows-sys 0.59.0",
  "winsplit",
@@ -5879,29 +5892,39 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.219.1"
+version = "0.219.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54"
+checksum = "8aa79bcd666a043b58f5fa62b221b0b914dd901e6f620e8ab7371057a797f3e1"
 dependencies = [
  "leb128",
- "wasmparser 0.219.1",
+ "wasmparser 0.219.2",
 ]
 
 [[package]]
 name = "wasm-encoder"
-version = "0.223.0"
+version = "0.223.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e636076193fa68103e937ac951b5f2f587624097017d764b8984d9c0f149464"
+checksum = "7a0a96fdeaee8fbeb4bd917fb8157d48c0d61c3b1f4ee4c363c8e8d68b2f4fe8"
 dependencies = [
  "leb128",
- "wasmparser 0.223.0",
+ "wasmparser 0.223.1",
+]
+
+[[package]]
+name = "wasm-encoder"
+version = "0.228.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05d30290541f2d4242a162bbda76b8f2d8b1ac59eab3568ed6f2327d52c9b2c4"
+dependencies = [
+ "leb128fmt",
+ "wasmparser 0.228.0",
 ]
 
 [[package]]
 name = "wasm-metadata"
-version = "0.223.0"
+version = "0.223.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c730c3379d3d20e5a0245b0724b924483e853588ca8fba547c1e21f19e7d735"
+checksum = "e2e7e37883181704d96b89dbd8f1291be13694c71cd0663aebb94b46d235a377"
 dependencies = [
  "anyhow",
  "indexmap",
@@ -5910,15 +5933,15 @@ dependencies = [
  "serde_json",
  "spdx",
  "url",
- "wasm-encoder 0.223.0",
- "wasmparser 0.223.0",
+ "wasm-encoder 0.223.1",
+ "wasmparser 0.223.1",
 ]
 
 [[package]]
 name = "wasmparser"
-version = "0.219.1"
+version = "0.219.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5"
+checksum = "5220ee4c6ffcc0cb9d7c47398052203bc902c8ef3985b0c8134118440c0b2921"
 dependencies = [
  "bitflags",
  "indexmap",
@@ -5926,18 +5949,18 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.222.0"
+version = "0.222.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4adf50fde1b1a49c1add6a80d47aea500c88db70551805853aa8b88f3ea27ab5"
+checksum = "fa210fd1788e6b37a1d1930f3389c48e1d6ebd1a013d34fa4b7f9e3e3bf03146"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
 name = "wasmparser"
-version = "0.223.0"
+version = "0.223.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35"
+checksum = "664b980991ed9a8c834eb528a8979ab1109edcf52dc05dd5751e2cc3fb31035d"
 dependencies = [
  "bitflags",
  "hashbrown",
@@ -5947,23 +5970,34 @@ dependencies = [
 ]
 
 [[package]]
+name = "wasmparser"
+version = "0.228.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3"
+dependencies = [
+ "bitflags",
+ "indexmap",
+ "semver",
+]
+
+[[package]]
 name = "wast"
-version = "223.0.0"
+version = "228.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59b2ba8a2ff9f06194b7be9524f92e45e70149f4dacc0d0c7ad92b59ac875e4"
+checksum = "9e5aae124478cb51439f6587f074a3a5e835afd22751c59a87b2e2a882727c97"
 dependencies = [
  "bumpalo",
- "leb128",
+ "leb128fmt",
  "memchr",
  "unicode-width 0.2.0",
- "wasm-encoder 0.223.0",
+ "wasm-encoder 0.228.0",
 ]
 
 [[package]]
 name = "wat"
-version = "1.223.0"
+version = "1.228.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "662786915c427e4918ff01eabb3c4756d4d947cd8f635761526b4cc9da2eaaad"
+checksum = "7ec29c89a8d055df988de7236483bf569988ac3d6905899f6af5ef920f9385ad"
 dependencies = [
  "wast",
 ]
@@ -6040,15 +6074,6 @@ dependencies = [
 
 [[package]]
 name = "windows-core"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-core"
 version = "0.57.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
@@ -6066,13 +6091,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
 dependencies = [
  "windows-implement 0.59.0",
- "windows-interface 0.59.0",
- "windows-result 0.3.0",
- "windows-strings",
+ "windows-interface 0.59.1",
+ "windows-result 0.3.2",
+ "windows-strings 0.3.1",
  "windows-targets 0.53.0",
 ]
 
 [[package]]
+name = "windows-core"
+version = "0.61.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
+dependencies = [
+ "windows-implement 0.60.0",
+ "windows-interface 0.59.1",
+ "windows-link",
+ "windows-result 0.3.2",
+ "windows-strings 0.4.0",
+]
+
+[[package]]
 name = "windows-implement"
 version = "0.57.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6080,7 +6118,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -6091,7 +6129,18 @@ checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.100",
 ]
 
 [[package]]
@@ -6102,21 +6151,27 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
 name = "windows-interface"
-version = "0.59.0"
+version = "0.59.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01"
+checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
+name = "windows-link"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+
+[[package]]
 name = "windows-result"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6127,20 +6182,29 @@ dependencies = [
 
 [[package]]
 name = "windows-result"
-version = "0.3.0"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d08106ce80268c4067c0571ca55a9b4e9516518eaa1a1fe9b37ca403ae1d1a34"
+checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
 dependencies = [
- "windows-targets 0.53.0",
+ "windows-link",
 ]
 
 [[package]]
 name = "windows-strings"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b888f919960b42ea4e11c2f408fadb55f78a9f236d5eef084103c8ce52893491"
+checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
 dependencies = [
- "windows-targets 0.53.0",
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
+dependencies = [
+ "windows-link",
 ]
 
 [[package]]
@@ -6372,18 +6436,18 @@ checksum = "3ab703352da6a72f35c39a533526393725640575bb211f61987a2748323ad956"
 
 [[package]]
 name = "wit-bindgen-rt"
-version = "0.33.0"
+version = "0.39.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
 name = "wit-component"
-version = "0.223.0"
+version = "0.223.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c10ed2aeee4c8ec5715875f62f4a3de3608d6987165c116810d8c2908aa9d93b"
+checksum = "3fc2fcc52a79f6f010a89c867e53e06d4227f86c58984add3e37f32b8e7af5f0"
 dependencies = [
  "anyhow",
  "bitflags",
@@ -6392,17 +6456,17 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "wasm-encoder 0.223.0",
+ "wasm-encoder 0.223.1",
  "wasm-metadata",
- "wasmparser 0.223.0",
+ "wasmparser 0.223.1",
  "wit-parser",
 ]
 
 [[package]]
 name = "wit-parser"
-version = "0.223.0"
+version = "0.223.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92772f4dcacb804b275981eea1d920b12b377993b53307f1e33d87404e080281"
+checksum = "263fde17f1fbe55a413f16eb59094bf751795c6da469a05c3d45ea6c77df6b40"
 dependencies = [
  "anyhow",
  "id-arena",
@@ -6413,7 +6477,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser 0.223.0",
+ "wasmparser 0.223.1",
 ]
 
 [[package]]
@@ -6434,12 +6498,11 @@ version = "0.1.1"
 
 [[package]]
 name = "xattr"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909"
+checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e"
 dependencies = [
  "libc",
- "linux-raw-sys",
  "rustix",
 ]
 
@@ -6481,69 +6544,48 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "synstructure",
 ]
 
 [[package]]
 name = "zerocopy"
-version = "0.7.35"
+version = "0.8.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
 dependencies = [
- "byteorder",
- "zerocopy-derive 0.7.35",
-]
-
-[[package]]
-name = "zerocopy"
-version = "0.8.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
-dependencies = [
- "zerocopy-derive 0.8.14",
+ "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.7.35"
+version = "0.8.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
 
 [[package]]
 name = "zerofrom"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
 dependencies = [
  "zerofrom-derive",
 ]
 
 [[package]]
 name = "zerofrom-derive"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
  "synstructure",
 ]
 
@@ -6566,5 +6608,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.96",
+ "syn 2.0.100",
 ]
diff --git a/RELEASES.md b/RELEASES.md
index 755e73a34c6..0948eb85192 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,126 @@
+Version 1.86.0 (2025-04-03)
+==========================
+
+<a id="1.86.0-Language"></a>
+
+Language
+--------
+- [Stabilize upcasting trait objects to supertraits.](https://github.com/rust-lang/rust/pull/134367)
+- [Allow safe functions to be marked with the `#[target_feature]` attribute.](https://github.com/rust-lang/rust/pull/134090)
+- [The `missing_abi` lint now warns-by-default.](https://github.com/rust-lang/rust/pull/132397)
+- Rust now lints about double negations, to catch cases that might have intended to be a prefix decrement operator (`--x`) as written in other languages. This was previously a clippy lint, `clippy::double_neg`, and is [now available directly in Rust as `double_negations`.](https://github.com/rust-lang/rust/pull/126604)
+- [More pointers are now detected as definitely not-null based on their alignment in const eval.](https://github.com/rust-lang/rust/pull/133700)
+- [Empty `repr()` attribute applied to invalid items are now correctly rejected.](https://github.com/rust-lang/rust/pull/133925)
+- [Inner attributes `#![test]` and `#![rustfmt::skip]` are no longer accepted in more places than intended.](https://github.com/rust-lang/rust/pull/134276)
+
+<a id="1.86.0-Compiler"></a>
+
+Compiler
+--------
+- [Debug-assert that raw pointers are non-null on access.](https://github.com/rust-lang/rust/pull/134424)
+- [Change `-O` to mean `-C opt-level=3` instead of `-C opt-level=2` to match Cargo's defaults.](https://github.com/rust-lang/rust/pull/135439)
+- [Fix emission of `overflowing_literals` under certain macro environments.](https://github.com/rust-lang/rust/pull/136393)
+
+<a id="1.86.0-Platform-Support"></a>
+
+Platform Support
+----------------
+- [Replace `i686-unknown-redox` target with `i586-unknown-redox`.](https://github.com/rust-lang/rust/pull/136698)
+- [Increase baseline CPU of `i686-unknown-hurd-gnu` to Pentium 4.](https://github.com/rust-lang/rust/pull/136700)
+- New tier 3 targets:
+  - [`{aarch64-unknown,x86_64-pc}-nto-qnx710_iosock`](https://github.com/rust-lang/rust/pull/133631).
+    For supporting Neutrino QNX 7.1 with `io-socket` network stack.
+  - [`{aarch64-unknown,x86_64-pc}-nto-qnx800`](https://github.com/rust-lang/rust/pull/133631).
+    For supporting Neutrino QNX 8.0 (`no_std`-only).
+  - [`{x86_64,i686}-win7-windows-gnu`](https://github.com/rust-lang/rust/pull/134609).
+    Intended for backwards compatibility with Windows 7. `{x86_64,i686}-win7-windows-msvc` are the Windows MSVC counterparts that already exist as Tier 3 targets.
+  - [`amdgcn-amd-amdhsa`](https://github.com/rust-lang/rust/pull/134740).
+  - [`x86_64-pc-cygwin`](https://github.com/rust-lang/rust/pull/134999).
+  - [`{mips,mipsel}-mti-none-elf`](https://github.com/rust-lang/rust/pull/135074).
+    Initial bare-metal support.
+  - [`m68k-unknown-none-elf`](https://github.com/rust-lang/rust/pull/135085).
+  - [`armv7a-nuttx-{eabi,eabihf}`, `aarch64-unknown-nuttx`, and `thumbv7a-nuttx-{eabi,eabihf}`](https://github.com/rust-lang/rust/pull/135757).
+
+Refer to Rust's [platform support page][platform-support-doc]
+for more information on Rust's tiered platform support.
+
+<a id="1.86.0-Libraries"></a>
+
+Libraries
+---------
+- The type of `FromBytesWithNulError` in `CStr::from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError>` was [changed from an opaque struct to an enum](https://github.com/rust-lang/rust/pull/134143), allowing users to examine why the conversion failed.
+- [Remove `RustcDecodable` and `RustcEncodable`.](https://github.com/rust-lang/rust/pull/134272)
+- [Deprecate libtest's `--logfile` option.](https://github.com/rust-lang/rust/pull/134283)
+- [On recent versions of Windows, `std::fs::remove_file` will now remove read-only files.](https://github.com/rust-lang/rust/pull/134679)
+
+<a id="1.86.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`{float}::next_down`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_down)
+- [`{float}::next_up`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_up)
+- [`<[_]>::get_disjoint_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_mut)
+- [`<[_]>::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_unchecked_mut)
+- [`slice::GetDisjointMutError`](https://doc.rust-lang.org/stable/std/slice/enum.GetDisjointMutError.html)
+- [`HashMap::get_disjoint_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_mut)
+- [`HashMap::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_unchecked_mut)
+- [`NonZero::count_ones`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.count_ones)
+- [`Vec::pop_if`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pop_if)
+- [`sync::Once::wait`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait)
+- [`sync::Once::wait_force`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait_force)
+- [`sync::OnceLock::wait`](https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.wait)
+
+These APIs are now stable in const contexts:
+
+- [`hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html)
+- [`io::Cursor::get_mut`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_mut)
+- [`io::Cursor::set_position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.set_position)
+- [`str::is_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.is_char_boundary)
+- [`str::split_at`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at)
+- [`str::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_checked)
+- [`str::split_at_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut)
+- [`str::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut_checked)
+
+<a id="1.86.0-Cargo"></a>
+
+Cargo
+-----
+- [When merging, replace rather than combine configuration keys that refer to a program path and its arguments.](https://github.com/rust-lang/cargo/pull/15066/)
+- [Error if both `--package` and `--workspace` are passed but the requested package is missing.](https://github.com/rust-lang/cargo/pull/15071/) This was previously silently ignored, which was considered a bug since missing packages should be reported.
+- [Deprecate the token argument in `cargo login` to avoid shell history leaks.](https://github.com/rust-lang/cargo/pull/15057/)
+- [Simplify the implementation of `SourceID` comparisons.](https://github.com/rust-lang/cargo/pull/14980/) This may potentially change behavior if the canonicalized URL compares differently in alternative registries.
+
+<a id="1.86.0-Rustdoc"></a>
+
+Rustdoc
+-----
+- [Add a sans-serif font setting.](https://github.com/rust-lang/rust/pull/133636)
+
+<a id="1.86.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+- [The `wasm_c_abi` future compatibility warning is now a hard error.](https://github.com/rust-lang/rust/pull/133951)
+  Users of `wasm-bindgen` should upgrade to at least version 0.2.89, otherwise compilation will fail.
+- [Remove long-deprecated no-op attributes `#![no_start]` and `#![crate_id]`.](https://github.com/rust-lang/rust/pull/134300)
+- [The future incompatibility lint `cenum_impl_drop_cast` has been made into a hard error.](https://github.com/rust-lang/rust/pull/135964) This means it is now an error to cast a field-less enum to an integer if the enum implements `Drop`.
+- [SSE2 is now required for "i686" 32-bit x86 hard-float targets; disabling it causes a warning that will become a hard error eventually.](https://github.com/rust-lang/rust/pull/137037)
+  To compile for pre-SSE2 32-bit x86, use a "i586" target instead.
+
+<a id="1.86.0-Internal-Changes"></a>
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Build the rustc on AArch64 Linux with ThinLTO + PGO.](https://github.com/rust-lang/rust/pull/133807)
+  The ARM 64-bit compiler (AArch64) on Linux is now optimized with ThinLTO and PGO, similar to the optimizations we have already performed for the x86-64 compiler on Linux. This should make it up to 30% faster.
+
+
 Version 1.85.1 (2025-03-18)
 ==========================
 
diff --git a/bootstrap.example.toml b/bootstrap.example.toml
index caffe1a9371..2a98821f225 100644
--- a/bootstrap.example.toml
+++ b/bootstrap.example.toml
@@ -28,8 +28,9 @@
 #  - A new option
 #  - A change in the default values
 #
-# If `change-id` does not match the version that is currently running,
-# `x.py` will inform you about the changes made on bootstrap.
+# If the change-id does not match the version currently in use, x.py will 
+# display the changes made to the bootstrap.
+# To suppress these warnings, you can set change-id = "ignore".
 #change-id = <latest change id in src/bootstrap/src/utils/change_tracker.rs>
 
 # =============================================================================
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 3f28dc7a1ef..843d5ca61dd 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1462,7 +1462,8 @@ impl BackendRepr {
         !self.is_unsized()
     }
 
-    /// Returns `true` if this is a single signed integer scalar
+    /// Returns `true` if this is a single signed integer scalar.
+    /// Sanity check: panics if this is not a scalar type (see PR #70189).
     #[inline]
     pub fn is_signed(&self) -> bool {
         match self {
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 064f05ef1f3..97e6879c33e 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -981,6 +981,75 @@ impl BinOpKind {
 
 pub type BinOp = Spanned<BinOpKind>;
 
+// Sometimes `BinOpKind` and `AssignOpKind` need the same treatment. The
+// operations covered by `AssignOpKind` are a subset of those covered by
+// `BinOpKind`, so it makes sense to convert `AssignOpKind` to `BinOpKind`.
+impl From<AssignOpKind> for BinOpKind {
+    fn from(op: AssignOpKind) -> BinOpKind {
+        match op {
+            AssignOpKind::AddAssign => BinOpKind::Add,
+            AssignOpKind::SubAssign => BinOpKind::Sub,
+            AssignOpKind::MulAssign => BinOpKind::Mul,
+            AssignOpKind::DivAssign => BinOpKind::Div,
+            AssignOpKind::RemAssign => BinOpKind::Rem,
+            AssignOpKind::BitXorAssign => BinOpKind::BitXor,
+            AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
+            AssignOpKind::BitOrAssign => BinOpKind::BitOr,
+            AssignOpKind::ShlAssign => BinOpKind::Shl,
+            AssignOpKind::ShrAssign => BinOpKind::Shr,
+        }
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
+pub enum AssignOpKind {
+    /// The `+=` operator (addition)
+    AddAssign,
+    /// The `-=` operator (subtraction)
+    SubAssign,
+    /// The `*=` operator (multiplication)
+    MulAssign,
+    /// The `/=` operator (division)
+    DivAssign,
+    /// The `%=` operator (modulus)
+    RemAssign,
+    /// The `^=` operator (bitwise xor)
+    BitXorAssign,
+    /// The `&=` operator (bitwise and)
+    BitAndAssign,
+    /// The `|=` operator (bitwise or)
+    BitOrAssign,
+    /// The `<<=` operator (shift left)
+    ShlAssign,
+    /// The `>>=` operator (shift right)
+    ShrAssign,
+}
+
+impl AssignOpKind {
+    pub fn as_str(&self) -> &'static str {
+        use AssignOpKind::*;
+        match self {
+            AddAssign => "+=",
+            SubAssign => "-=",
+            MulAssign => "*=",
+            DivAssign => "/=",
+            RemAssign => "%=",
+            BitXorAssign => "^=",
+            BitAndAssign => "&=",
+            BitOrAssign => "|=",
+            ShlAssign => "<<=",
+            ShrAssign => ">>=",
+        }
+    }
+
+    /// AssignOps are always by value.
+    pub fn is_by_value(self) -> bool {
+        true
+    }
+}
+
+pub type AssignOp = Spanned<AssignOpKind>;
+
 /// Unary operator.
 ///
 /// Note that `&data` is not an operator, it's an `AddrOf` expression.
@@ -1593,7 +1662,7 @@ pub enum ExprKind {
     /// An assignment with an operator.
     ///
     /// E.g., `a += 1`.
-    AssignOp(BinOp, P<Expr>, P<Expr>),
+    AssignOp(AssignOp, P<Expr>, P<Expr>),
     /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
     Field(P<Expr>, Ident),
     /// An indexing operation (e.g., `foo[2]`).
@@ -3303,9 +3372,6 @@ pub struct Item<K = ItemKind> {
     pub id: NodeId,
     pub span: Span,
     pub vis: Visibility,
-    /// The name of the item.
-    /// It might be a dummy name in case of anonymous items.
-    pub ident: Ident,
 
     pub kind: K,
 
@@ -3327,23 +3393,23 @@ impl Item {
 
     pub fn opt_generics(&self) -> Option<&Generics> {
         match &self.kind {
-            ItemKind::ExternCrate(_)
+            ItemKind::ExternCrate(..)
             | ItemKind::Use(_)
-            | ItemKind::Mod(_, _)
+            | ItemKind::Mod(..)
             | ItemKind::ForeignMod(_)
             | ItemKind::GlobalAsm(_)
             | ItemKind::MacCall(_)
             | ItemKind::Delegation(_)
             | ItemKind::DelegationMac(_)
-            | ItemKind::MacroDef(_) => None,
+            | 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::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),
         }
@@ -3420,6 +3486,7 @@ impl Default for FnHeader {
 pub struct Trait {
     pub safety: Safety,
     pub is_auto: IsAuto,
+    pub ident: Ident,
     pub generics: Generics,
     pub bounds: GenericBounds,
     pub items: ThinVec<P<AssocItem>>,
@@ -3465,6 +3532,7 @@ pub struct TyAliasWhereClauses {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct TyAlias {
     pub defaultness: Defaultness,
+    pub ident: Ident,
     pub generics: Generics,
     pub where_clauses: TyAliasWhereClauses,
     pub bounds: GenericBounds,
@@ -3493,6 +3561,7 @@ pub struct FnContract {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Fn {
     pub defaultness: Defaultness,
+    pub ident: Ident,
     pub generics: Generics,
     pub sig: FnSig,
     pub contract: Option<P<FnContract>>,
@@ -3506,6 +3575,7 @@ pub struct Delegation {
     pub id: NodeId,
     pub qself: Option<P<QSelf>>,
     pub path: Path,
+    pub ident: Ident,
     pub rename: Option<Ident>,
     pub body: Option<P<Block>>,
     /// The item was expanded from a glob delegation item.
@@ -3523,6 +3593,7 @@ pub struct DelegationMac {
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct StaticItem {
+    pub ident: Ident,
     pub ty: P<Ty>,
     pub safety: Safety,
     pub mutability: Mutability,
@@ -3533,6 +3604,7 @@ pub struct StaticItem {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct ConstItem {
     pub defaultness: Defaultness,
+    pub ident: Ident,
     pub generics: Generics,
     pub ty: P<Ty>,
     pub expr: Option<P<Expr>>,
@@ -3545,7 +3617,7 @@ pub enum ItemKind {
     /// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
     ///
     /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
-    ExternCrate(Option<Symbol>),
+    ExternCrate(Option<Symbol>, Ident),
     /// A use declaration item (`use`).
     ///
     /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
@@ -3567,7 +3639,7 @@ pub enum ItemKind {
     /// E.g., `mod foo;` or `mod foo { .. }`.
     /// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
     /// semantically by Rust.
-    Mod(Safety, ModKind),
+    Mod(Safety, Ident, ModKind),
     /// An external module (`extern`).
     ///
     /// E.g., `extern {}` or `extern "C" {}`.
@@ -3581,15 +3653,15 @@ pub enum ItemKind {
     /// An enum definition (`enum`).
     ///
     /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
-    Enum(EnumDef, Generics),
+    Enum(Ident, EnumDef, Generics),
     /// A struct definition (`struct`).
     ///
     /// E.g., `struct Foo<A> { x: A }`.
-    Struct(VariantData, Generics),
+    Struct(Ident, VariantData, Generics),
     /// A union definition (`union`).
     ///
     /// E.g., `union Foo<A, B> { x: A, y: B }`.
-    Union(VariantData, Generics),
+    Union(Ident, VariantData, Generics),
     /// A trait declaration (`trait`).
     ///
     /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
@@ -3597,7 +3669,7 @@ pub enum ItemKind {
     /// Trait alias.
     ///
     /// E.g., `trait Foo = Bar + Quux;`.
-    TraitAlias(Generics, GenericBounds),
+    TraitAlias(Ident, Generics, GenericBounds),
     /// An implementation.
     ///
     /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
@@ -3608,7 +3680,7 @@ pub enum ItemKind {
     MacCall(P<MacCall>),
 
     /// A macro definition.
-    MacroDef(MacroDef),
+    MacroDef(Ident, MacroDef),
 
     /// A single delegation item (`reuse`).
     ///
@@ -3620,6 +3692,31 @@ pub enum ItemKind {
 }
 
 impl ItemKind {
+    pub fn ident(&self) -> Option<Ident> {
+        match *self {
+            ItemKind::ExternCrate(_, ident)
+            | ItemKind::Static(box StaticItem { ident, .. })
+            | ItemKind::Const(box ConstItem { ident, .. })
+            | ItemKind::Fn(box Fn { ident, .. })
+            | ItemKind::Mod(_, ident, _)
+            | ItemKind::TyAlias(box TyAlias { ident, .. })
+            | ItemKind::Enum(ident, ..)
+            | ItemKind::Struct(ident, ..)
+            | ItemKind::Union(ident, ..)
+            | ItemKind::Trait(box Trait { ident, .. })
+            | ItemKind::TraitAlias(ident, ..)
+            | ItemKind::MacroDef(ident, _)
+            | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
+
+            ItemKind::Use(_)
+            | ItemKind::ForeignMod(_)
+            | ItemKind::GlobalAsm(_)
+            | ItemKind::Impl(_)
+            | ItemKind::MacCall(_)
+            | ItemKind::DelegationMac(_) => None,
+        }
+    }
+
     /// "a" or "an"
     pub fn article(&self) -> &'static str {
         use ItemKind::*;
@@ -3660,11 +3757,11 @@ impl ItemKind {
             Self::Fn(box Fn { generics, .. })
             | Self::TyAlias(box TyAlias { generics, .. })
             | Self::Const(box ConstItem { generics, .. })
-            | Self::Enum(_, generics)
-            | Self::Struct(_, generics)
-            | Self::Union(_, generics)
+            | Self::Enum(_, _, generics)
+            | Self::Struct(_, _, generics)
+            | Self::Union(_, _, generics)
             | Self::Trait(box Trait { generics, .. })
-            | Self::TraitAlias(generics, _)
+            | Self::TraitAlias(_, generics, _)
             | Self::Impl(box Impl { generics, .. }) => Some(generics),
             _ => None,
         }
@@ -3700,6 +3797,17 @@ pub enum AssocItemKind {
 }
 
 impl AssocItemKind {
+    pub fn ident(&self) -> Option<Ident> {
+        match *self {
+            AssocItemKind::Const(box ConstItem { ident, .. })
+            | AssocItemKind::Fn(box Fn { ident, .. })
+            | AssocItemKind::Type(box TyAlias { ident, .. })
+            | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
+
+            AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
+        }
+    }
+
     pub fn defaultness(&self) -> Defaultness {
         match *self {
             Self::Const(box ConstItem { defaultness, .. })
@@ -3746,14 +3854,26 @@ impl TryFrom<ItemKind> for AssocItemKind {
 pub enum ForeignItemKind {
     /// A foreign static item (`static FOO: u8`).
     Static(Box<StaticItem>),
-    /// An foreign function.
+    /// A foreign function.
     Fn(Box<Fn>),
-    /// An foreign type.
+    /// A foreign type.
     TyAlias(Box<TyAlias>),
     /// A macro expanding to foreign items.
     MacCall(P<MacCall>),
 }
 
+impl ForeignItemKind {
+    pub fn ident(&self) -> Option<Ident> {
+        match *self {
+            ForeignItemKind::Static(box StaticItem { ident, .. })
+            | ForeignItemKind::Fn(box Fn { ident, .. })
+            | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
+
+            ForeignItemKind::MacCall(_) => None,
+        }
+    }
+}
+
 impl From<ForeignItemKind> for ItemKind {
     fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
         match foreign_item_kind {
@@ -3790,21 +3910,21 @@ mod size_asserts {
 
     use super::*;
     // tidy-alphabetical-start
-    static_assert_size!(AssocItem, 88);
+    static_assert_size!(AssocItem, 80);
     static_assert_size!(AssocItemKind, 16);
     static_assert_size!(Attribute, 32);
     static_assert_size!(Block, 32);
     static_assert_size!(Expr, 72);
     static_assert_size!(ExprKind, 40);
-    static_assert_size!(Fn, 176);
-    static_assert_size!(ForeignItem, 88);
+    static_assert_size!(Fn, 184);
+    static_assert_size!(ForeignItem, 80);
     static_assert_size!(ForeignItemKind, 16);
     static_assert_size!(GenericArg, 24);
     static_assert_size!(GenericBound, 88);
     static_assert_size!(Generics, 40);
     static_assert_size!(Impl, 136);
-    static_assert_size!(Item, 136);
-    static_assert_size!(ItemKind, 64);
+    static_assert_size!(Item, 144);
+    static_assert_size!(ItemKind, 80);
     static_assert_size!(LitKind, 24);
     static_assert_size!(Local, 80);
     static_assert_size!(MetaItemLit, 40);
diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs
index 849cc650e9d..c9e2e9911ef 100644
--- a/compiler/rustc_ast/src/ast_traits.rs
+++ b/compiler/rustc_ast/src/ast_traits.rs
@@ -209,13 +209,11 @@ impl HasTokens for Attribute {
 impl HasTokens for Nonterminal {
     fn tokens(&self) -> Option<&LazyAttrTokenStream> {
         match self {
-            Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
             Nonterminal::NtBlock(block) => block.tokens(),
         }
     }
     fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
         match self {
-            Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
             Nonterminal::NtBlock(block) => block.tokens_mut(),
         }
     }
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 4d613085d79..0b65246693d 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -570,6 +570,14 @@ impl MetaItemInner {
         }
     }
 
+    /// Returns the bool if `self` is a boolean `MetaItemInner::Literal`.
+    pub fn boolean_literal(&self) -> Option<bool> {
+        match self {
+            MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => Some(*b),
+            _ => None,
+        }
+    }
+
     /// Returns the `MetaItem` if `self` is a `MetaItemInner::MetaItem` or if it's
     /// `MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(_), .. })`.
     pub fn meta_item_or_bool(&self) -> Option<&MetaItemInner> {
diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
index c8ec185ee5e..f01c781f46c 100644
--- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs
+++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
@@ -77,6 +77,17 @@ pub struct AutoDiffAttrs {
     /// e.g. in the [JAX
     /// Documentation](https://jax.readthedocs.io/en/latest/_tutorials/advanced-autodiff.html#how-it-s-made-two-foundational-autodiff-functions).
     pub mode: DiffMode,
+    /// A user-provided, batching width. If not given, we will default to 1 (no batching).
+    /// Calling a differentiated, non-batched function through a loop 100 times is equivalent to:
+    /// - Calling the function 50 times with a batch size of 2
+    /// - Calling the function 25 times with a batch size of 4,
+    /// etc. A batched function takes more (or longer) arguments, and might be able to benefit from
+    /// cache locality, better re-usal of primal values, and other optimizations.
+    /// We will (before LLVM's vectorizer runs) just generate most LLVM-IR instructions `width`
+    /// times, so this massively increases code size. As such, values like 1024 are unlikely to
+    /// work. We should consider limiting this to u8 or u16, but will leave it at u32 for
+    /// experiments for now and focus on documenting the implications of a large width.
+    pub width: u32,
     pub ret_activity: DiffActivity,
     pub input_activity: Vec<DiffActivity>,
 }
@@ -222,6 +233,7 @@ impl AutoDiffAttrs {
     pub const fn error() -> Self {
         AutoDiffAttrs {
             mode: DiffMode::Error,
+            width: 0,
             ret_activity: DiffActivity::None,
             input_activity: Vec::new(),
         }
@@ -229,6 +241,7 @@ impl AutoDiffAttrs {
     pub fn source() -> Self {
         AutoDiffAttrs {
             mode: DiffMode::Source,
+            width: 0,
             ret_activity: DiffActivity::None,
             input_activity: Vec::new(),
         }
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 274fe312f7f..f7d13acdfc4 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -41,7 +41,6 @@ pub trait WalkItemKind {
         &mut self,
         span: Span,
         id: NodeId,
-        ident: &mut Ident,
         visibility: &mut Visibility,
         ctxt: Self::Ctxt,
         visitor: &mut impl MutVisitor,
@@ -900,8 +899,6 @@ pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) {
 fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
     match nt {
         token::NtBlock(block) => vis.visit_block(block),
-        token::NtExpr(expr) => vis.visit_expr(expr),
-        token::NtLiteral(expr) => vis.visit_expr(expr),
     }
 }
 
@@ -963,10 +960,10 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
     match kind {
         FnKind::Fn(
             _ctxt,
-            _ident,
             _vis,
             Fn {
                 defaultness,
+                ident,
                 generics,
                 contract,
                 body,
@@ -974,8 +971,9 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
                 define_opaque,
             },
         ) => {
-            // Identifier and visibility are visited as a part of the item.
+            // Visibility is visited as a part of the item.
             visit_defaultness(vis, defaultness);
+            vis.visit_ident(ident);
             vis.visit_fn_header(header);
             vis.visit_generics(generics);
             vis.visit_fn_decl(decl);
@@ -1233,12 +1231,11 @@ pub fn walk_item_kind<K: WalkItemKind>(
     kind: &mut K,
     span: Span,
     id: NodeId,
-    ident: &mut Ident,
     visibility: &mut Visibility,
     ctxt: K::Ctxt,
     vis: &mut impl MutVisitor,
 ) {
-    kind.walk(span, id, ident, visibility, ctxt, vis)
+    kind.walk(span, id, visibility, ctxt, vis)
 }
 
 impl WalkItemKind for ItemKind {
@@ -1247,21 +1244,22 @@ impl WalkItemKind for ItemKind {
         &mut self,
         span: Span,
         id: NodeId,
-        ident: &mut Ident,
         visibility: &mut Visibility,
         _ctxt: Self::Ctxt,
         vis: &mut impl MutVisitor,
     ) {
         match self {
-            ItemKind::ExternCrate(_orig_name) => {}
+            ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
             ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
             ItemKind::Static(box StaticItem {
+                ident,
                 ty,
                 safety: _,
                 mutability: _,
                 expr,
                 define_opaque,
             }) => {
+                vis.visit_ident(ident);
                 vis.visit_ty(ty);
                 visit_opt(expr, |expr| vis.visit_expr(expr));
                 walk_define_opaques(vis, define_opaque);
@@ -1270,10 +1268,11 @@ impl WalkItemKind for ItemKind {
                 walk_const_item(vis, item);
             }
             ItemKind::Fn(func) => {
-                vis.visit_fn(FnKind::Fn(FnCtxt::Free, ident, visibility, &mut *func), span, id);
+                vis.visit_fn(FnKind::Fn(FnCtxt::Free, visibility, &mut *func), span, id);
             }
-            ItemKind::Mod(safety, mod_kind) => {
+            ItemKind::Mod(safety, ident, mod_kind) => {
                 visit_safety(vis, safety);
+                vis.visit_ident(ident);
                 match mod_kind {
                     ModKind::Loaded(
                         items,
@@ -1290,18 +1289,29 @@ impl WalkItemKind for ItemKind {
             }
             ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
             ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
-            ItemKind::TyAlias(box TyAlias { defaultness, generics, where_clauses, bounds, ty }) => {
+            ItemKind::TyAlias(box TyAlias {
+                defaultness,
+                ident,
+                generics,
+                where_clauses,
+                bounds,
+                ty,
+            }) => {
                 visit_defaultness(vis, defaultness);
+                vis.visit_ident(ident);
                 vis.visit_generics(generics);
                 visit_bounds(vis, bounds, BoundKind::Bound);
                 visit_opt(ty, |ty| vis.visit_ty(ty));
                 walk_ty_alias_where_clauses(vis, where_clauses);
             }
-            ItemKind::Enum(EnumDef { variants }, generics) => {
+            ItemKind::Enum(ident, EnumDef { variants }, generics) => {
+                vis.visit_ident(ident);
                 vis.visit_generics(generics);
                 variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
             }
-            ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
+            ItemKind::Struct(ident, variant_data, generics)
+            | ItemKind::Union(ident, variant_data, generics) => {
+                vis.visit_ident(ident);
                 vis.visit_generics(generics);
                 vis.visit_variant_data(variant_data);
             }
@@ -1326,22 +1336,28 @@ impl WalkItemKind for ItemKind {
                     vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
                 });
             }
-            ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => {
+            ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
                 visit_safety(vis, safety);
+                vis.visit_ident(ident);
                 vis.visit_generics(generics);
                 visit_bounds(vis, bounds, BoundKind::Bound);
                 items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait));
             }
-            ItemKind::TraitAlias(generics, bounds) => {
+            ItemKind::TraitAlias(ident, generics, bounds) => {
+                vis.visit_ident(ident);
                 vis.visit_generics(generics);
                 visit_bounds(vis, bounds, BoundKind::Bound);
             }
             ItemKind::MacCall(m) => vis.visit_mac_call(m),
-            ItemKind::MacroDef(def) => vis.visit_macro_def(def),
+            ItemKind::MacroDef(ident, def) => {
+                vis.visit_ident(ident);
+                vis.visit_macro_def(def)
+            }
             ItemKind::Delegation(box Delegation {
                 id,
                 qself,
                 path,
+                ident,
                 rename,
                 body,
                 from_glob: _,
@@ -1349,6 +1365,7 @@ impl WalkItemKind for ItemKind {
                 vis.visit_id(id);
                 vis.visit_qself(qself);
                 vis.visit_path(path);
+                vis.visit_ident(ident);
                 if let Some(rename) = rename {
                     vis.visit_ident(rename);
                 }
@@ -1381,7 +1398,6 @@ impl WalkItemKind for AssocItemKind {
         &mut self,
         span: Span,
         id: NodeId,
-        ident: &mut Ident,
         visibility: &mut Visibility,
         ctxt: Self::Ctxt,
         visitor: &mut impl MutVisitor,
@@ -1391,20 +1407,18 @@ impl WalkItemKind for AssocItemKind {
                 walk_const_item(visitor, item);
             }
             AssocItemKind::Fn(func) => {
-                visitor.visit_fn(
-                    FnKind::Fn(FnCtxt::Assoc(ctxt), ident, visibility, &mut *func),
-                    span,
-                    id,
-                );
+                visitor.visit_fn(FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &mut *func), span, id);
             }
             AssocItemKind::Type(box TyAlias {
                 defaultness,
+                ident,
                 generics,
                 where_clauses,
                 bounds,
                 ty,
             }) => {
                 visit_defaultness(visitor, defaultness);
+                visitor.visit_ident(ident);
                 visitor.visit_generics(generics);
                 visit_bounds(visitor, bounds, BoundKind::Bound);
                 visit_opt(ty, |ty| visitor.visit_ty(ty));
@@ -1415,6 +1429,7 @@ impl WalkItemKind for AssocItemKind {
                 id,
                 qself,
                 path,
+                ident,
                 rename,
                 body,
                 from_glob: _,
@@ -1422,6 +1437,7 @@ impl WalkItemKind for AssocItemKind {
                 visitor.visit_id(id);
                 visitor.visit_qself(qself);
                 visitor.visit_path(path);
+                visitor.visit_ident(ident);
                 if let Some(rename) = rename {
                     visitor.visit_ident(rename);
                 }
@@ -1449,8 +1465,9 @@ impl WalkItemKind for AssocItemKind {
 }
 
 fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) {
-    let ConstItem { defaultness, generics, ty, expr, define_opaque } = item;
+    let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
     visit_defaultness(vis, defaultness);
+    vis.visit_ident(ident);
     vis.visit_generics(generics);
     vis.visit_ty(ty);
     visit_opt(expr, |expr| vis.visit_expr(expr));
@@ -1487,12 +1504,11 @@ fn walk_item_ctxt<K: WalkItemKind>(
     item: &mut P<Item<K>>,
     ctxt: K::Ctxt,
 ) {
-    let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
+    let Item { attrs, id, kind, vis, span, tokens } = item.deref_mut();
     visitor.visit_id(id);
     visit_attrs(visitor, attrs);
     visitor.visit_vis(vis);
-    visitor.visit_ident(ident);
-    kind.walk(*span, *id, ident, vis, ctxt, visitor);
+    kind.walk(*span, *id, vis, ctxt, visitor);
     visit_lazy_tts(visitor, tokens);
     visitor.visit_span(span);
 }
@@ -1525,38 +1541,37 @@ impl WalkItemKind for ForeignItemKind {
         &mut self,
         span: Span,
         id: NodeId,
-        ident: &mut Ident,
         visibility: &mut Visibility,
         _ctxt: Self::Ctxt,
         visitor: &mut impl MutVisitor,
     ) {
         match self {
             ForeignItemKind::Static(box StaticItem {
+                ident,
                 ty,
                 mutability: _,
                 expr,
                 safety: _,
                 define_opaque,
             }) => {
+                visitor.visit_ident(ident);
                 visitor.visit_ty(ty);
                 visit_opt(expr, |expr| visitor.visit_expr(expr));
                 walk_define_opaques(visitor, define_opaque);
             }
             ForeignItemKind::Fn(func) => {
-                visitor.visit_fn(
-                    FnKind::Fn(FnCtxt::Foreign, ident, visibility, &mut *func),
-                    span,
-                    id,
-                );
+                visitor.visit_fn(FnKind::Fn(FnCtxt::Foreign, visibility, &mut *func), span, id);
             }
             ForeignItemKind::TyAlias(box TyAlias {
                 defaultness,
+                ident,
                 generics,
                 where_clauses,
                 bounds,
                 ty,
             }) => {
                 visit_defaultness(visitor, defaultness);
+                visitor.visit_ident(ident);
                 visitor.visit_generics(generics);
                 visit_bounds(visitor, bounds, BoundKind::Bound);
                 visit_opt(ty, |ty| visitor.visit_ty(ty));
@@ -1984,8 +1999,7 @@ impl DummyAstNode for Item {
                 span: Default::default(),
                 tokens: Default::default(),
             },
-            ident: Ident::dummy(),
-            kind: ItemKind::ExternCrate(None),
+            kind: ItemKind::ExternCrate(None, Ident::dummy()),
             tokens: Default::default(),
         }
     }
@@ -2052,7 +2066,7 @@ impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNo
 #[derive(Debug)]
 pub enum FnKind<'a> {
     /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
-    Fn(FnCtxt, &'a mut Ident, &'a mut Visibility, &'a mut Fn),
+    Fn(FnCtxt, &'a mut Visibility, &'a mut Fn),
 
     /// E.g., `|x, y| body`.
     Closure(
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 6e6f0f1b266..d57a369eebf 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -198,16 +198,17 @@ impl Lit {
         }
     }
 
-    /// Keep this in sync with `Token::can_begin_literal_maybe_minus` excluding unary negation.
+    /// Keep this in sync with `Token::can_begin_literal_maybe_minus` and
+    /// `Parser::eat_token_lit` (excluding unary negation).
     pub fn from_token(token: &Token) -> Option<Lit> {
         match token.uninterpolate().kind {
             Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)),
             Literal(token_lit) => Some(token_lit),
-            Interpolated(ref nt)
-                if let NtExpr(expr) | NtLiteral(expr) = &**nt
-                    && let ast::ExprKind::Lit(token_lit) = expr.kind =>
-            {
-                Some(token_lit)
+            OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
+                MetaVarKind::Literal | MetaVarKind::Expr { .. },
+            ))) => {
+                // Unreachable with the current test suite.
+                panic!("from_token metavar");
             }
             _ => None,
         }
@@ -447,8 +448,9 @@ pub enum TokenKind {
 
     /// Identifier token.
     /// Do not forget about `NtIdent` when you want to match on identifiers.
-    /// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
-    /// treat regular and interpolated identifiers in the same way.
+    /// It's recommended to use `Token::{ident,uninterpolate}` and
+    /// `Parser::token_uninterpolated_span` to treat regular and interpolated
+    /// identifiers in the same way.
     Ident(Symbol, IdentIsRaw),
     /// This identifier (and its span) is the identifier passed to the
     /// declarative macro. The span in the surrounding `Token` is the span of
@@ -457,8 +459,9 @@ pub enum TokenKind {
 
     /// Lifetime identifier token.
     /// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
-    /// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
-    /// treat regular and interpolated lifetime identifiers in the same way.
+    /// It's recommended to use `Token::{ident,uninterpolate}` and
+    /// `Parser::token_uninterpolated_span` to treat regular and interpolated
+    /// identifiers in the same way.
     Lifetime(Symbol, IdentIsRaw),
     /// This identifier (and its span) is the lifetime passed to the
     /// declarative macro. The span in the surrounding `Token` is the span of
@@ -584,20 +587,6 @@ impl Token {
         Token::new(Ident(ident.name, ident.is_raw_guess().into()), ident.span)
     }
 
-    /// For interpolated tokens, returns a span of the fragment to which the interpolated
-    /// token refers. For all other tokens this is just a regular span.
-    /// It is particularly important to use this for identifiers and lifetimes
-    /// for which spans affect name resolution and edition checks.
-    /// Note that keywords are also identifiers, so they should use this
-    /// if they keep spans or perform edition checks.
-    pub fn uninterpolated_span(&self) -> Span {
-        match self.kind {
-            NtIdent(ident, _) | NtLifetime(ident, _) => ident.span,
-            Interpolated(ref nt) => nt.use_span(),
-            _ => self.span,
-        }
-    }
-
     pub fn is_range_separator(&self) -> bool {
         [DotDot, DotDotDot, DotDotEq].contains(&self.kind)
     }
@@ -642,12 +631,7 @@ impl Token {
             PathSep                           | // global path
             Lifetime(..)                      | // labeled loop
             Pound                             => true, // expression attributes
-            Interpolated(ref nt) =>
-                matches!(&**nt,
-                    NtBlock(..)   |
-                    NtExpr(..)    |
-                    NtLiteral(..)
-                ),
+            Interpolated(ref nt) => matches!(&**nt, NtBlock(..)),
             OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
                 MetaVarKind::Block |
                 MetaVarKind::Expr { .. } |
@@ -677,11 +661,6 @@ impl Token {
             Lt |                                 // path (UFCS constant)
             Shl => true,                         // path (double UFCS)
             Or => matches!(pat_kind, PatWithOr), // leading vert `|` or-pattern
-            Interpolated(nt) =>
-                matches!(&**nt,
-                    | NtExpr(..)
-                    | NtLiteral(..)
-                ),
             OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
                 MetaVarKind::Expr { .. } |
                 MetaVarKind::Literal |
@@ -724,7 +703,7 @@ impl Token {
         match self.kind {
             OpenDelim(Delimiter::Brace) | Literal(..) | Minus => true,
             Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
-            Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
+            Interpolated(ref nt) => matches!(&**nt, NtBlock(..)),
             OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
                 MetaVarKind::Expr { .. } | MetaVarKind::Block | MetaVarKind::Literal,
             ))) => true,
@@ -768,22 +747,12 @@ impl Token {
     ///
     /// In other words, would this token be a valid start of `parse_literal_maybe_minus`?
     ///
-    /// Keep this in sync with and `Lit::from_token`, excluding unary negation.
+    /// Keep this in sync with `Lit::from_token` and `Parser::eat_token_lit`
+    /// (excluding unary negation).
     pub fn can_begin_literal_maybe_minus(&self) -> bool {
         match self.uninterpolate().kind {
             Literal(..) | Minus => true,
             Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
-            Interpolated(ref nt) => match &**nt {
-                NtLiteral(_) => true,
-                NtExpr(e) => match &e.kind {
-                    ast::ExprKind::Lit(_) => true,
-                    ast::ExprKind::Unary(ast::UnOp::Neg, e) => {
-                        matches!(&e.kind, ast::ExprKind::Lit(_))
-                    }
-                    _ => false,
-                },
-                _ => false,
-            },
             OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
                 MetaVarKind::Literal => true,
                 MetaVarKind::Expr { can_begin_literal_maybe_minus, .. } => {
@@ -798,14 +767,6 @@ impl Token {
     pub fn can_begin_string_literal(&self) -> bool {
         match self.uninterpolate().kind {
             Literal(..) => true,
-            Interpolated(ref nt) => match &**nt {
-                NtLiteral(_) => true,
-                NtExpr(e) => match &e.kind {
-                    ast::ExprKind::Lit(_) => true,
-                    _ => false,
-                },
-                _ => false,
-            },
             OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
                 MetaVarKind::Literal => true,
                 MetaVarKind::Expr { can_begin_string_literal, .. } => can_begin_string_literal,
@@ -869,12 +830,17 @@ impl Token {
 
     /// Is this a pre-parsed expression dropped into the token stream
     /// (which happens while parsing the result of macro expansion)?
-    pub fn is_whole_expr(&self) -> bool {
+    pub fn is_metavar_expr(&self) -> bool {
         #[allow(irrefutable_let_patterns)] // FIXME: temporary
         if let Interpolated(nt) = &self.kind
-            && let NtExpr(_) | NtLiteral(_) | NtBlock(_) = &**nt
+            && let NtBlock(_) = &**nt
         {
             true
+        } else if matches!(
+            self.is_metavar_seq(),
+            Some(MetaVarKind::Expr { .. } | MetaVarKind::Literal | MetaVarKind::Path)
+        ) {
+            true
         } else {
             matches!(self.is_metavar_seq(), Some(MetaVarKind::Path))
         }
@@ -882,6 +848,7 @@ impl Token {
 
     /// Is the token an interpolated block (`$b:block`)?
     pub fn is_whole_block(&self) -> bool {
+        #[allow(irrefutable_let_patterns)] // FIXME: temporary
         if let Interpolated(nt) = &self.kind
             && let NtBlock(..) = &**nt
         {
@@ -1100,8 +1067,6 @@ pub enum NtExprKind {
 /// For interpolation during macro expansion.
 pub enum Nonterminal {
     NtBlock(P<ast::Block>),
-    NtExpr(P<ast::Expr>),
-    NtLiteral(P<ast::Expr>),
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
@@ -1191,15 +1156,12 @@ impl Nonterminal {
     pub fn use_span(&self) -> Span {
         match self {
             NtBlock(block) => block.span,
-            NtExpr(expr) | NtLiteral(expr) => expr.span,
         }
     }
 
     pub fn descr(&self) -> &'static str {
         match self {
             NtBlock(..) => "block",
-            NtExpr(..) => "expression",
-            NtLiteral(..) => "literal",
         }
     }
 }
@@ -1218,8 +1180,6 @@ impl fmt::Debug for Nonterminal {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             NtBlock(..) => f.pad("NtBlock(..)"),
-            NtExpr(..) => f.pad("NtExpr(..)"),
-            NtLiteral(..) => f.pad("NtLiteral(..)"),
         }
     }
 }
@@ -1242,7 +1202,7 @@ mod size_asserts {
     // tidy-alphabetical-start
     static_assert_size!(Lit, 12);
     static_assert_size!(LitKind, 2);
-    static_assert_size!(Nonterminal, 16);
+    static_assert_size!(Nonterminal, 8);
     static_assert_size!(Token, 24);
     static_assert_size!(TokenKind, 16);
     // tidy-alphabetical-end
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index bdd244be6d1..fb331e74aeb 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -233,35 +233,52 @@ fn attrs_and_tokens_to_token_trees(
 
     // Insert inner attribute tokens.
     if !inner_attrs.is_empty() {
-        let mut found = false;
-        // Check the last two trees (to account for a trailing semi)
-        for tree in res.iter_mut().rev().take(2) {
-            if let TokenTree::Delimited(span, spacing, delim, delim_tokens) = tree {
-                // Inner attributes are only supported on extern blocks, functions,
-                // impls, and modules. All of these have their inner attributes
-                // placed at the beginning of the rightmost outermost braced group:
-                // e.g. fn foo() { #![my_attr] }
-                //
-                // Therefore, we can insert them back into the right location
-                // without needing to do any extra position tracking.
-                //
-                // Note: Outline modules are an exception - they can
-                // have attributes like `#![my_attr]` at the start of a file.
-                // Support for custom attributes in this position is not
-                // properly implemented - we always synthesize fake tokens,
-                // so we never reach this code.
+        let found = insert_inner_attrs(inner_attrs, res);
+        assert!(found, "Failed to find trailing delimited group in: {res:?}");
+    }
+
+    // Inner attributes are only supported on blocks, functions, impls, and
+    // modules. All of these have their inner attributes placed at the
+    // beginning of the rightmost outermost braced group:
+    // e.g. `fn foo() { #![my_attr] }`. (Note: the braces may be within
+    // invisible delimiters.)
+    //
+    // Therefore, we can insert them back into the right location without
+    // needing to do any extra position tracking.
+    //
+    // Note: Outline modules are an exception - they can have attributes like
+    // `#![my_attr]` at the start of a file. Support for custom attributes in
+    // this position is not properly implemented - we always synthesize fake
+    // tokens, so we never reach this code.
+    fn insert_inner_attrs(inner_attrs: &[Attribute], tts: &mut Vec<TokenTree>) -> bool {
+        for tree in tts.iter_mut().rev() {
+            if let TokenTree::Delimited(span, spacing, Delimiter::Brace, stream) = tree {
+                // Found it: the rightmost, outermost braced group.
                 let mut tts = vec![];
                 for inner_attr in inner_attrs {
                     tts.extend(inner_attr.token_trees());
                 }
-                tts.extend(delim_tokens.0.iter().cloned());
+                tts.extend(stream.0.iter().cloned());
                 let stream = TokenStream::new(tts);
-                *tree = TokenTree::Delimited(*span, *spacing, *delim, stream);
-                found = true;
-                break;
+                *tree = TokenTree::Delimited(*span, *spacing, Delimiter::Brace, stream);
+                return true;
+            } else if let TokenTree::Delimited(span, spacing, Delimiter::Invisible(src), stream) =
+                tree
+            {
+                // Recurse inside invisible delimiters.
+                let mut vec: Vec<_> = stream.iter().cloned().collect();
+                if insert_inner_attrs(inner_attrs, &mut vec) {
+                    *tree = TokenTree::Delimited(
+                        *span,
+                        *spacing,
+                        Delimiter::Invisible(*src),
+                        TokenStream::new(vec),
+                    );
+                    return true;
+                }
             }
         }
-        assert!(found, "Failed to find trailing delimited group in: {res:?}");
+        false
     }
 }
 
@@ -462,7 +479,6 @@ impl TokenStream {
     pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
         match nt {
             Nonterminal::NtBlock(block) => TokenStream::from_ast(block),
-            Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),
         }
     }
 
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 98b1fc52ed7..1e5f414fae1 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -1,6 +1,6 @@
 use rustc_span::kw;
 
-use crate::ast::{self, BinOpKind, RangeLimits};
+use crate::ast::{self, AssignOpKind, BinOpKind, RangeLimits};
 use crate::token::{self, Token};
 
 /// Associative operator.
@@ -9,7 +9,7 @@ pub enum AssocOp {
     /// A binary op.
     Binary(BinOpKind),
     /// `?=` where ? is one of the assignable BinOps
-    AssignOp(BinOpKind),
+    AssignOp(AssignOpKind),
     /// `=`
     Assign,
     /// `as`
@@ -44,16 +44,16 @@ impl AssocOp {
             token::Or => Some(Binary(BinOpKind::BitOr)),
             token::Shl => Some(Binary(BinOpKind::Shl)),
             token::Shr => Some(Binary(BinOpKind::Shr)),
-            token::PlusEq => Some(AssignOp(BinOpKind::Add)),
-            token::MinusEq => Some(AssignOp(BinOpKind::Sub)),
-            token::StarEq => Some(AssignOp(BinOpKind::Mul)),
-            token::SlashEq => Some(AssignOp(BinOpKind::Div)),
-            token::PercentEq => Some(AssignOp(BinOpKind::Rem)),
-            token::CaretEq => Some(AssignOp(BinOpKind::BitXor)),
-            token::AndEq => Some(AssignOp(BinOpKind::BitAnd)),
-            token::OrEq => Some(AssignOp(BinOpKind::BitOr)),
-            token::ShlEq => Some(AssignOp(BinOpKind::Shl)),
-            token::ShrEq => Some(AssignOp(BinOpKind::Shr)),
+            token::PlusEq => Some(AssignOp(AssignOpKind::AddAssign)),
+            token::MinusEq => Some(AssignOp(AssignOpKind::SubAssign)),
+            token::StarEq => Some(AssignOp(AssignOpKind::MulAssign)),
+            token::SlashEq => Some(AssignOp(AssignOpKind::DivAssign)),
+            token::PercentEq => Some(AssignOp(AssignOpKind::RemAssign)),
+            token::CaretEq => Some(AssignOp(AssignOpKind::BitXorAssign)),
+            token::AndEq => Some(AssignOp(AssignOpKind::BitAndAssign)),
+            token::OrEq => Some(AssignOp(AssignOpKind::BitOrAssign)),
+            token::ShlEq => Some(AssignOp(AssignOpKind::ShlAssign)),
+            token::ShrEq => Some(AssignOp(AssignOpKind::ShrAssign)),
             token::Lt => Some(Binary(BinOpKind::Lt)),
             token::Le => Some(Binary(BinOpKind::Le)),
             token::Ge => Some(Binary(BinOpKind::Ge)),
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 2716601ca4f..1ef92ff8898 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -66,7 +66,7 @@ impl BoundKind {
 #[derive(Copy, Clone, Debug)]
 pub enum FnKind<'a> {
     /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
-    Fn(FnCtxt, &'a Ident, &'a Visibility, &'a Fn),
+    Fn(FnCtxt, &'a Visibility, &'a Fn),
 
     /// E.g., `|x, y| body`.
     Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr),
@@ -75,21 +75,21 @@ pub enum FnKind<'a> {
 impl<'a> FnKind<'a> {
     pub fn header(&self) -> Option<&'a FnHeader> {
         match *self {
-            FnKind::Fn(_, _, _, Fn { sig, .. }) => Some(&sig.header),
+            FnKind::Fn(_, _, Fn { sig, .. }) => Some(&sig.header),
             FnKind::Closure(..) => None,
         }
     }
 
     pub fn ident(&self) -> Option<&Ident> {
         match self {
-            FnKind::Fn(_, ident, ..) => Some(ident),
+            FnKind::Fn(_, _, Fn { ident, .. }) => Some(ident),
             _ => None,
         }
     }
 
     pub fn decl(&self) -> &'a FnDecl {
         match self {
-            FnKind::Fn(_, _, _, Fn { sig, .. }) => &sig.decl,
+            FnKind::Fn(_, _, Fn { sig, .. }) => &sig.decl,
             FnKind::Closure(_, _, decl, _) => decl,
         }
     }
@@ -118,7 +118,6 @@ pub trait WalkItemKind {
         &'a self,
         span: Span,
         id: NodeId,
-        ident: &'a Ident,
         visibility: &'a Visibility,
         ctxt: Self::Ctxt,
         visitor: &mut V,
@@ -364,63 +363,72 @@ impl WalkItemKind for ItemKind {
         &'a self,
         span: Span,
         id: NodeId,
-        ident: &'a Ident,
         vis: &'a Visibility,
         _ctxt: Self::Ctxt,
         visitor: &mut V,
     ) -> V::Result {
         match self {
-            ItemKind::ExternCrate(_rename) => {}
+            ItemKind::ExternCrate(_rename, ident) => try_visit!(visitor.visit_ident(ident)),
             ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
             ItemKind::Static(box StaticItem {
+                ident,
                 ty,
                 safety: _,
                 mutability: _,
                 expr,
                 define_opaque,
             }) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
                 try_visit!(walk_define_opaques(visitor, define_opaque));
             }
             ItemKind::Const(box ConstItem {
                 defaultness: _,
+                ident,
                 generics,
                 ty,
                 expr,
                 define_opaque,
             }) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
                 try_visit!(walk_define_opaques(visitor, define_opaque));
             }
             ItemKind::Fn(func) => {
-                let kind = FnKind::Fn(FnCtxt::Free, ident, vis, &*func);
+                let kind = FnKind::Fn(FnCtxt::Free, vis, &*func);
                 try_visit!(visitor.visit_fn(kind, span, id));
             }
-            ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
-                ModKind::Loaded(items, _inline, _inner_span, _) => {
-                    walk_list!(visitor, visit_item, items);
+            ItemKind::Mod(_unsafety, ident, mod_kind) => {
+                try_visit!(visitor.visit_ident(ident));
+                match mod_kind {
+                    ModKind::Loaded(items, _inline, _inner_span, _) => {
+                        walk_list!(visitor, visit_item, items);
+                    }
+                    ModKind::Unloaded => {}
                 }
-                ModKind::Unloaded => {}
-            },
+            }
             ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
                 walk_list!(visitor, visit_foreign_item, items);
             }
             ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
             ItemKind::TyAlias(box TyAlias {
                 generics,
+                ident,
                 bounds,
                 ty,
                 defaultness: _,
                 where_clauses: _,
             }) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
                 visit_opt!(visitor, visit_ty, ty);
             }
-            ItemKind::Enum(enum_definition, generics) => {
+            ItemKind::Enum(ident, enum_definition, generics) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 try_visit!(visitor.visit_enum_def(enum_definition));
             }
@@ -444,32 +452,47 @@ impl WalkItemKind for ItemKind {
                     AssocCtxt::Impl { of_trait: of_trait.is_some() }
                 );
             }
-            ItemKind::Struct(struct_definition, generics)
-            | ItemKind::Union(struct_definition, generics) => {
+            ItemKind::Struct(ident, struct_definition, generics)
+            | ItemKind::Union(ident, struct_definition, generics) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 try_visit!(visitor.visit_variant_data(struct_definition));
             }
-            ItemKind::Trait(box Trait { safety: _, is_auto: _, generics, bounds, items }) => {
+            ItemKind::Trait(box Trait {
+                safety: _,
+                is_auto: _,
+                ident,
+                generics,
+                bounds,
+                items,
+            }) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
                 walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
             }
-            ItemKind::TraitAlias(generics, bounds) => {
+            ItemKind::TraitAlias(ident, generics, bounds) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
             }
             ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
-            ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, id)),
+            ItemKind::MacroDef(ident, ts) => {
+                try_visit!(visitor.visit_ident(ident));
+                try_visit!(visitor.visit_mac_def(ts, id))
+            }
             ItemKind::Delegation(box Delegation {
                 id,
                 qself,
                 path,
+                ident,
                 rename,
                 body,
                 from_glob: _,
             }) => {
                 try_visit!(visitor.visit_qself(qself));
                 try_visit!(visitor.visit_path(path, *id));
+                try_visit!(visitor.visit_ident(ident));
                 visit_opt!(visitor, visit_ident, rename);
                 visit_opt!(visitor, visit_block, body);
             }
@@ -743,34 +766,37 @@ impl WalkItemKind for ForeignItemKind {
         &'a self,
         span: Span,
         id: NodeId,
-        ident: &'a Ident,
         vis: &'a Visibility,
         _ctxt: Self::Ctxt,
         visitor: &mut V,
     ) -> V::Result {
         match self {
             ForeignItemKind::Static(box StaticItem {
+                ident,
                 ty,
                 mutability: _,
                 expr,
                 safety: _,
                 define_opaque,
             }) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
                 try_visit!(walk_define_opaques(visitor, define_opaque));
             }
             ForeignItemKind::Fn(func) => {
-                let kind = FnKind::Fn(FnCtxt::Foreign, ident, vis, &*func);
+                let kind = FnKind::Fn(FnCtxt::Foreign, vis, &*func);
                 try_visit!(visitor.visit_fn(kind, span, id));
             }
             ForeignItemKind::TyAlias(box TyAlias {
                 generics,
+                ident,
                 bounds,
                 ty,
                 defaultness: _,
                 where_clauses: _,
             }) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
                 visit_opt!(visitor, visit_ty, ty);
@@ -917,10 +943,10 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
     match kind {
         FnKind::Fn(
             _ctxt,
-            _ident,
             _vis,
             Fn {
                 defaultness: _,
+                ident,
                 sig: FnSig { header, decl, span: _ },
                 generics,
                 contract,
@@ -928,7 +954,8 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
                 define_opaque,
             },
         ) => {
-            // Identifier and visibility are visited as a part of the item.
+            // Visibility is visited as a part of the item.
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_fn_header(header));
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_fn_decl(decl));
@@ -952,7 +979,6 @@ impl WalkItemKind for AssocItemKind {
         &'a self,
         span: Span,
         id: NodeId,
-        ident: &'a Ident,
         vis: &'a Visibility,
         ctxt: Self::Ctxt,
         visitor: &mut V,
@@ -960,28 +986,32 @@ impl WalkItemKind for AssocItemKind {
         match self {
             AssocItemKind::Const(box ConstItem {
                 defaultness: _,
+                ident,
                 generics,
                 ty,
                 expr,
                 define_opaque,
             }) => {
+                try_visit!(visitor.visit_ident(ident));
                 try_visit!(visitor.visit_generics(generics));
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
                 try_visit!(walk_define_opaques(visitor, define_opaque));
             }
             AssocItemKind::Fn(func) => {
-                let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, vis, &*func);
+                let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), vis, &*func);
                 try_visit!(visitor.visit_fn(kind, span, id));
             }
             AssocItemKind::Type(box TyAlias {
                 generics,
+                ident,
                 bounds,
                 ty,
                 defaultness: _,
                 where_clauses: _,
             }) => {
                 try_visit!(visitor.visit_generics(generics));
+                try_visit!(visitor.visit_ident(ident));
                 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
                 visit_opt!(visitor, visit_ty, ty);
             }
@@ -992,12 +1022,14 @@ impl WalkItemKind for AssocItemKind {
                 id,
                 qself,
                 path,
+                ident,
                 rename,
                 body,
                 from_glob: _,
             }) => {
                 try_visit!(visitor.visit_qself(qself));
                 try_visit!(visitor.visit_path(path, *id));
+                try_visit!(visitor.visit_ident(ident));
                 visit_opt!(visitor, visit_ident, rename);
                 visit_opt!(visitor, visit_block, body);
             }
@@ -1039,11 +1071,10 @@ fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
     item: &'a Item<K>,
     ctxt: K::Ctxt,
 ) -> V::Result {
-    let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item;
+    let Item { id, span, vis, attrs, kind, tokens: _ } = item;
     walk_list!(visitor, visit_attribute, attrs);
     try_visit!(visitor.visit_vis(vis));
-    try_visit!(visitor.visit_ident(ident));
-    try_visit!(kind.walk(*span, *id, ident, vis, ctxt, visitor));
+    try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
     V::Result::output()
 }
 
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index f7640c602d6..9899ee03a51 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -56,6 +56,7 @@ use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt};
 pub(crate) struct DelegationResults<'hir> {
     pub body_id: hir::BodyId,
     pub sig: hir::FnSig<'hir>,
+    pub ident: Ident,
     pub generics: &'hir hir::Generics<'hir>,
 }
 
@@ -104,9 +105,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
                 let sig = self.lower_delegation_sig(sig_id, decl, span);
                 let body_id = self.lower_delegation_body(delegation, param_count, span);
-
+                let ident = self.lower_ident(delegation.ident);
                 let generics = self.lower_delegation_generics(span);
-                DelegationResults { body_id, sig, generics }
+                DelegationResults { body_id, sig, ident, generics }
             }
             Err(err) => self.generate_delegation_error(err, span),
         }
@@ -405,8 +406,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let header = self.generate_header_error();
         let sig = hir::FnSig { decl, header, span };
 
+        let ident = Ident::dummy();
         let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span)));
-        DelegationResults { generics, body_id, sig }
+        DelegationResults { ident, generics, body_id, sig }
     }
 
     fn generate_header_error(&self) -> hir::FnHeader {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 52291fdfb30..80bb1e8fc41 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -274,7 +274,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
                 ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span),
                 ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp(
-                    self.lower_binop(*op),
+                    self.lower_assign_op(*op),
                     self.lower_expr(el),
                     self.lower_expr(er),
                 ),
@@ -443,6 +443,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         Spanned { node: b.node, span: self.lower_span(b.span) }
     }
 
+    fn lower_assign_op(&mut self, a: AssignOp) -> AssignOp {
+        Spanned { node: a.node, span: self.lower_span(a.span) }
+    }
+
     fn lower_legacy_const_generics(
         &mut self,
         mut f: Expr,
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index 343895984ca..0de0319c667 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -323,14 +323,12 @@ fn make_count<'hir>(
 /// Generates
 ///
 /// ```text
-///     <core::fmt::rt::Placeholder::new(
-///         …usize, // position
-///         '…', // fill
-///         <core::fmt::rt::Alignment>::…, // alignment
-///         …u32, // flags
-///         <core::fmt::rt::Count::…>, // width
-///         <core::fmt::rt::Count::…>, // precision
-///     )
+///     <core::fmt::rt::Placeholder {
+///         position: …usize,
+///         flags: …u32,
+///         precision: <core::fmt::rt::Count::…>,
+///         width: <core::fmt::rt::Count::…>,
+///     }
 /// ```
 fn make_format_spec<'hir>(
     ctx: &mut LoweringContext<'_, 'hir>,
@@ -384,13 +382,13 @@ fn make_format_spec<'hir>(
     let flags = ctx.expr_u32(sp, flags);
     let precision = make_count(ctx, sp, precision, argmap);
     let width = make_count(ctx, sp, width, argmap);
-    let format_placeholder_new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
-        sp,
-        hir::LangItem::FormatPlaceholder,
-        sym::new,
-    ));
-    let args = ctx.arena.alloc_from_iter([position, flags, precision, width]);
-    ctx.expr_call_mut(sp, format_placeholder_new, args)
+    let position = ctx.expr_field(Ident::new(sym::position, sp), ctx.arena.alloc(position), sp);
+    let flags = ctx.expr_field(Ident::new(sym::flags, sp), ctx.arena.alloc(flags), sp);
+    let precision = ctx.expr_field(Ident::new(sym::precision, sp), ctx.arena.alloc(precision), sp);
+    let width = ctx.expr_field(Ident::new(sym::width, sp), ctx.arena.alloc(width), sp);
+    let placeholder = ctx.arena.alloc(hir::QPath::LangItem(hir::LangItem::FormatPlaceholder, sp));
+    let fields = ctx.arena.alloc_from_iter([position, flags, precision, width]);
+    ctx.expr(sp, hir::ExprKind::Struct(placeholder, fields, hir::StructTailExpr::None))
 }
 
 fn expand_format_args<'hir>(
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 43bf951eddc..958a6917dff 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -107,7 +107,6 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
     }
 
     fn lower_foreign_item(&mut self, item: &ForeignItem) {
-        debug_assert_ne!(item.ident.name, kw::Empty);
         self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
     }
 }
@@ -151,7 +150,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let vis_span = self.lower_span(i.vis.span);
         let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
         let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
-        let kind = self.lower_item_kind(i.span, i.id, hir_id, i.ident, attrs, vis_span, &i.kind);
+        let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
         let item = hir::Item {
             owner_id: hir_id.expect_owner(),
             kind,
@@ -166,41 +165,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
         span: Span,
         id: NodeId,
         hir_id: hir::HirId,
-        ident: Ident,
         attrs: &'hir [hir::Attribute],
         vis_span: Span,
         i: &ItemKind,
     ) -> hir::ItemKind<'hir> {
         match i {
-            ItemKind::ExternCrate(orig_name) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::ExternCrate(orig_name, ident) => {
+                let ident = self.lower_ident(*ident);
                 hir::ItemKind::ExternCrate(*orig_name, ident)
             }
             ItemKind::Use(use_tree) => {
-                debug_assert_eq!(ident.name, kw::Empty);
                 // Start with an empty prefix.
                 let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
 
                 self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
             }
             ItemKind::Static(box ast::StaticItem {
+                ident,
                 ty: t,
                 safety: _,
                 mutability: m,
                 expr: e,
                 define_opaque,
             }) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+                let ident = self.lower_ident(*ident);
                 let (ty, body_id) =
                     self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
                 self.lower_define_opaque(hir_id, define_opaque);
                 hir::ItemKind::Static(ident, ty, *m, body_id)
             }
-            ItemKind::Const(box ast::ConstItem { generics, ty, expr, define_opaque, .. }) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::Const(box ast::ConstItem {
+                ident,
+                generics,
+                ty,
+                expr,
+                define_opaque,
+                ..
+            }) => {
+                let ident = self.lower_ident(*ident);
                 let (generics, (ty, body_id)) = self.lower_generics(
                     generics,
                     id,
@@ -214,13 +216,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
             ItemKind::Fn(box Fn {
                 sig: FnSig { decl, header, span: fn_sig_span },
+                ident,
                 generics,
                 body,
                 contract,
                 define_opaque,
                 ..
             }) => {
-                debug_assert_ne!(ident.name, kw::Empty);
                 self.with_new_scopes(*fn_sig_span, |this| {
                     // Note: we don't need to change the return type from `T` to
                     // `impl Future<Output = T>` here because lower_body
@@ -248,7 +250,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         span: this.lower_span(*fn_sig_span),
                     };
                     this.lower_define_opaque(hir_id, define_opaque);
-                    let ident = this.lower_ident(ident);
+                    let ident = this.lower_ident(*ident);
                     hir::ItemKind::Fn {
                         ident,
                         sig,
@@ -258,9 +260,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     }
                 })
             }
-            ItemKind::Mod(_, mod_kind) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::Mod(_, ident, mod_kind) => {
+                let ident = self.lower_ident(*ident);
                 match mod_kind {
                     ModKind::Loaded(items, _, spans, _) => {
                         hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
@@ -268,24 +269,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
                 }
             }
-            ItemKind::ForeignMod(fm) => {
-                debug_assert_eq!(ident.name, kw::Empty);
-                hir::ItemKind::ForeignMod {
-                    abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
-                    items: self
-                        .arena
-                        .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
-                }
-            }
+            ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
+                abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
+                items: self
+                    .arena
+                    .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
+            },
             ItemKind::GlobalAsm(asm) => {
-                debug_assert_eq!(ident.name, kw::Empty);
                 let asm = self.lower_inline_asm(span, asm);
                 let fake_body =
                     self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
                 hir::ItemKind::GlobalAsm { asm, fake_body }
             }
-            ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
-                debug_assert_ne!(ident.name, kw::Empty);
+            ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
                 // We lower
                 //
                 // type Foo = impl Trait
@@ -294,7 +290,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 //
                 // type Foo = Foo1
                 // opaque type Foo1: Trait
-                let ident = self.lower_ident(ident);
+                let ident = self.lower_ident(*ident);
                 let mut generics = generics.clone();
                 add_ty_alias_where_clause(&mut generics, *where_clauses, true);
                 let (generics, ty) = self.lower_generics(
@@ -322,9 +318,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 hir::ItemKind::TyAlias(ident, ty, generics)
             }
-            ItemKind::Enum(enum_definition, generics) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::Enum(ident, enum_definition, generics) => {
+                let ident = self.lower_ident(*ident);
                 let (generics, variants) = self.lower_generics(
                     generics,
                     id,
@@ -337,9 +332,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics)
             }
-            ItemKind::Struct(struct_def, generics) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::Struct(ident, struct_def, generics) => {
+                let ident = self.lower_ident(*ident);
                 let (generics, struct_def) = self.lower_generics(
                     generics,
                     id,
@@ -348,9 +342,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 hir::ItemKind::Struct(ident, struct_def, generics)
             }
-            ItemKind::Union(vdata, generics) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::Union(ident, vdata, generics) => {
+                let ident = self.lower_ident(*ident);
                 let (generics, vdata) = self.lower_generics(
                     generics,
                     id,
@@ -369,7 +362,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 self_ty: ty,
                 items: impl_items,
             }) => {
-                debug_assert_eq!(ident.name, kw::Empty);
                 // Lower the "impl header" first. This ordering is important
                 // for in-band lifetimes! Consider `'a` here:
                 //
@@ -435,9 +427,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     items: new_impl_items,
                 }))
             }
-            ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::Trait(box Trait { is_auto, safety, ident, generics, bounds, items }) => {
+                let ident = self.lower_ident(*ident);
                 let (generics, (safety, items, bounds)) = self.lower_generics(
                     generics,
                     id,
@@ -456,9 +447,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
             }
-            ItemKind::TraitAlias(generics, bounds) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::TraitAlias(ident, generics, bounds) => {
+                let ident = self.lower_ident(*ident);
                 let (generics, bounds) = self.lower_generics(
                     generics,
                     id,
@@ -472,9 +462,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 hir::ItemKind::TraitAlias(ident, generics, bounds)
             }
-            ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
+            ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
+                let ident = self.lower_ident(*ident);
                 let body = P(self.lower_delim_args(body));
                 let def_id = self.local_def_id(id);
                 let def_kind = self.tcx.def_kind(def_id);
@@ -488,11 +477,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 hir::ItemKind::Macro(ident, macro_def, macro_kind)
             }
             ItemKind::Delegation(box delegation) => {
-                debug_assert_ne!(ident.name, kw::Empty);
-                let ident = self.lower_ident(ident);
                 let delegation_results = self.lower_delegation(delegation, id, false);
                 hir::ItemKind::Fn {
-                    ident,
+                    ident: delegation_results.ident,
                     sig: delegation_results.sig,
                     generics: delegation_results.generics,
                     body: delegation_results.body_id,
@@ -649,61 +636,61 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
         let owner_id = hir_id.expect_owner();
         let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
-        let item = hir::ForeignItem {
-            owner_id,
-            ident: self.lower_ident(i.ident),
-            kind: match &i.kind {
-                ForeignItemKind::Fn(box Fn { sig, generics, define_opaque, .. }) => {
-                    let fdec = &sig.decl;
-                    let itctx = ImplTraitContext::Universal;
-                    let (generics, (decl, fn_args)) =
-                        self.lower_generics(generics, i.id, itctx, |this| {
-                            (
-                                // Disallow `impl Trait` in foreign items.
-                                this.lower_fn_decl(
-                                    fdec,
-                                    i.id,
-                                    sig.span,
-                                    FnDeclKind::ExternFn,
-                                    None,
-                                ),
-                                this.lower_fn_params_to_names(fdec),
-                            )
-                        });
+        let (ident, kind) = match &i.kind {
+            ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
+                let fdec = &sig.decl;
+                let itctx = ImplTraitContext::Universal;
+                let (generics, (decl, fn_args)) =
+                    self.lower_generics(generics, i.id, itctx, |this| {
+                        (
+                            // Disallow `impl Trait` in foreign items.
+                            this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
+                            this.lower_fn_params_to_names(fdec),
+                        )
+                    });
 
-                    // Unmarked safety in unsafe block defaults to unsafe.
-                    let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
+                // Unmarked safety in unsafe block defaults to unsafe.
+                let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
 
-                    if define_opaque.is_some() {
-                        self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
-                    }
+                if define_opaque.is_some() {
+                    self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
+                }
 
+                (
+                    ident,
                     hir::ForeignItemKind::Fn(
                         hir::FnSig { header, decl, span: self.lower_span(sig.span) },
                         fn_args,
                         generics,
-                    )
+                    ),
+                )
+            }
+            ForeignItemKind::Static(box StaticItem {
+                ident,
+                ty,
+                mutability,
+                expr: _,
+                safety,
+                define_opaque,
+            }) => {
+                let ty =
+                    self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
+                let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
+                if define_opaque.is_some() {
+                    self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
                 }
-                ForeignItemKind::Static(box StaticItem {
-                    ty,
-                    mutability,
-                    expr: _,
-                    safety,
-                    define_opaque,
-                }) => {
-                    let ty = self
-                        .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
-                    let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
-
-                    if define_opaque.is_some() {
-                        self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
-                    }
+                (ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
+            }
+            ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
+                (ident, hir::ForeignItemKind::Type)
+            }
+            ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
+        };
 
-                    hir::ForeignItemKind::Static(ty, *mutability, safety)
-                }
-                ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
-                ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
-            },
+        let item = hir::ForeignItem {
+            owner_id,
+            ident: self.lower_ident(*ident),
+            kind,
             vis_span: self.lower_span(i.vis.span),
             span: self.lower_span(i.span),
         };
@@ -713,7 +700,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
         hir::ForeignItemRef {
             id: hir::ForeignItemId { owner_id: self.owner_id(i.id) },
-            ident: self.lower_ident(i.ident),
+            // `unwrap` is safe because `ForeignItemKind::MacCall` is the only foreign item kind
+            // without an identifier and it cannot reach here.
+            ident: self.lower_ident(i.kind.ident().unwrap()),
             span: self.lower_span(i.span),
         }
     }
@@ -800,13 +789,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
-        debug_assert_ne!(i.ident.name, kw::Empty);
         let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
         let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
         let trait_item_def_id = hir_id.expect_owner();
 
-        let (generics, kind, has_default) = match &i.kind {
-            AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => {
+        let (ident, generics, kind, has_default) = match &i.kind {
+            AssocItemKind::Const(box ConstItem {
+                ident,
+                generics,
+                ty,
+                expr,
+                define_opaque,
+                ..
+            }) => {
                 let (generics, kind) = self.lower_generics(
                     generics,
                     i.id,
@@ -831,9 +826,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     }
                 }
 
-                (generics, kind, expr.is_some())
+                (*ident, generics, kind, expr.is_some())
             }
-            AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => {
+            AssocItemKind::Fn(box Fn {
+                sig, ident, generics, body: None, define_opaque, ..
+            }) => {
                 // FIXME(contracts): Deny contract here since it won't apply to
                 // any impl method or callees.
                 let names = self.lower_fn_params_to_names(&sig.decl);
@@ -851,10 +848,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         "only trait methods with default bodies can define opaque types",
                     );
                 }
-                (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
+                (
+                    *ident,
+                    generics,
+                    hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)),
+                    false,
+                )
             }
             AssocItemKind::Fn(box Fn {
                 sig,
+                ident,
                 generics,
                 body: Some(body),
                 contract,
@@ -880,9 +883,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     attrs,
                 );
                 self.lower_define_opaque(hir_id, &define_opaque);
-                (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
+                (
+                    *ident,
+                    generics,
+                    hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
+                    true,
+                )
             }
-            AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => {
+            AssocItemKind::Type(box TyAlias {
+                ident, generics, where_clauses, bounds, ty, ..
+            }) => {
                 let mut generics = generics.clone();
                 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
                 let (generics, kind) = self.lower_generics(
@@ -905,7 +915,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         )
                     },
                 );
-                (generics, kind, ty.is_some())
+                (*ident, generics, kind, ty.is_some())
             }
             AssocItemKind::Delegation(box delegation) => {
                 let delegation_results = self.lower_delegation(delegation, i.id, false);
@@ -913,7 +923,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     delegation_results.sig,
                     hir::TraitFn::Provided(delegation_results.body_id),
                 );
-                (delegation_results.generics, item_kind, true)
+                (delegation.ident, delegation_results.generics, item_kind, true)
             }
             AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
                 panic!("macros should have been expanded by now")
@@ -922,7 +932,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         let item = hir::TraitItem {
             owner_id: trait_item_def_id,
-            ident: self.lower_ident(i.ident),
+            ident: self.lower_ident(ident),
             generics,
             kind,
             span: self.lower_span(i.span),
@@ -932,15 +942,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
-        let kind = match &i.kind {
-            AssocItemKind::Const(..) => hir::AssocItemKind::Const,
-            AssocItemKind::Type(..) => hir::AssocItemKind::Type,
-            AssocItemKind::Fn(box Fn { sig, .. }) => {
-                hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
+        let (ident, kind) = match &i.kind {
+            AssocItemKind::Const(box ConstItem { ident, .. }) => {
+                (*ident, hir::AssocItemKind::Const)
             }
-            AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
-                has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
-            },
+            AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type),
+            AssocItemKind::Fn(box Fn { ident, sig, .. }) => {
+                (*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() })
+            }
+            AssocItemKind::Delegation(box delegation) => (
+                delegation.ident,
+                hir::AssocItemKind::Fn {
+                    has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
+                },
+            ),
             AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
                 panic!("macros should have been expanded by now")
             }
@@ -948,7 +963,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
         hir::TraitItemRef {
             id,
-            ident: self.lower_ident(i.ident),
+            ident: self.lower_ident(ident),
             span: self.lower_span(i.span),
             kind,
         }
@@ -964,16 +979,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
         i: &AssocItem,
         is_in_trait_impl: bool,
     ) -> &'hir hir::ImplItem<'hir> {
-        debug_assert_ne!(i.ident.name, kw::Empty);
         // Since `default impl` is not yet implemented, this is always true in impls.
         let has_value = true;
         let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
         let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
         let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
 
-        let (generics, kind) = match &i.kind {
-            AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => self
-                .lower_generics(
+        let (ident, (generics, kind)) = match &i.kind {
+            AssocItemKind::Const(box ConstItem {
+                ident,
+                generics,
+                ty,
+                expr,
+                define_opaque,
+                ..
+            }) => (
+                *ident,
+                self.lower_generics(
                     generics,
                     i.id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
@@ -982,11 +1004,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
                         let body = this.lower_const_body(i.span, expr.as_deref());
                         this.lower_define_opaque(hir_id, &define_opaque);
-
                         hir::ImplItemKind::Const(ty, body)
                     },
                 ),
-            AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => {
+            ),
+            AssocItemKind::Fn(box Fn {
+                sig,
+                ident,
+                generics,
+                body,
+                contract,
+                define_opaque,
+                ..
+            }) => {
                 let body_id = self.lower_maybe_coroutine_body(
                     sig.span,
                     i.span,
@@ -1007,44 +1037,50 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 self.lower_define_opaque(hir_id, &define_opaque);
 
-                (generics, hir::ImplItemKind::Fn(sig, body_id))
+                (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
             }
-            AssocItemKind::Type(box TyAlias { generics, where_clauses, ty, .. }) => {
+            AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
                 let mut generics = generics.clone();
                 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
-                self.lower_generics(
-                    &generics,
-                    i.id,
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
-                    |this| match ty {
-                        None => {
-                            let guar = this.dcx().span_delayed_bug(
-                                i.span,
-                                "expected to lower associated type, but it was missing",
-                            );
-                            let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
-                            hir::ImplItemKind::Type(ty)
-                        }
-                        Some(ty) => {
-                            let ty = this.lower_ty(
-                                ty,
-                                ImplTraitContext::OpaqueTy {
-                                    origin: hir::OpaqueTyOrigin::TyAlias {
-                                        parent: this.local_def_id(i.id),
-                                        in_assoc_ty: true,
+                (
+                    *ident,
+                    self.lower_generics(
+                        &generics,
+                        i.id,
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                        |this| match ty {
+                            None => {
+                                let guar = this.dcx().span_delayed_bug(
+                                    i.span,
+                                    "expected to lower associated type, but it was missing",
+                                );
+                                let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
+                                hir::ImplItemKind::Type(ty)
+                            }
+                            Some(ty) => {
+                                let ty = this.lower_ty(
+                                    ty,
+                                    ImplTraitContext::OpaqueTy {
+                                        origin: hir::OpaqueTyOrigin::TyAlias {
+                                            parent: this.local_def_id(i.id),
+                                            in_assoc_ty: true,
+                                        },
                                     },
-                                },
-                            );
-                            hir::ImplItemKind::Type(ty)
-                        }
-                    },
+                                );
+                                hir::ImplItemKind::Type(ty)
+                            }
+                        },
+                    ),
                 )
             }
             AssocItemKind::Delegation(box delegation) => {
                 let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
                 (
-                    delegation_results.generics,
-                    hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
+                    delegation.ident,
+                    (
+                        delegation_results.generics,
+                        hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
+                    ),
                 )
             }
             AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
@@ -1054,7 +1090,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         let item = hir::ImplItem {
             owner_id: hir_id.expect_owner(),
-            ident: self.lower_ident(i.ident),
+            ident: self.lower_ident(ident),
             generics,
             kind,
             vis_span: self.lower_span(i.vis.span),
@@ -1067,7 +1103,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
         hir::ImplItemRef {
             id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
-            ident: self.lower_ident(i.ident),
+            // `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only
+            // assoc item kinds without an identifier and they cannot reach here.
+            ident: self.lower_ident(i.kind.ident().unwrap()),
             span: self.lower_span(i.span),
             kind: match &i.kind {
                 AssocItemKind::Const(..) => hir::AssocItemKind::Const,
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index da739b0e453..9916de8b7b1 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -47,14 +47,14 @@ enum SelfSemantic {
 }
 
 enum TraitOrTraitImpl {
-    Trait { span: Span, constness: Option<Span> },
-    TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: Span },
+    Trait { span: Span, constness_span: Option<Span> },
+    TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref_span: Span },
 }
 
 impl TraitOrTraitImpl {
     fn constness(&self) -> Option<Span> {
         match self {
-            Self::Trait { constness: Some(span), .. }
+            Self::Trait { constness_span: Some(span), .. }
             | Self::TraitImpl { constness: Const::Yes(span), .. } => Some(*span),
             _ => None,
         }
@@ -66,7 +66,7 @@ struct AstValidator<'a> {
     features: &'a Features,
 
     /// The span of the `extern` in an `extern { ... }` block, if any.
-    extern_mod: Option<Span>,
+    extern_mod_span: Option<Span>,
 
     outer_trait_or_trait_impl: Option<TraitOrTraitImpl>,
 
@@ -75,7 +75,7 @@ struct AstValidator<'a> {
     /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
     /// Nested `impl Trait` _is_ allowed in associated type position,
     /// e.g., `impl Iterator<Item = impl Debug>`.
-    outer_impl_trait: Option<Span>,
+    outer_impl_trait_span: Option<Span>,
 
     disallow_tilde_const: Option<TildeConstReason>,
 
@@ -96,17 +96,22 @@ impl<'a> AstValidator<'a> {
             trait_.map(|(constness, polarity, trait_ref)| TraitOrTraitImpl::TraitImpl {
                 constness,
                 polarity,
-                trait_ref: trait_ref.path.span,
+                trait_ref_span: trait_ref.path.span,
             }),
         );
         f(self);
         self.outer_trait_or_trait_impl = old;
     }
 
-    fn with_in_trait(&mut self, span: Span, constness: Option<Span>, f: impl FnOnce(&mut Self)) {
+    fn with_in_trait(
+        &mut self,
+        span: Span,
+        constness_span: Option<Span>,
+        f: impl FnOnce(&mut Self),
+    ) {
         let old = mem::replace(
             &mut self.outer_trait_or_trait_impl,
-            Some(TraitOrTraitImpl::Trait { span, constness }),
+            Some(TraitOrTraitImpl::Trait { span, constness_span }),
         );
         f(self);
         self.outer_trait_or_trait_impl = old;
@@ -170,10 +175,10 @@ impl<'a> AstValidator<'a> {
         Err(errors::WhereClauseBeforeTypeAlias { span, sugg })
     }
 
-    fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
-        let old = mem::replace(&mut self.outer_impl_trait, outer);
+    fn with_impl_trait(&mut self, outer_span: Option<Span>, f: impl FnOnce(&mut Self)) {
+        let old = mem::replace(&mut self.outer_impl_trait_span, outer_span);
         f(self);
-        self.outer_impl_trait = old;
+        self.outer_impl_trait_span = old;
     }
 
     // Mirrors `visit::walk_ty`, but tracks relevant state.
@@ -258,21 +263,22 @@ impl<'a> AstValidator<'a> {
             && let TraitOrTraitImpl::TraitImpl {
                 constness: Const::No,
                 polarity: ImplPolarity::Positive,
-                trait_ref,
+                trait_ref_span,
                 ..
             } = parent
         {
-            Some(trait_ref.shrink_to_lo())
+            Some(trait_ref_span.shrink_to_lo())
         } else {
             None
         };
 
-        let make_trait_const_sugg =
-            if const_trait_impl && let TraitOrTraitImpl::Trait { span, constness: None } = parent {
-                Some(span.shrink_to_lo())
-            } else {
-                None
-            };
+        let make_trait_const_sugg = if const_trait_impl
+            && let TraitOrTraitImpl::Trait { span, constness_span: None } = parent
+        {
+            Some(span.shrink_to_lo())
+        } else {
+            None
+        };
 
         let parent_constness = parent.constness();
         self.dcx().emit_err(errors::TraitFnConst {
@@ -448,13 +454,13 @@ impl<'a> AstValidator<'a> {
         check_where_clause(where_clauses.after);
     }
 
-    fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
-        let Some(body) = body else {
+    fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body_span: Option<Span>) {
+        let Some(body_span) = body_span else {
             return;
         };
         self.dcx().emit_err(errors::BodyInExtern {
             span: ident.span,
-            body,
+            body: body_span,
             block: self.current_extern_span(),
             kind,
         });
@@ -473,7 +479,7 @@ impl<'a> AstValidator<'a> {
     }
 
     fn current_extern_span(&self) -> Span {
-        self.sess.source_map().guess_head_span(self.extern_mod.unwrap())
+        self.sess.source_map().guess_head_span(self.extern_mod_span.unwrap())
     }
 
     /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
@@ -583,9 +589,10 @@ impl<'a> AstValidator<'a> {
         self.dcx().emit_err(errors::ModuleNonAscii { span: ident.span, name: ident.name });
     }
 
-    fn deny_generic_params(&self, generics: &Generics, ident: Span) {
+    fn deny_generic_params(&self, generics: &Generics, ident_span: Span) {
         if !generics.params.is_empty() {
-            self.dcx().emit_err(errors::AutoTraitGeneric { span: generics.span, ident });
+            self.dcx()
+                .emit_err(errors::AutoTraitGeneric { span: generics.span, ident: ident_span });
         }
     }
 
@@ -605,11 +612,11 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn deny_items(&self, trait_items: &[P<AssocItem>], ident: Span) {
+    fn deny_items(&self, trait_items: &[P<AssocItem>], ident_span: Span) {
         if !trait_items.is_empty() {
-            let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect();
+            let spans: Vec<_> = trait_items.iter().map(|i| i.kind.ident().unwrap().span).collect();
             let total = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span);
-            self.dcx().emit_err(errors::AutoTraitItems { spans, total, ident });
+            self.dcx().emit_err(errors::AutoTraitItems { spans, total, ident: ident_span });
         }
     }
 
@@ -694,7 +701,7 @@ impl<'a> AstValidator<'a> {
                 }
             }
             TyKind::ImplTrait(_, bounds) => {
-                if let Some(outer_impl_trait_sp) = self.outer_impl_trait {
+                if let Some(outer_impl_trait_sp) = self.outer_impl_trait_span {
                     self.dcx().emit_err(errors::NestedImplTrait {
                         span: ty.span,
                         outer: outer_impl_trait_sp,
@@ -727,6 +734,19 @@ impl<'a> AstValidator<'a> {
             )
         }
     }
+
+    // Used within `visit_item` for item kinds where we don't call `visit::walk_item`.
+    fn visit_attrs_vis(&mut self, attrs: &'a AttrVec, vis: &'a Visibility) {
+        walk_list!(self, visit_attribute, attrs);
+        self.visit_vis(vis);
+    }
+
+    // Used within `visit_item` for item kinds where we don't call `visit::walk_item`.
+    fn visit_attrs_vis_ident(&mut self, attrs: &'a AttrVec, vis: &'a Visibility, ident: &'a Ident) {
+        walk_list!(self, visit_attribute, attrs);
+        self.visit_vis(vis);
+        self.visit_ident(ident);
+    }
 }
 
 /// Checks that generic parameters are in the correct order,
@@ -817,8 +837,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             self.has_proc_macro_decls = true;
         }
 
-        if attr::contains_name(&item.attrs, sym::no_mangle) {
-            self.check_nomangle_item_asciionly(item.ident, item.span);
+        if let Some(ident) = item.kind.ident()
+            && attr::contains_name(&item.attrs, sym::no_mangle)
+        {
+            self.check_nomangle_item_asciionly(ident, item.span);
         }
 
         match &item.kind {
@@ -832,37 +854,33 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self_ty,
                 items,
             }) => {
-                self.with_in_trait_impl(Some((*constness, *polarity, t)), |this| {
-                    this.visibility_not_permitted(
-                        &item.vis,
-                        errors::VisibilityNotPermittedNote::TraitImpl,
-                    );
-                    if let TyKind::Dummy = self_ty.kind {
-                        // Abort immediately otherwise the `TyKind::Dummy` will reach HIR lowering,
-                        // which isn't allowed. Not a problem for this obscure, obsolete syntax.
-                        this.dcx().emit_fatal(errors::ObsoleteAuto { span: item.span });
-                    }
-                    if let (&Safety::Unsafe(span), &ImplPolarity::Negative(sp)) = (safety, polarity)
-                    {
-                        this.dcx().emit_err(errors::UnsafeNegativeImpl {
-                            span: sp.to(t.path.span),
-                            negative: sp,
-                            r#unsafe: span,
-                        });
-                    }
+                self.visit_attrs_vis(&item.attrs, &item.vis);
+                self.visibility_not_permitted(
+                    &item.vis,
+                    errors::VisibilityNotPermittedNote::TraitImpl,
+                );
+                if let TyKind::Dummy = self_ty.kind {
+                    // Abort immediately otherwise the `TyKind::Dummy` will reach HIR lowering,
+                    // which isn't allowed. Not a problem for this obscure, obsolete syntax.
+                    self.dcx().emit_fatal(errors::ObsoleteAuto { span: item.span });
+                }
+                if let (&Safety::Unsafe(span), &ImplPolarity::Negative(sp)) = (safety, polarity) {
+                    self.dcx().emit_err(errors::UnsafeNegativeImpl {
+                        span: sp.to(t.path.span),
+                        negative: sp,
+                        r#unsafe: span,
+                    });
+                }
 
-                    this.visit_vis(&item.vis);
-                    this.visit_ident(&item.ident);
-                    let disallowed = matches!(constness, Const::No)
-                        .then(|| TildeConstReason::TraitImpl { span: item.span });
-                    this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
-                    this.visit_trait_ref(t);
-                    this.visit_ty(self_ty);
+                let disallowed = matches!(constness, Const::No)
+                    .then(|| TildeConstReason::TraitImpl { span: item.span });
+                self.with_tilde_const(disallowed, |this| this.visit_generics(generics));
+                self.visit_trait_ref(t);
+                self.visit_ty(self_ty);
 
+                self.with_in_trait_impl(Some((*constness, *polarity, t)), |this| {
                     walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: true });
                 });
-                walk_list!(self, visit_attribute, &item.attrs);
-                return; // Avoid visiting again.
             }
             ItemKind::Impl(box Impl {
                 safety,
@@ -882,45 +900,49 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     only_trait,
                 };
 
-                self.with_in_trait_impl(None, |this| {
-                    this.visibility_not_permitted(
-                        &item.vis,
-                        errors::VisibilityNotPermittedNote::IndividualImplItems,
-                    );
-                    if let &Safety::Unsafe(span) = safety {
-                        this.dcx().emit_err(errors::InherentImplCannotUnsafe {
-                            span: self_ty.span,
-                            annotation_span: span,
-                            annotation: "unsafe",
-                            self_ty: self_ty.span,
-                        });
-                    }
-                    if let &ImplPolarity::Negative(span) = polarity {
-                        this.dcx().emit_err(error(span, "negative", false));
-                    }
-                    if let &Defaultness::Default(def_span) = defaultness {
-                        this.dcx().emit_err(error(def_span, "`default`", true));
-                    }
-                    if let &Const::Yes(span) = constness {
-                        this.dcx().emit_err(error(span, "`const`", true));
-                    }
+                self.visit_attrs_vis(&item.attrs, &item.vis);
+                self.visibility_not_permitted(
+                    &item.vis,
+                    errors::VisibilityNotPermittedNote::IndividualImplItems,
+                );
+                if let &Safety::Unsafe(span) = safety {
+                    self.dcx().emit_err(errors::InherentImplCannotUnsafe {
+                        span: self_ty.span,
+                        annotation_span: span,
+                        annotation: "unsafe",
+                        self_ty: self_ty.span,
+                    });
+                }
+                if let &ImplPolarity::Negative(span) = polarity {
+                    self.dcx().emit_err(error(span, "negative", false));
+                }
+                if let &Defaultness::Default(def_span) = defaultness {
+                    self.dcx().emit_err(error(def_span, "`default`", true));
+                }
+                if let &Const::Yes(span) = constness {
+                    self.dcx().emit_err(error(span, "`const`", true));
+                }
 
-                    this.visit_vis(&item.vis);
-                    this.visit_ident(&item.ident);
-                    this.with_tilde_const(
-                        Some(TildeConstReason::Impl { span: item.span }),
-                        |this| this.visit_generics(generics),
-                    );
-                    this.visit_ty(self_ty);
+                self.with_tilde_const(Some(TildeConstReason::Impl { span: item.span }), |this| {
+                    this.visit_generics(generics)
+                });
+                self.visit_ty(self_ty);
+                self.with_in_trait_impl(None, |this| {
                     walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: false });
                 });
-                walk_list!(self, visit_attribute, &item.attrs);
-                return; // Avoid visiting again.
             }
             ItemKind::Fn(
-                func
-                @ box Fn { defaultness, generics: _, sig, contract: _, body, define_opaque: _ },
+                func @ box Fn {
+                    defaultness,
+                    ident,
+                    generics: _,
+                    sig,
+                    contract: _,
+                    body,
+                    define_opaque: _,
+                },
             ) => {
+                self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
                 self.check_defaultness(item.span, *defaultness);
 
                 let is_intrinsic =
@@ -948,45 +970,40 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     });
                 }
 
-                self.visit_vis(&item.vis);
-                self.visit_ident(&item.ident);
-                let kind = FnKind::Fn(FnCtxt::Free, &item.ident, &item.vis, &*func);
+                let kind = FnKind::Fn(FnCtxt::Free, &item.vis, &*func);
                 self.visit_fn(kind, item.span, item.id);
-                walk_list!(self, visit_attribute, &item.attrs);
-                return; // Avoid visiting again.
             }
             ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => {
-                self.with_in_extern_mod(*safety, |this| {
-                    let old_item = mem::replace(&mut this.extern_mod, Some(item.span));
-                    this.visibility_not_permitted(
-                        &item.vis,
-                        errors::VisibilityNotPermittedNote::IndividualForeignItems,
-                    );
-
-                    if &Safety::Default == safety {
-                        if item.span.at_least_rust_2024() {
-                            this.dcx().emit_err(errors::MissingUnsafeOnExtern { span: item.span });
-                        } else {
-                            this.lint_buffer.buffer_lint(
-                                MISSING_UNSAFE_ON_EXTERN,
-                                item.id,
-                                item.span,
-                                BuiltinLintDiag::MissingUnsafeOnExtern {
-                                    suggestion: item.span.shrink_to_lo(),
-                                },
-                            );
-                        }
+                let old_item = mem::replace(&mut self.extern_mod_span, Some(item.span));
+                self.visibility_not_permitted(
+                    &item.vis,
+                    errors::VisibilityNotPermittedNote::IndividualForeignItems,
+                );
+
+                if &Safety::Default == safety {
+                    if item.span.at_least_rust_2024() {
+                        self.dcx().emit_err(errors::MissingUnsafeOnExtern { span: item.span });
+                    } else {
+                        self.lint_buffer.buffer_lint(
+                            MISSING_UNSAFE_ON_EXTERN,
+                            item.id,
+                            item.span,
+                            BuiltinLintDiag::MissingUnsafeOnExtern {
+                                suggestion: item.span.shrink_to_lo(),
+                            },
+                        );
                     }
+                }
 
-                    if abi.is_none() {
-                        this.maybe_lint_missing_abi(*extern_span, item.id);
-                    }
+                if abi.is_none() {
+                    self.maybe_lint_missing_abi(*extern_span, item.id);
+                }
+                self.with_in_extern_mod(*safety, |this| {
                     visit::walk_item(this, item);
-                    this.extern_mod = old_item;
                 });
-                return; // Avoid visiting again.
+                self.extern_mod_span = old_item;
             }
-            ItemKind::Enum(def, _) => {
+            ItemKind::Enum(_, def, _) => {
                 for variant in &def.variants {
                     self.visibility_not_permitted(
                         &variant.vis,
@@ -999,36 +1016,33 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         );
                     }
                 }
+                visit::walk_item(self, item)
             }
-            ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
+            ItemKind::Trait(box Trait { is_auto, generics, ident, bounds, items, .. }) => {
+                self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
                 let is_const_trait =
                     attr::find_by_name(&item.attrs, sym::const_trait).map(|attr| attr.span);
-                self.with_in_trait(item.span, is_const_trait, |this| {
-                    if *is_auto == IsAuto::Yes {
-                        // Auto traits cannot have generics, super traits nor contain items.
-                        this.deny_generic_params(generics, item.ident.span);
-                        this.deny_super_traits(bounds, item.ident.span);
-                        this.deny_where_clause(&generics.where_clause, item.ident.span);
-                        this.deny_items(items, item.ident.span);
-                    }
+                if *is_auto == IsAuto::Yes {
+                    // Auto traits cannot have generics, super traits nor contain items.
+                    self.deny_generic_params(generics, ident.span);
+                    self.deny_super_traits(bounds, ident.span);
+                    self.deny_where_clause(&generics.where_clause, ident.span);
+                    self.deny_items(items, ident.span);
+                }
 
-                    // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
-                    // context for the supertraits.
-                    this.visit_vis(&item.vis);
-                    this.visit_ident(&item.ident);
-                    let disallowed = is_const_trait
-                        .is_none()
-                        .then(|| TildeConstReason::Trait { span: item.span });
-                    this.with_tilde_const(disallowed, |this| {
-                        this.visit_generics(generics);
-                        walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
-                    });
+                // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
+                // context for the supertraits.
+                let disallowed =
+                    is_const_trait.is_none().then(|| TildeConstReason::Trait { span: item.span });
+                self.with_tilde_const(disallowed, |this| {
+                    this.visit_generics(generics);
+                    walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
+                });
+                self.with_in_trait(item.span, is_const_trait, |this| {
                     walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait);
                 });
-                walk_list!(self, visit_attribute, &item.attrs);
-                return; // Avoid visiting again
             }
-            ItemKind::Mod(safety, mod_kind) => {
+            ItemKind::Mod(safety, ident, mod_kind) => {
                 if let &Safety::Unsafe(span) = safety {
                     self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
                 }
@@ -1036,36 +1050,31 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _))
                     && !attr::contains_name(&item.attrs, sym::path)
                 {
-                    self.check_mod_file_item_asciionly(item.ident);
+                    self.check_mod_file_item_asciionly(*ident);
                 }
+                visit::walk_item(self, item)
             }
-            ItemKind::Struct(vdata, generics) => match vdata {
+            ItemKind::Struct(ident, vdata, generics) => match vdata {
                 VariantData::Struct { fields, .. } => {
-                    self.visit_vis(&item.vis);
-                    self.visit_ident(&item.ident);
+                    self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
                     self.visit_generics(generics);
                     // Permit `Anon{Struct,Union}` as field type.
                     walk_list!(self, visit_struct_field_def, fields);
-                    walk_list!(self, visit_attribute, &item.attrs);
-                    return;
                 }
-                _ => {}
+                _ => visit::walk_item(self, item),
             },
-            ItemKind::Union(vdata, generics) => {
+            ItemKind::Union(ident, vdata, generics) => {
                 if vdata.fields().is_empty() {
                     self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
                 }
                 match vdata {
                     VariantData::Struct { fields, .. } => {
-                        self.visit_vis(&item.vis);
-                        self.visit_ident(&item.ident);
+                        self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
                         self.visit_generics(generics);
                         // Permit `Anon{Struct,Union}` as field type.
                         walk_list!(self, visit_struct_field_def, fields);
-                        walk_list!(self, visit_attribute, &item.attrs);
-                        return;
                     }
-                    _ => {}
+                    _ => visit::walk_item(self, item),
                 }
             }
             ItemKind::Const(box ConstItem { defaultness, expr, .. }) => {
@@ -1076,6 +1085,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         replace_span: self.ending_semi_or_hi(item.span),
                     });
                 }
+                visit::walk_item(self, item);
             }
             ItemKind::Static(box StaticItem { expr, safety, .. }) => {
                 self.check_item_safety(item.span, *safety);
@@ -1089,6 +1099,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         replace_span: self.ending_semi_or_hi(item.span),
                     });
                 }
+                visit::walk_item(self, item);
             }
             ItemKind::TyAlias(
                 ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
@@ -1112,23 +1123,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         help: self.sess.is_nightly_build(),
                     });
                 }
+                visit::walk_item(self, item);
             }
-            _ => {}
+            _ => visit::walk_item(self, item),
         }
-
-        visit::walk_item(self, item);
     }
 
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
         match &fi.kind {
-            ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
+            ForeignItemKind::Fn(box Fn { defaultness, ident, sig, body, .. }) => {
                 self.check_defaultness(fi.span, *defaultness);
-                self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
+                self.check_foreign_fn_bodyless(*ident, body.as_deref());
                 self.check_foreign_fn_headerless(sig.header);
-                self.check_foreign_item_ascii_only(fi.ident);
+                self.check_foreign_item_ascii_only(*ident);
             }
             ForeignItemKind::TyAlias(box TyAlias {
                 defaultness,
+                ident,
                 generics,
                 where_clauses,
                 bounds,
@@ -1136,15 +1147,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 ..
             }) => {
                 self.check_defaultness(fi.span, *defaultness);
-                self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
+                self.check_foreign_kind_bodyless(*ident, "type", ty.as_ref().map(|b| b.span));
                 self.check_type_no_bounds(bounds, "`extern` blocks");
                 self.check_foreign_ty_genericless(generics, where_clauses);
-                self.check_foreign_item_ascii_only(fi.ident);
+                self.check_foreign_item_ascii_only(*ident);
             }
-            ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => {
+            ForeignItemKind::Static(box StaticItem { ident, safety, expr, .. }) => {
                 self.check_item_safety(fi.span, *safety);
-                self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
-                self.check_foreign_item_ascii_only(fi.ident);
+                self.check_foreign_kind_bodyless(*ident, "static", expr.as_ref().map(|b| b.span));
+                self.check_foreign_item_ascii_only(*ident);
             }
             ForeignItemKind::MacCall(..) => {}
         }
@@ -1353,7 +1364,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         if let FnKind::Fn(
             _,
             _,
-            _,
             Fn {
                 sig: FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. },
                 ..
@@ -1364,7 +1374,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         }
 
         // Functions without bodies cannot have patterns.
-        if let FnKind::Fn(ctxt, _, _, Fn { body: None, sig, .. }) = fk {
+        if let FnKind::Fn(ctxt, _, Fn { body: None, sig, .. }) = fk {
             Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
                 if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) {
                     if let Some(ident) = ident {
@@ -1398,15 +1408,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         .is_some();
 
         let disallowed = (!tilde_const_allowed).then(|| match fk {
-            FnKind::Fn(_, ident, _, _) => TildeConstReason::Function { ident: ident.span },
+            FnKind::Fn(_, _, f) => TildeConstReason::Function { ident: f.ident.span },
             FnKind::Closure(..) => TildeConstReason::Closure,
         });
         self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
     }
 
     fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
-        if attr::contains_name(&item.attrs, sym::no_mangle) {
-            self.check_nomangle_item_asciionly(item.ident, item.span);
+        if let Some(ident) = item.kind.ident()
+            && attr::contains_name(&item.attrs, sym::no_mangle)
+        {
+            self.check_nomangle_item_asciionly(ident, item.span);
         }
 
         if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() {
@@ -1466,8 +1478,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
         }
 
-        if let AssocItemKind::Const(..) = item.kind {
-            self.check_item_named(item.ident, "const");
+        if let AssocItemKind::Const(ci) = &item.kind {
+            self.check_item_named(ci.ident, "const");
         }
 
         let parent_is_const =
@@ -1479,10 +1491,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     || ctxt == AssocCtxt::Trait
                     || matches!(func.sig.header.constness, Const::Yes(_)) =>
             {
-                self.visit_vis(&item.vis);
-                self.visit_ident(&item.ident);
-                let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.ident, &item.vis, &*func);
-                walk_list!(self, visit_attribute, &item.attrs);
+                self.visit_attrs_vis_ident(&item.attrs, &item.vis, &func.ident);
+                let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.vis, &*func);
                 self.visit_fn(kind, item.span, item.id);
             }
             AssocItemKind::Type(_) => {
@@ -1587,7 +1597,7 @@ fn deny_equality_constraints(
                     generics.where_clause.span
                 } else {
                     let mut span = predicate_span;
-                    let mut prev: Option<Span> = None;
+                    let mut prev_span: Option<Span> = None;
                     let mut preds = generics.where_clause.predicates.iter().peekable();
                     // Find the predicate that shouldn't have been in the where bound list.
                     while let Some(pred) = preds.next() {
@@ -1597,12 +1607,12 @@ fn deny_equality_constraints(
                             if let Some(next) = preds.peek() {
                                 // This is the first predicate, remove the trailing comma as well.
                                 span = span.with_hi(next.span.lo());
-                            } else if let Some(prev) = prev {
+                            } else if let Some(prev_span) = prev_span {
                                 // Remove the previous comma as well.
-                                span = span.with_lo(prev.hi());
+                                span = span.with_lo(prev_span.hi());
                             }
                         }
-                        prev = Some(pred.span);
+                        prev_span = Some(pred.span);
                     }
                     span
                 };
@@ -1677,10 +1687,10 @@ pub fn check_crate(
     let mut validator = AstValidator {
         sess,
         features,
-        extern_mod: None,
+        extern_mod_span: None,
         outer_trait_or_trait_impl: None,
         has_proc_macro_decls: false,
-        outer_impl_trait: None,
+        outer_impl_trait_span: None,
         disallow_tilde_const: Some(TildeConstReason::Item),
         extern_mod_safety: None,
         lint_buffer: lints,
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 31ff102c127..e312f15f05b 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -99,6 +99,13 @@ impl<'a> PostExpansionVisitor<'a> {
                 }
                 visit::walk_ty(self, ty);
             }
+
+            fn visit_anon_const(&mut self, _: &ast::AnonConst) -> Self::Result {
+                // We don't walk the anon const because it crosses a conceptual boundary: We're no
+                // longer "inside" the original type.
+                // Brittle: We assume that the callers of `check_impl_trait` will later recurse into
+                // the items found in the AnonConst to look for nested TyAliases.
+            }
         }
         ImplTraitVisitor { vis: self, in_associated_ty }.visit_ty(ty);
     }
@@ -229,7 +236,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 gate!(&self, trait_alias, i.span, "trait aliases are experimental");
             }
 
-            ast::ItemKind::MacroDef(ast::MacroDef { macro_rules: false, .. }) => {
+            ast::ItemKind::MacroDef(_, ast::MacroDef { macro_rules: false, .. }) => {
                 let msg = "`macro` is experimental";
                 gate!(&self, decl_macro, i.span, msg);
             }
@@ -325,17 +332,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             ast::ExprKind::TryBlock(_) => {
                 gate!(&self, try_blocks, e.span, "`try` expression is experimental");
             }
-            ast::ExprKind::Lit(token::Lit { kind: token::LitKind::Float, suffix, .. }) => {
-                match suffix {
-                    Some(sym::f16) => {
-                        gate!(&self, f16, e.span, "the type `f16` is unstable")
-                    }
-                    Some(sym::f128) => {
-                        gate!(&self, f128, e.span, "the type `f128` is unstable")
-                    }
-                    _ => (),
+            ast::ExprKind::Lit(token::Lit {
+                kind: token::LitKind::Float | token::LitKind::Integer,
+                suffix,
+                ..
+            }) => match suffix {
+                Some(sym::f16) => {
+                    gate!(&self, f16, e.span, "the type `f16` is unstable")
                 }
-            }
+                Some(sym::f128) => {
+                    gate!(&self, f128, e.span, "the type `f128` is unstable")
+                }
+                _ => (),
+            },
             _ => {}
         }
         visit::walk_expr(self, e)
@@ -483,7 +492,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
         half_open_range_patterns_in_slices,
         "half-open range patterns in slices are unstable"
     );
-    gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
     gate_all!(associated_const_equality, "associated const equality is incomplete");
     gate_all!(yeet_expr, "`do yeet` expression is experimental");
     gate_all!(dyn_star, "`dyn*` trait objects are experimental");
@@ -505,6 +513,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(contracts, "contracts are incomplete");
     gate_all!(contracts_internals, "contract internal machinery is for internal use only");
     gate_all!(where_clause_attrs, "attributes in `where` clause are unstable");
+    gate_all!(super_let, "`super let` is experimental");
 
     if !visitor.features.never_patterns() {
         if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 7d9dc89bd75..df848a26d39 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -274,22 +274,22 @@ impl<'a> State<'a> {
 
     fn print_expr_binary(
         &mut self,
-        op: ast::BinOp,
+        op: ast::BinOpKind,
         lhs: &ast::Expr,
         rhs: &ast::Expr,
         fixup: FixupContext,
     ) {
-        let binop_prec = op.node.precedence();
+        let binop_prec = op.precedence();
         let left_prec = lhs.precedence();
         let right_prec = rhs.precedence();
 
-        let (mut left_needs_paren, right_needs_paren) = match op.node.fixity() {
+        let (mut left_needs_paren, right_needs_paren) = match op.fixity() {
             Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec),
             Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec),
             Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec),
         };
 
-        match (&lhs.kind, op.node) {
+        match (&lhs.kind, op) {
             // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
             // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
             // of `(x as i32) < ...`. We need to convince it _not_ to do that.
@@ -312,7 +312,7 @@ impl<'a> State<'a> {
 
         self.print_expr_cond_paren(lhs, left_needs_paren, fixup.leftmost_subexpression());
         self.space();
-        self.word_space(op.node.as_str());
+        self.word_space(op.as_str());
         self.print_expr_cond_paren(rhs, right_needs_paren, fixup.subsequent_subexpression());
     }
 
@@ -410,7 +410,7 @@ impl<'a> State<'a> {
                 self.print_expr_method_call(seg, receiver, args, fixup);
             }
             ast::ExprKind::Binary(op, lhs, rhs) => {
-                self.print_expr_binary(*op, lhs, rhs, fixup);
+                self.print_expr_binary(op.node, lhs, rhs, fixup);
             }
             ast::ExprKind::Unary(op, expr) => {
                 self.print_expr_unary(*op, expr, fixup);
@@ -605,8 +605,7 @@ impl<'a> State<'a> {
                     fixup.leftmost_subexpression(),
                 );
                 self.space();
-                self.word(op.node.as_str());
-                self.word_space("=");
+                self.word_space(op.node.as_str());
                 self.print_expr_cond_paren(
                     rhs,
                     rhs.precedence() < ExprPrecedence::Assign,
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index d406a56c05d..653bd77cc4d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -28,23 +28,24 @@ impl<'a> State<'a> {
     }
 
     fn print_foreign_item(&mut self, item: &ast::ForeignItem) {
-        let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item;
+        let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
         self.ann.pre(self, AnnNode::SubItem(id));
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(span.lo());
         self.print_outer_attributes(attrs);
         match kind {
             ast::ForeignItemKind::Fn(func) => {
-                self.print_fn_full(ident, vis, attrs, &*func);
+                self.print_fn_full(vis, attrs, &*func);
             }
             ast::ForeignItemKind::Static(box ast::StaticItem {
+                ident,
                 ty,
                 mutability,
                 expr,
                 safety,
                 define_opaque,
             }) => self.print_item_const(
-                ident,
+                *ident,
                 Some(*mutability),
                 &ast::Generics::default(),
                 ty,
@@ -56,13 +57,14 @@ impl<'a> State<'a> {
             ),
             ast::ForeignItemKind::TyAlias(box ast::TyAlias {
                 defaultness,
+                ident,
                 generics,
                 where_clauses,
                 bounds,
                 ty,
             }) => {
                 self.print_associated_type(
-                    ident,
+                    *ident,
                     generics,
                     *where_clauses,
                     bounds,
@@ -162,7 +164,7 @@ impl<'a> State<'a> {
         self.print_outer_attributes(&item.attrs);
         self.ann.pre(self, AnnNode::Item(item));
         match &item.kind {
-            ast::ItemKind::ExternCrate(orig_name) => {
+            ast::ItemKind::ExternCrate(orig_name, ident) => {
                 self.head(visibility_qualified(&item.vis, "extern crate"));
                 if let &Some(orig_name) = orig_name {
                     self.print_name(orig_name);
@@ -170,7 +172,7 @@ impl<'a> State<'a> {
                     self.word("as");
                     self.space();
                 }
-                self.print_ident(item.ident);
+                self.print_ident(*ident);
                 self.word(";");
                 self.end(); // end inner head-block
                 self.end(); // end outer head-block
@@ -182,6 +184,7 @@ impl<'a> State<'a> {
                 self.word(";");
             }
             ast::ItemKind::Static(box StaticItem {
+                ident,
                 ty,
                 safety,
                 mutability: mutbl,
@@ -190,7 +193,7 @@ impl<'a> State<'a> {
             }) => {
                 self.print_safety(*safety);
                 self.print_item_const(
-                    item.ident,
+                    *ident,
                     Some(*mutbl),
                     &ast::Generics::default(),
                     ty,
@@ -203,13 +206,14 @@ impl<'a> State<'a> {
             }
             ast::ItemKind::Const(box ast::ConstItem {
                 defaultness,
+                ident,
                 generics,
                 ty,
                 expr,
                 define_opaque,
             }) => {
                 self.print_item_const(
-                    item.ident,
+                    *ident,
                     None,
                     generics,
                     ty,
@@ -221,15 +225,15 @@ impl<'a> State<'a> {
                 );
             }
             ast::ItemKind::Fn(func) => {
-                self.print_fn_full(item.ident, &item.vis, &item.attrs, &*func);
+                self.print_fn_full(&item.vis, &item.attrs, &*func);
             }
-            ast::ItemKind::Mod(safety, mod_kind) => {
+            ast::ItemKind::Mod(safety, ident, mod_kind) => {
                 self.head(Self::to_string(|s| {
                     s.print_visibility(&item.vis);
                     s.print_safety(*safety);
                     s.word("mod");
                 }));
-                self.print_ident(item.ident);
+                self.print_ident(*ident);
 
                 match mod_kind {
                     ModKind::Loaded(items, ..) => {
@@ -273,13 +277,14 @@ impl<'a> State<'a> {
             }
             ast::ItemKind::TyAlias(box ast::TyAlias {
                 defaultness,
+                ident,
                 generics,
                 where_clauses,
                 bounds,
                 ty,
             }) => {
                 self.print_associated_type(
-                    item.ident,
+                    *ident,
                     generics,
                     *where_clauses,
                     bounds,
@@ -288,16 +293,16 @@ impl<'a> State<'a> {
                     *defaultness,
                 );
             }
-            ast::ItemKind::Enum(enum_definition, params) => {
-                self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
+            ast::ItemKind::Enum(ident, enum_definition, params) => {
+                self.print_enum_def(enum_definition, params, *ident, item.span, &item.vis);
             }
-            ast::ItemKind::Struct(struct_def, generics) => {
+            ast::ItemKind::Struct(ident, struct_def, generics) => {
                 self.head(visibility_qualified(&item.vis, "struct"));
-                self.print_struct(struct_def, generics, item.ident, item.span, true);
+                self.print_struct(struct_def, generics, *ident, item.span, true);
             }
-            ast::ItemKind::Union(struct_def, generics) => {
+            ast::ItemKind::Union(ident, struct_def, generics) => {
                 self.head(visibility_qualified(&item.vis, "union"));
-                self.print_struct(struct_def, generics, item.ident, item.span, true);
+                self.print_struct(struct_def, generics, *ident, item.span, true);
             }
             ast::ItemKind::Impl(box ast::Impl {
                 safety,
@@ -347,19 +352,19 @@ impl<'a> State<'a> {
                 self.bclose(item.span, empty);
             }
             ast::ItemKind::Trait(box ast::Trait {
-                is_auto,
                 safety,
+                is_auto,
+                ident,
                 generics,
                 bounds,
                 items,
-                ..
             }) => {
                 self.head("");
                 self.print_visibility(&item.vis);
                 self.print_safety(*safety);
                 self.print_is_auto(*is_auto);
                 self.word_nbsp("trait");
-                self.print_ident(item.ident);
+                self.print_ident(*ident);
                 self.print_generic_params(&generics.params);
                 if !bounds.is_empty() {
                     self.word_nbsp(":");
@@ -375,9 +380,9 @@ impl<'a> State<'a> {
                 let empty = item.attrs.is_empty() && items.is_empty();
                 self.bclose(item.span, empty);
             }
-            ast::ItemKind::TraitAlias(generics, bounds) => {
+            ast::ItemKind::TraitAlias(ident, generics, bounds) => {
                 self.head(visibility_qualified(&item.vis, "trait"));
-                self.print_ident(item.ident);
+                self.print_ident(*ident);
                 self.print_generic_params(&generics.params);
                 self.nbsp();
                 if !bounds.is_empty() {
@@ -395,8 +400,8 @@ impl<'a> State<'a> {
                     self.word(";");
                 }
             }
-            ast::ItemKind::MacroDef(macro_def) => {
-                self.print_mac_def(macro_def, &item.ident, item.span, |state| {
+            ast::ItemKind::MacroDef(ident, macro_def) => {
+                self.print_mac_def(macro_def, &ident, item.span, |state| {
                     state.print_visibility(&item.vis)
                 });
             }
@@ -549,24 +554,25 @@ impl<'a> State<'a> {
     }
 
     fn print_assoc_item(&mut self, item: &ast::AssocItem) {
-        let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item;
+        let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
         self.ann.pre(self, AnnNode::SubItem(id));
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(span.lo());
         self.print_outer_attributes(attrs);
         match kind {
             ast::AssocItemKind::Fn(func) => {
-                self.print_fn_full(ident, vis, attrs, &*func);
+                self.print_fn_full(vis, attrs, &*func);
             }
             ast::AssocItemKind::Const(box ast::ConstItem {
                 defaultness,
+                ident,
                 generics,
                 ty,
                 expr,
                 define_opaque,
             }) => {
                 self.print_item_const(
-                    ident,
+                    *ident,
                     None,
                     generics,
                     ty,
@@ -579,13 +585,14 @@ impl<'a> State<'a> {
             }
             ast::AssocItemKind::Type(box ast::TyAlias {
                 defaultness,
+                ident,
                 generics,
                 where_clauses,
                 bounds,
                 ty,
             }) => {
                 self.print_associated_type(
-                    ident,
+                    *ident,
                     generics,
                     *where_clauses,
                     bounds,
@@ -671,14 +678,8 @@ impl<'a> State<'a> {
         }
     }
 
-    fn print_fn_full(
-        &mut self,
-        name: Ident,
-        vis: &ast::Visibility,
-        attrs: &[ast::Attribute],
-        func: &ast::Fn,
-    ) {
-        let ast::Fn { defaultness, generics, sig, contract, body, define_opaque } = func;
+    fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) {
+        let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque } = func;
 
         self.print_define_opaques(define_opaque.as_deref());
 
@@ -687,7 +688,7 @@ impl<'a> State<'a> {
         }
         self.print_visibility(vis);
         self.print_defaultness(*defaultness);
-        self.print_fn(&sig.decl, sig.header, Some(name), generics);
+        self.print_fn(&sig.decl, sig.header, Some(*ident), generics);
         if let Some(contract) = &contract {
             self.nbsp();
             self.print_contract(contract);
@@ -734,13 +735,13 @@ impl<'a> State<'a> {
         &mut self,
         decl: &ast::FnDecl,
         header: ast::FnHeader,
-        name: Option<Ident>,
+        ident: Option<Ident>,
         generics: &ast::Generics,
     ) {
         self.print_fn_header_info(header);
-        if let Some(name) = name {
+        if let Some(ident) = ident {
             self.nbsp();
-            self.print_ident(name);
+            self.print_ident(ident);
         }
         self.print_generic_params(&generics.params);
         self.print_fn_params_and_ret(decl, false);
diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl
index ada20e5c614..33b80c4b03d 100644
--- a/compiler/rustc_borrowck/messages.ftl
+++ b/compiler/rustc_borrowck/messages.ftl
@@ -162,13 +162,6 @@ borrowck_opaque_type_lifetime_mismatch =
     .prev_lifetime_label = lifetime `{$prev}` previously used here
     .note = if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
 
-borrowck_opaque_type_non_generic_param =
-    expected generic {$kind} parameter, found `{$ty}`
-    .label = {STREQ($ty, "'static") ->
-        [true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
-        *[other] this generic parameter must be used with a generic {$kind} parameter
-    }
-
 borrowck_partial_var_move_by_use_in_closure =
     variable {$is_partial ->
         [true] partially moved
diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs
index 5a89f7c351c..45cdd232564 100644
--- a/compiler/rustc_borrowck/src/consumers.rs
+++ b/compiler/rustc_borrowck/src/consumers.rs
@@ -1,7 +1,7 @@
 //! This file provides API for compiler consumers.
 
 use rustc_hir::def_id::LocalDefId;
-use rustc_index::{IndexSlice, IndexVec};
+use rustc_index::IndexVec;
 use rustc_middle::mir::{Body, Promoted};
 use rustc_middle::ty::TyCtxt;
 
@@ -100,8 +100,5 @@ pub fn get_body_with_borrowck_facts(
     def: LocalDefId,
     options: ConsumerOptions,
 ) -> BodyWithBorrowckFacts<'_> {
-    let (input_body, promoted) = tcx.mir_promoted(def);
-    let input_body: &Body<'_> = &input_body.borrow();
-    let promoted: &IndexSlice<_, _> = &promoted.borrow();
-    *super::do_mir_borrowck(tcx, input_body, promoted, Some(options)).1.unwrap()
+    *super::do_mir_borrowck(tcx, def, Some(options)).1.unwrap()
 }
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 978186f76a1..1f4eb0c449f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -181,7 +181,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             let closure = self.add_moved_or_invoked_closure_note(location, used_place, &mut err);
 
             let mut is_loop_move = false;
-            let mut in_pattern = false;
             let mut seen_spans = FxIndexSet::default();
 
             for move_site in &move_site_vec {
@@ -204,7 +203,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     self.suggest_ref_or_clone(
                         mpi,
                         &mut err,
-                        &mut in_pattern,
                         move_spans,
                         moved_place.as_ref(),
                         &mut has_suggest_reborrow,
@@ -256,15 +254,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             let place = &self.move_data.move_paths[mpi].place;
             let ty = place.ty(self.body, self.infcx.tcx).ty;
 
-            // If we're in pattern, we do nothing in favor of the previous suggestion (#80913).
-            // Same for if we're in a loop, see #101119.
-            if is_loop_move & !in_pattern && !matches!(use_spans, UseSpans::ClosureUse { .. }) {
-                if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
-                    // We have a `&mut` ref, we need to reborrow on each iteration (#62112).
-                    self.suggest_reborrow(&mut err, span, moved_place);
-                }
-            }
-
             if self.infcx.param_env.caller_bounds().iter().any(|c| {
                 c.as_trait_clause().is_some_and(|pred| {
                     pred.skip_binder().self_ty() == ty && self.infcx.tcx.is_fn_trait(pred.def_id())
@@ -330,7 +319,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         &self,
         mpi: MovePathIndex,
         err: &mut Diag<'infcx>,
-        in_pattern: &mut bool,
         move_spans: UseSpans<'tcx>,
         moved_place: PlaceRef<'tcx>,
         has_suggest_reborrow: &mut bool,
@@ -545,7 +533,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 && !move_span.is_dummy()
                 && !self.infcx.tcx.sess.source_map().is_imported(move_span)
             {
-                *in_pattern = true;
                 let mut sugg = vec![(pat.span.shrink_to_lo(), "ref ".to_string())];
                 if let Some(pat) = finder.parent_pat {
                     sugg.insert(0, (pat.span.shrink_to_lo(), "ref ".to_string()));
@@ -1364,7 +1351,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         }
         // Try to find predicates on *generic params* that would allow copying `ty`
         let mut suggestion =
-            if let Some(symbol) = tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+            if let Some(symbol) = tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
                 format!(": {symbol}.clone()")
             } else {
                 ".clone()".to_owned()
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 29cc749877b..0394a42ea9c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -502,7 +502,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 let upvar = &self.upvars[upvar_field.unwrap().index()];
                 let upvar_hir_id = upvar.get_root_variable();
                 let upvar_name = upvar.to_string(tcx);
-                let upvar_span = tcx.hir().span(upvar_hir_id);
+                let upvar_span = tcx.hir_span(upvar_hir_id);
 
                 let place_name = self.describe_any_place(move_place.as_ref());
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index fddddf404db..56cc4327585 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -969,7 +969,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             }
         };
 
-        // If we can detect the expression to be an function or method call where the closure was
+        // If we can detect the expression to be a function or method call where the closure was
         // an argument, we point at the function or method definition argument...
         if let Some((callee_def_id, call_span, call_args)) = get_call_details() {
             let arg_pos = call_args
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 50a18b04de4..d1d783c22e3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -628,7 +628,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
 
             if let Some(def_hir) = defined_hir {
                 let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap();
-                let upvar_def_span = self.infcx.tcx.hir().span(def_hir);
+                let upvar_def_span = self.infcx.tcx.hir_span(def_hir);
                 let upvar_span = upvars_map.get(&def_hir).unwrap().span;
                 diag.subdiagnostic(VarHereDenote::Defined { span: upvar_def_span });
                 diag.subdiagnostic(VarHereDenote::Captured { span: upvar_span });
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 412aaf70c3f..45f5eaa514b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -291,7 +291,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
         match *error_region {
             ty::ReEarlyParam(ebr) => ebr.has_name().then(|| {
                 let def_id = tcx.generics_of(self.mir_def_id()).region_param(ebr, tcx).def_id;
-                let span = tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
+                let span = tcx.hir_span_if_local(def_id).unwrap_or(DUMMY_SP);
                 RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyParamRegion(span) }
             }),
 
@@ -302,7 +302,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
             ty::ReLateParam(late_param) => match late_param.kind {
                 ty::LateParamRegionKind::Named(region_def_id, name) => {
                     // Get the span to point to, even if we don't use the name.
-                    let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP);
+                    let span = tcx.hir_span_if_local(region_def_id).unwrap_or(DUMMY_SP);
                     debug!(
                         "bound region named: {:?}, is_named: {:?}",
                         name,
diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
index 693d22abbe6..14ed6a27a7a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
@@ -70,7 +70,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}");
 
         let upvar_name = tcx.hir_name(upvar_hir_id);
-        let upvar_span = tcx.hir().span(upvar_hir_id);
+        let upvar_span = tcx.hir_span(upvar_hir_id);
         debug!(
             "get_upvar_name_and_span_for_region: upvar_name={upvar_name:?} upvar_span={upvar_span:?}",
         );
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 84b7b8c6a2d..240bd20053b 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -35,7 +35,7 @@ use rustc_infer::infer::{
 };
 use rustc_middle::mir::*;
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode, fold_regions};
+use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
 use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::impls::{
     EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
@@ -103,11 +103,8 @@ pub fn provide(providers: &mut Providers) {
 }
 
 fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
-    let (input_body, promoted) = tcx.mir_promoted(def);
-    debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
-
+    let (input_body, _) = tcx.mir_promoted(def);
     let input_body: &Body<'_> = &input_body.borrow();
-
     if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
         debug!("Skipping borrowck because of injected body or tainted body");
         // Let's make up a borrowck result! Fun times!
@@ -120,7 +117,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
         return tcx.arena.alloc(result);
     }
 
-    let borrowck_result = do_mir_borrowck(tcx, input_body, &*promoted.borrow(), None).0;
+    let borrowck_result = do_mir_borrowck(tcx, def, None).0;
     debug!("mir_borrowck done");
 
     tcx.arena.alloc(borrowck_result)
@@ -131,15 +128,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
 /// Use `consumer_options: None` for the default behavior of returning
 /// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
 /// to the given [`ConsumerOptions`].
-#[instrument(skip(tcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
+#[instrument(skip(tcx), level = "debug")]
 fn do_mir_borrowck<'tcx>(
     tcx: TyCtxt<'tcx>,
-    input_body: &Body<'tcx>,
-    input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
+    def: LocalDefId,
     consumer_options: Option<ConsumerOptions>,
 ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
-    let def = input_body.source.def_id().expect_local();
     let infcx = BorrowckInferCtxt::new(tcx, def);
+    let (input_body, promoted) = tcx.mir_promoted(def);
+    let input_body: &Body<'_> = &input_body.borrow();
+    let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
     if let Some(e) = input_body.tainted_by_errors {
         infcx.set_tainted_by_errors(e);
     }
@@ -173,12 +171,6 @@ fn do_mir_borrowck<'tcx>(
     let free_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
     let body = &body_owned; // no further changes
 
-    // 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()) {
-        infcx.register_predefined_opaques_for_next_solver(def);
-    }
-
     let location_table = PoloniusLocationTable::new(body);
 
     let move_data = MoveData::gather_moves(body, tcx, |_| true);
@@ -433,7 +425,12 @@ pub(crate) struct BorrowckInferCtxt<'tcx> {
 
 impl<'tcx> BorrowckInferCtxt<'tcx> {
     pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
-        let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, def_id));
+        let typing_mode = if tcx.use_typing_mode_borrowck() {
+            TypingMode::borrowck(tcx, def_id)
+        } else {
+            TypingMode::analysis_in_body(tcx, def_id)
+        };
+        let infcx = tcx.infer_ctxt().build(typing_mode);
         let param_env = tcx.param_env(def_id);
         BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()), param_env }
     }
@@ -480,28 +477,6 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
 
         next_region
     }
-
-    /// With the new solver we prepopulate the opaque type storage during
-    /// MIR borrowck with the hidden types from HIR typeck. This is necessary
-    /// to avoid ambiguities as earlier goals can rely on the hidden type
-    /// of an opaque which is only constrained by a later goal.
-    fn register_predefined_opaques_for_next_solver(&self, def_id: LocalDefId) {
-        let tcx = self.tcx;
-        // OK to use the identity arguments for each opaque type key, since
-        // we remap opaques from HIR typeck back to their definition params.
-        for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) {
-            // HIR typeck did not infer the regions of the opaque, so we instantiate
-            // them with fresh inference variables.
-            let (key, hidden_ty) = fold_regions(tcx, data, |_, _| {
-                self.next_nll_region_var_in_universe(
-                    NllRegionVariableOrigin::Existential { from_forall: false },
-                    ty::UniverseIndex::ROOT,
-                )
-            });
-
-            self.inject_new_hidden_type_unchecked(key, hidden_ty);
-        }
-    }
 }
 
 impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index ca8b9fb4e9d..a098450352f 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -1,22 +1,17 @@
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_errors::ErrorGuaranteed;
-use rustc_hir::OpaqueTyOrigin;
-use rustc_hir::def_id::LocalDefId;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _};
+use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
 use rustc_macros::extension;
 use rustc_middle::ty::{
-    self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
-    TypeVisitableExt, TypingMode, fold_regions,
+    self, DefiningScopeKind, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
+    TypeVisitableExt, fold_regions,
 };
 use rustc_span::Span;
-use rustc_trait_selection::regions::OutlivesEnvironmentBuildExt;
-use rustc_trait_selection::traits::ObligationCtxt;
+use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid;
 use tracing::{debug, instrument};
 
 use super::RegionInferenceContext;
 use crate::opaque_types::ConcreteOpaqueTypes;
-use crate::session_diagnostics::{LifetimeMismatchOpaqueParam, NonGenericOpaqueTypeParam};
+use crate::session_diagnostics::LifetimeMismatchOpaqueParam;
 use crate::universal_regions::RegionClassification;
 
 impl<'tcx> RegionInferenceContext<'tcx> {
@@ -272,14 +267,21 @@ impl<'tcx> InferCtxt<'tcx> {
             return Ty::new_error(self.tcx, e);
         }
 
-        if let Err(guar) =
-            check_opaque_type_parameter_valid(self, opaque_type_key, instantiated_ty.span)
-        {
+        if let Err(guar) = check_opaque_type_parameter_valid(
+            self,
+            opaque_type_key,
+            instantiated_ty.span,
+            DefiningScopeKind::MirBorrowck,
+        ) {
             return Ty::new_error(self.tcx, guar);
         }
 
         let definition_ty = instantiated_ty
-            .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
+            .remap_generic_params_to_declaration_params(
+                opaque_type_key,
+                self.tcx,
+                DefiningScopeKind::MirBorrowck,
+            )
             .ty;
 
         if let Err(e) = definition_ty.error_reported() {
@@ -289,156 +291,3 @@ impl<'tcx> InferCtxt<'tcx> {
         definition_ty
     }
 }
-
-/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter].
-///
-/// [rustc-dev-guide chapter]:
-/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html
-fn check_opaque_type_parameter_valid<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    opaque_type_key: OpaqueTypeKey<'tcx>,
-    span: Span,
-) -> Result<(), ErrorGuaranteed> {
-    let tcx = infcx.tcx;
-    let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
-    let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
-    let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
-
-    for (i, arg) in opaque_type_key.iter_captured_args(tcx) {
-        let arg_is_param = match arg.unpack() {
-            GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
-            GenericArgKind::Lifetime(lt) => {
-                matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_))
-                    || (lt.is_static() && opaque_env.param_equal_static(i))
-            }
-            GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)),
-        };
-
-        if arg_is_param {
-            // Register if the same lifetime appears multiple times in the generic args.
-            // There is an exception when the opaque type *requires* the lifetimes to be equal.
-            // See [rustc-dev-guide chapter] § "An exception to uniqueness rule".
-            let seen_where = seen_params.entry(arg).or_default();
-            if !seen_where.first().is_some_and(|&prev_i| opaque_env.params_equal(i, prev_i)) {
-                seen_where.push(i);
-            }
-        } else {
-            // Prevent `fn foo() -> Foo<u32>` from being defining.
-            let opaque_param = opaque_generics.param_at(i, tcx);
-            let kind = opaque_param.kind.descr();
-
-            opaque_env.param_is_error(i)?;
-
-            return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
-                ty: arg,
-                kind,
-                span,
-                param_span: tcx.def_span(opaque_param.def_id),
-            }));
-        }
-    }
-
-    for (_, indices) in seen_params {
-        if indices.len() > 1 {
-            let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
-            let spans: Vec<_> = indices
-                .into_iter()
-                .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
-                .collect();
-            #[allow(rustc::diagnostic_outside_of_impl)]
-            #[allow(rustc::untranslatable_diagnostic)]
-            return Err(infcx
-                .dcx()
-                .struct_span_err(span, "non-defining opaque type use in defining scope")
-                .with_span_note(spans, format!("{descr} used multiple times"))
-                .emit());
-        }
-    }
-
-    Ok(())
-}
-
-/// Computes if an opaque type requires a lifetime parameter to be equal to
-/// another one or to the `'static` lifetime.
-/// These requirements are derived from the explicit and implied bounds.
-struct LazyOpaqueTyEnv<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    def_id: LocalDefId,
-
-    /// Equal parameters will have the same name. Computed Lazily.
-    /// Example:
-    ///     `type Opaque<'a: 'static, 'b: 'c, 'c: 'b> = impl Sized;`
-    ///     Identity args: `['a, 'b, 'c]`
-    ///     Canonical args: `['static, 'b, 'b]`
-    canonical_args: std::cell::OnceCell<ty::GenericArgsRef<'tcx>>,
-}
-
-impl<'tcx> LazyOpaqueTyEnv<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
-        Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() }
-    }
-
-    fn param_equal_static(&self, param_index: usize) -> bool {
-        self.get_canonical_args()[param_index].expect_region().is_static()
-    }
-
-    fn params_equal(&self, param1: usize, param2: usize) -> bool {
-        let canonical_args = self.get_canonical_args();
-        canonical_args[param1] == canonical_args[param2]
-    }
-
-    fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> {
-        self.get_canonical_args()[param_index].error_reported()
-    }
-
-    fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> {
-        if let Some(&canonical_args) = self.canonical_args.get() {
-            return canonical_args;
-        }
-
-        let &Self { tcx, def_id, .. } = self;
-        let origin = tcx.local_opaque_ty_origin(def_id);
-        let parent = match origin {
-            OpaqueTyOrigin::FnReturn { parent, .. }
-            | OpaqueTyOrigin::AsyncFn { parent, .. }
-            | OpaqueTyOrigin::TyAlias { parent, .. } => parent,
-        };
-        let param_env = tcx.param_env(parent);
-        let args = GenericArgs::identity_for_item(tcx, parent).extend_to(
-            tcx,
-            def_id.to_def_id(),
-            |param, _| {
-                tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into()
-            },
-        );
-
-        // FIXME(#132279): It feels wrong to use `non_body_analysis` here given that we're
-        // in a body here.
-        let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
-        let ocx = ObligationCtxt::new(&infcx);
-
-        let wf_tys = ocx.assumed_wf_types(param_env, parent).unwrap_or_else(|_| {
-            tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds");
-            Default::default()
-        });
-        let outlives_env = OutlivesEnvironment::new(&infcx, parent, param_env, wf_tys);
-
-        let mut seen = vec![tcx.lifetimes.re_static];
-        let canonical_args = fold_regions(tcx, args, |r1, _| {
-            if r1.is_error() {
-                r1
-            } else if let Some(&r2) = seen.iter().find(|&&r2| {
-                let free_regions = outlives_env.free_region_map();
-                free_regions.sub_free_regions(tcx, r1, r2)
-                    && free_regions.sub_free_regions(tcx, r2, r1)
-            }) {
-                r2
-            } else {
-                seen.push(r1);
-                r1
-            }
-        });
-        self.canonical_args.set(canonical_args).unwrap();
-        canonical_args
-    }
-}
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 4be5d0dbf42..5143b2fa205 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -295,17 +295,6 @@ pub(crate) struct MoveBorrow<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(borrowck_opaque_type_non_generic_param, code = E0792)]
-pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
-    pub ty: GenericArg<'tcx>,
-    pub kind: &'a str,
-    #[primary_span]
-    pub span: Span,
-    #[label]
-    pub param_span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(borrowck_opaque_type_lifetime_mismatch)]
 pub(crate) struct LifetimeMismatchOpaqueParam<'tcx> {
     pub arg: GenericArg<'tcx>,
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 3f03834f8d7..603dc90bafc 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -79,6 +79,7 @@ builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode}
 builtin_macros_autodiff_ty_activity = {$act} can not be used for this type
 builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}`
 
+builtin_macros_autodiff_width = autodiff width must fit u32, but is {$width}
 builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s
     .label = not applicable here
     .label2 = not a `struct`, `enum` or `union`
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index 1c1b2c88f76..ea406e70666 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -21,15 +21,15 @@ pub(crate) fn expand(
 
     // Allow using `#[alloc_error_handler]` on an item statement
     // FIXME - if we get deref patterns, use them to reduce duplication here
-    let (item, is_stmt, sig_span) = if let Annotatable::Item(item) = &item
+    let (item, ident, is_stmt, sig_span) = if let Annotatable::Item(item) = &item
         && let ItemKind::Fn(fn_kind) = &item.kind
     {
-        (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
+        (item, fn_kind.ident, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
     } else if let Annotatable::Stmt(stmt) = &item
         && let StmtKind::Item(item) = &stmt.kind
         && let ItemKind::Fn(fn_kind) = &item.kind
     {
-        (item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
+        (item, fn_kind.ident, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
     } else {
         ecx.dcx().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
         return vec![orig_item];
@@ -39,7 +39,7 @@ pub(crate) fn expand(
     let span = ecx.with_def_site_ctxt(item.span);
 
     // Generate item statements for the allocator methods.
-    let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)];
+    let stmts = thin_vec![generate_handler(ecx, ident, span, sig_span)];
 
     // Generate anonymous constant serving as container for the allocator methods.
     let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
@@ -85,6 +85,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
     let kind = ItemKind::Fn(Box::new(Fn {
         defaultness: ast::Defaultness::Final,
         sig,
+        ident: Ident::from_str_and_span("__rg_oom", span),
         generics: Generics::default(),
         contract: None,
         body,
@@ -93,6 +94,6 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
 
     let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
 
-    let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind);
+    let item = cx.item(span, attrs, kind);
     cx.stmt_item(sig_span, item)
 }
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index eb5b345e49e..3e8ddb8abd4 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -10,7 +10,7 @@ use rustc_index::bit_set::GrowableBitSet;
 use rustc_parse::exp;
 use rustc_parse::parser::{ExpKeywordPair, Parser};
 use rustc_session::lint;
-use rustc_span::{ErrorGuaranteed, Ident, InnerSpan, Span, Symbol, kw};
+use rustc_span::{ErrorGuaranteed, InnerSpan, Span, Symbol, kw};
 use rustc_target::asm::InlineAsmArch;
 use smallvec::smallvec;
 use {rustc_ast as ast, rustc_parse_format as parse};
@@ -888,7 +888,6 @@ pub(super) fn expand_global_asm<'cx>(
             };
             match mac {
                 Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item {
-                    ident: Ident::empty(),
                     attrs: ast::AttrVec::new(),
                     id: ast::DUMMY_NODE_ID,
                     kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index a949ab94f3a..ea7248ca539 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -112,7 +112,6 @@ impl<'cx, 'a> Context<'cx, 'a> {
             self.span,
             self.cx.item(
                 self.span,
-                Ident::empty(),
                 thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)],
                 ItemKind::Use(UseTree {
                     prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])),
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index be11711757e..7f99f75b2b9 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -12,12 +12,12 @@ mod llvm_enzyme {
         valid_ty_for_activity,
     };
     use rustc_ast::ptr::P;
-    use rustc_ast::token::{Token, TokenKind};
+    use rustc_ast::token::{Lit, LitKind, Token, TokenKind};
     use rustc_ast::tokenstream::*;
     use rustc_ast::visit::AssocCtxt::*;
     use rustc_ast::{
-        self as ast, AssocItemKind, BindingMode, FnRetTy, FnSig, Generics, ItemKind, MetaItemInner,
-        PatKind, TyKind,
+        self as ast, AssocItemKind, BindingMode, ExprKind, FnRetTy, FnSig, Generics, ItemKind,
+        MetaItemInner, PatKind, QSelf, TyKind,
     };
     use rustc_expand::base::{Annotatable, ExtCtxt};
     use rustc_span::{Ident, Span, Symbol, kw, sym};
@@ -45,6 +45,16 @@ mod llvm_enzyme {
         }
     }
     fn first_ident(x: &MetaItemInner) -> rustc_span::Ident {
+        if let Some(l) = x.lit() {
+            match l.kind {
+                ast::LitKind::Int(val, _) => {
+                    // get an Ident from a lit
+                    return rustc_span::Ident::from_str(val.get().to_string().as_str());
+                }
+                _ => {}
+            }
+        }
+
         let segments = &x.meta_item().unwrap().path.segments;
         assert!(segments.len() == 1);
         segments[0].ident
@@ -54,6 +64,14 @@ mod llvm_enzyme {
         first_ident(x).name.to_string()
     }
 
+    fn width(x: &MetaItemInner) -> Option<u128> {
+        let lit = x.lit()?;
+        match lit.kind {
+            ast::LitKind::Int(x, _) => Some(x.get()),
+            _ => return None,
+        }
+    }
+
     pub(crate) fn from_ast(
         ecx: &mut ExtCtxt<'_>,
         meta_item: &ThinVec<MetaItemInner>,
@@ -65,9 +83,32 @@ mod llvm_enzyme {
             dcx.emit_err(errors::AutoDiffInvalidMode { span: meta_item[1].span(), mode });
             return AutoDiffAttrs::error();
         };
+
+        // Now we check, whether the user wants autodiff in batch/vector mode, or scalar mode.
+        // If he doesn't specify an integer (=width), we default to scalar mode, thus width=1.
+        let mut first_activity = 2;
+
+        let width = if let [_, _, x, ..] = &meta_item[..]
+            && let Some(x) = width(x)
+        {
+            first_activity = 3;
+            match x.try_into() {
+                Ok(x) => x,
+                Err(_) => {
+                    dcx.emit_err(errors::AutoDiffInvalidWidth {
+                        span: meta_item[2].span(),
+                        width: x,
+                    });
+                    return AutoDiffAttrs::error();
+                }
+            }
+        } else {
+            1
+        };
+
         let mut activities: Vec<DiffActivity> = vec![];
         let mut errors = false;
-        for x in &meta_item[2..] {
+        for x in &meta_item[first_activity..] {
             let activity_str = name(&x);
             let res = DiffActivity::from_str(&activity_str);
             match res {
@@ -98,7 +139,20 @@ mod llvm_enzyme {
             (&DiffActivity::None, activities.as_slice())
         };
 
-        AutoDiffAttrs { mode, ret_activity: *ret_activity, input_activity: input_activity.to_vec() }
+        AutoDiffAttrs {
+            mode,
+            width,
+            ret_activity: *ret_activity,
+            input_activity: input_activity.to_vec(),
+        }
+    }
+
+    fn meta_item_inner_to_ts(t: &MetaItemInner, ts: &mut Vec<TokenTree>) {
+        let comma: Token = Token::new(TokenKind::Comma, Span::default());
+        let val = first_ident(t);
+        let t = Token::from_ast_ident(val);
+        ts.push(TokenTree::Token(t, Spacing::Joint));
+        ts.push(TokenTree::Token(comma.clone(), Spacing::Alone));
     }
 
     /// We expand the autodiff macro to generate a new placeholder function which passes
@@ -146,26 +200,26 @@ mod llvm_enzyme {
         }
         let dcx = ecx.sess.dcx();
         // first get the annotable item:
-        let (sig, is_impl): (FnSig, bool) = match &item {
+        let (primal, sig, is_impl): (Ident, FnSig, bool) = match &item {
             Annotatable::Item(iitem) => {
-                let sig = match &iitem.kind {
-                    ItemKind::Fn(box ast::Fn { sig, .. }) => sig,
+                let (ident, sig) = match &iitem.kind {
+                    ItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
                     _ => {
                         dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
                         return vec![item];
                     }
                 };
-                (sig.clone(), false)
+                (*ident, sig.clone(), false)
             }
             Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
-                let sig = match &assoc_item.kind {
-                    ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig,
+                let (ident, sig) = match &assoc_item.kind {
+                    ast::AssocItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
                     _ => {
                         dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
                         return vec![item];
                     }
                 };
-                (sig.clone(), true)
+                (*ident, sig.clone(), true)
             }
             _ => {
                 dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
@@ -184,11 +238,9 @@ mod llvm_enzyme {
         let has_ret = has_ret(&sig.decl.output);
         let sig_span = ecx.with_call_site_ctxt(sig.span);
 
-        let (vis, primal) = match &item {
-            Annotatable::Item(iitem) => (iitem.vis.clone(), iitem.ident.clone()),
-            Annotatable::AssocItem(assoc_item, _) => {
-                (assoc_item.vis.clone(), assoc_item.ident.clone())
-            }
+        let vis = match &item {
+            Annotatable::Item(iitem) => iitem.vis.clone(),
+            Annotatable::AssocItem(assoc_item, _) => assoc_item.vis.clone(),
             _ => {
                 dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
                 return vec![item];
@@ -197,27 +249,49 @@ mod llvm_enzyme {
 
         // create TokenStream from vec elemtents:
         // meta_item doesn't have a .tokens field
-        let comma: Token = Token::new(TokenKind::Comma, Span::default());
         let mut ts: Vec<TokenTree> = vec![];
         if meta_item_vec.len() < 2 {
             // At the bare minimum, we need a fnc name and a mode, even for a dummy function with no
             // input and output args.
             dcx.emit_err(errors::AutoDiffMissingConfig { span: item.span() });
             return vec![item];
+        }
+
+        meta_item_inner_to_ts(&meta_item_vec[1], &mut ts);
+
+        // Now, if the user gave a width (vector aka batch-mode ad), then we copy it.
+        // If it is not given, we default to 1 (scalar mode).
+        let start_position;
+        let kind: LitKind = LitKind::Integer;
+        let symbol;
+        if meta_item_vec.len() >= 3
+            && let Some(width) = width(&meta_item_vec[2])
+        {
+            start_position = 3;
+            symbol = Symbol::intern(&width.to_string());
         } else {
-            for t in meta_item_vec.clone()[1..].iter() {
-                let val = first_ident(t);
-                let t = Token::from_ast_ident(val);
-                ts.push(TokenTree::Token(t, Spacing::Joint));
-                ts.push(TokenTree::Token(comma.clone(), Spacing::Alone));
-            }
+            start_position = 2;
+            symbol = sym::integer(1);
+        }
+        let l: Lit = Lit { kind, symbol, suffix: None };
+        let t = Token::new(TokenKind::Literal(l), Span::default());
+        let comma = Token::new(TokenKind::Comma, Span::default());
+        ts.push(TokenTree::Token(t, Spacing::Joint));
+        ts.push(TokenTree::Token(comma.clone(), Spacing::Alone));
+
+        for t in meta_item_vec.clone()[start_position..].iter() {
+            meta_item_inner_to_ts(t, &mut ts);
         }
+
         if !has_ret {
             // We don't want users to provide a return activity if the function doesn't return anything.
             // For simplicity, we just add a dummy token to the end of the list.
             let t = Token::new(TokenKind::Ident(sym::None, false.into()), Span::default());
             ts.push(TokenTree::Token(t, Spacing::Joint));
+            ts.push(TokenTree::Token(comma, Spacing::Alone));
         }
+        // We remove the last, trailing comma.
+        ts.pop();
         let ts: TokenStream = TokenStream::from_iter(ts);
 
         let x: AutoDiffAttrs = from_ast(ecx, &meta_item_vec, has_ret);
@@ -237,12 +311,12 @@ mod llvm_enzyme {
         let d_body = gen_enzyme_body(
             ecx, &x, n_active, &sig, &d_sig, primal, &new_args, span, sig_span, idents, errored,
         );
-        let d_ident = first_ident(&meta_item_vec[0]);
 
         // The first element of it is the name of the function to be generated
         let asdf = Box::new(ast::Fn {
             defaultness: ast::Defaultness::Final,
             sig: d_sig,
+            ident: first_ident(&meta_item_vec[0]),
             generics: Generics::default(),
             contract: None,
             body: Some(d_body),
@@ -323,14 +397,12 @@ mod llvm_enzyme {
                 id: ast::DUMMY_NODE_ID,
                 span,
                 vis,
-                ident: d_ident,
                 kind: assoc_item,
                 tokens: None,
             });
             Annotatable::AssocItem(d_fn, Impl { of_trait: false })
         } else {
-            let mut d_fn =
-                ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
+            let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
             d_fn.vis = vis;
             Annotatable::Item(d_fn)
         };
@@ -474,6 +546,8 @@ mod llvm_enzyme {
             return body;
         }
 
+        // Everything from here onwards just tries to fullfil the return type. Fun!
+
         // having an active-only return means we'll drop the original return type.
         // So that can be treated identical to not having one in the first place.
         let primal_ret = has_ret(&sig.decl.output) && !x.has_active_only_ret();
@@ -501,86 +575,65 @@ mod llvm_enzyme {
             return body;
         }
 
-        let mut exprs = ThinVec::<P<ast::Expr>>::new();
-        if primal_ret {
-            // We have both primal ret and active floats.
-            // primal ret is first, by construction.
-            exprs.push(primal_call);
-        }
-
-        // Now construct default placeholder for each active float.
-        // Is there something nicer than f32::default() and f64::default()?
+        let mut exprs: P<ast::Expr> = primal_call.clone();
         let d_ret_ty = match d_sig.decl.output {
             FnRetTy::Ty(ref ty) => ty.clone(),
             FnRetTy::Default(span) => {
                 panic!("Did not expect Default ret ty: {:?}", span);
             }
         };
-        let mut d_ret_ty = match d_ret_ty.kind.clone() {
-            TyKind::Tup(ref tys) => tys.clone(),
-            TyKind::Path(_, rustc_ast::Path { segments, .. }) => {
-                if let [segment] = &segments[..]
-                    && segment.args.is_none()
-                {
-                    let id = vec![segments[0].ident];
-                    let kind = TyKind::Path(None, ecx.path(span, id));
-                    let ty = P(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span, tokens: None });
-                    thin_vec![ty]
-                } else {
-                    panic!("Expected tuple or simple path return type");
-                }
-            }
-            _ => {
-                // We messed up construction of d_sig
-                panic!("Did not expect non-tuple ret ty: {:?}", d_ret_ty);
-            }
-        };
-
-        if x.mode.is_fwd() && x.ret_activity == DiffActivity::Dual {
-            assert!(d_ret_ty.len() == 2);
-            // both should be identical, by construction
-            let arg = d_ret_ty[0].kind.is_simple_path().unwrap();
-            let arg2 = d_ret_ty[1].kind.is_simple_path().unwrap();
-            assert!(arg == arg2);
-            let sl: Vec<Symbol> = vec![arg, kw::Default];
-            let tmp = ecx.def_site_path(&sl);
-            let default_call_expr = ecx.expr_path(ecx.path(span, tmp));
-            let default_call_expr = ecx.expr_call(new_decl_span, default_call_expr, thin_vec![]);
-            exprs.push(default_call_expr);
-        } else if x.mode.is_rev() {
-            if primal_ret {
-                // We have extra handling above for the primal ret
-                d_ret_ty = d_ret_ty[1..].to_vec().into();
-            }
 
-            for arg in d_ret_ty.iter() {
-                let arg = arg.kind.is_simple_path().unwrap();
-                let sl: Vec<Symbol> = vec![arg, kw::Default];
-                let tmp = ecx.def_site_path(&sl);
-                let default_call_expr = ecx.expr_path(ecx.path(span, tmp));
+        if x.mode.is_fwd() {
+            // Fwd mode is easy. If the return activity is Const, we support arbitrary types.
+            // Otherwise, we only support a scalar, a pair of scalars, or an array of scalars.
+            // We checked that (on a best-effort base) in the preceding gen_enzyme_decl function.
+            // In all three cases, we can return `std::hint::black_box(<T>::default())`.
+            if x.ret_activity == DiffActivity::Const {
+                // Here we call the primal function, since our dummy function has the same return
+                // type due to the Const return activity.
+                exprs = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![exprs]);
+            } else {
+                let q = QSelf { ty: d_ret_ty.clone(), path_span: span, position: 0 };
+                let y =
+                    ExprKind::Path(Some(P(q)), ecx.path_ident(span, Ident::from_str("default")));
+                let default_call_expr = ecx.expr(span, y);
                 let default_call_expr =
                     ecx.expr_call(new_decl_span, default_call_expr, thin_vec![]);
-                exprs.push(default_call_expr);
-            }
-        }
-
-        let ret: P<ast::Expr>;
-        match &exprs[..] {
-            [] => {
-                assert!(!has_ret(&d_sig.decl.output));
-                // We don't have to match the return type.
-                return body;
+                exprs = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![default_call_expr]);
             }
-            [arg] => {
-                ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![arg.clone()]);
-            }
-            args => {
-                let ret_tuple: P<ast::Expr> = ecx.expr_tuple(span, args.into());
-                ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![ret_tuple]);
+        } else if x.mode.is_rev() {
+            if x.width == 1 {
+                // We either have `-> ArbitraryType` or `-> (ArbitraryType, repeated_float_scalars)`.
+                match d_ret_ty.kind {
+                    TyKind::Tup(ref args) => {
+                        // We have a tuple return type. We need to create a tuple of the same size
+                        // and fill it with default values.
+                        let mut exprs2 = thin_vec![exprs];
+                        for arg in args.iter().skip(1) {
+                            let arg = arg.kind.is_simple_path().unwrap();
+                            let sl: Vec<Symbol> = vec![arg, kw::Default];
+                            let tmp = ecx.def_site_path(&sl);
+                            let default_call_expr = ecx.expr_path(ecx.path(span, tmp));
+                            let default_call_expr =
+                                ecx.expr_call(new_decl_span, default_call_expr, thin_vec![]);
+                            exprs2.push(default_call_expr);
+                        }
+                        exprs = ecx.expr_tuple(new_decl_span, exprs2);
+                    }
+                    _ => {
+                        // Interestingly, even the `-> ArbitraryType` case
+                        // ends up getting matched and handled correctly above,
+                        // so we don't have to handle any other case for now.
+                        panic!("Unsupported return type: {:?}", d_ret_ty);
+                    }
+                }
             }
+            exprs = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![exprs]);
+        } else {
+            unreachable!("Unsupported mode: {:?}", x.mode);
         }
-        assert!(has_ret(&d_sig.decl.output));
-        body.stmts.push(ecx.stmt_expr(ret));
+
+        body.stmts.push(ecx.stmt_expr(exprs));
 
         body
     }
@@ -688,50 +741,55 @@ mod llvm_enzyme {
             match activity {
                 DiffActivity::Active => {
                     act_ret.push(arg.ty.clone());
+                    // if width =/= 1, then push [arg.ty; width] to act_ret
                 }
                 DiffActivity::ActiveOnly => {
                     // We will add the active scalar to the return type.
                     // This is handled later.
                 }
                 DiffActivity::Duplicated | DiffActivity::DuplicatedOnly => {
-                    let mut shadow_arg = arg.clone();
-                    // We += into the shadow in reverse mode.
-                    shadow_arg.ty = P(assure_mut_ref(&arg.ty));
-                    let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind {
-                        ident.name
-                    } else {
-                        debug!("{:#?}", &shadow_arg.pat);
-                        panic!("not an ident?");
-                    };
-                    let name: String = format!("d{}", old_name);
-                    new_inputs.push(name.clone());
-                    let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span);
-                    shadow_arg.pat = P(ast::Pat {
-                        id: ast::DUMMY_NODE_ID,
-                        kind: PatKind::Ident(BindingMode::NONE, ident, None),
-                        span: shadow_arg.pat.span,
-                        tokens: shadow_arg.pat.tokens.clone(),
-                    });
-                    d_inputs.push(shadow_arg);
+                    for i in 0..x.width {
+                        let mut shadow_arg = arg.clone();
+                        // We += into the shadow in reverse mode.
+                        shadow_arg.ty = P(assure_mut_ref(&arg.ty));
+                        let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind {
+                            ident.name
+                        } else {
+                            debug!("{:#?}", &shadow_arg.pat);
+                            panic!("not an ident?");
+                        };
+                        let name: String = format!("d{}_{}", old_name, i);
+                        new_inputs.push(name.clone());
+                        let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span);
+                        shadow_arg.pat = P(ast::Pat {
+                            id: ast::DUMMY_NODE_ID,
+                            kind: PatKind::Ident(BindingMode::NONE, ident, None),
+                            span: shadow_arg.pat.span,
+                            tokens: shadow_arg.pat.tokens.clone(),
+                        });
+                        d_inputs.push(shadow_arg.clone());
+                    }
                 }
                 DiffActivity::Dual | DiffActivity::DualOnly => {
-                    let mut shadow_arg = arg.clone();
-                    let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind {
-                        ident.name
-                    } else {
-                        debug!("{:#?}", &shadow_arg.pat);
-                        panic!("not an ident?");
-                    };
-                    let name: String = format!("b{}", old_name);
-                    new_inputs.push(name.clone());
-                    let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span);
-                    shadow_arg.pat = P(ast::Pat {
-                        id: ast::DUMMY_NODE_ID,
-                        kind: PatKind::Ident(BindingMode::NONE, ident, None),
-                        span: shadow_arg.pat.span,
-                        tokens: shadow_arg.pat.tokens.clone(),
-                    });
-                    d_inputs.push(shadow_arg);
+                    for i in 0..x.width {
+                        let mut shadow_arg = arg.clone();
+                        let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind {
+                            ident.name
+                        } else {
+                            debug!("{:#?}", &shadow_arg.pat);
+                            panic!("not an ident?");
+                        };
+                        let name: String = format!("b{}_{}", old_name, i);
+                        new_inputs.push(name.clone());
+                        let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span);
+                        shadow_arg.pat = P(ast::Pat {
+                            id: ast::DUMMY_NODE_ID,
+                            kind: PatKind::Ident(BindingMode::NONE, ident, None),
+                            span: shadow_arg.pat.span,
+                            tokens: shadow_arg.pat.tokens.clone(),
+                        });
+                        d_inputs.push(shadow_arg.clone());
+                    }
                 }
                 DiffActivity::Const => {
                     // Nothing to do here.
@@ -787,23 +845,48 @@ mod llvm_enzyme {
         d_decl.inputs = d_inputs.into();
 
         if x.mode.is_fwd() {
+            let ty = match d_decl.output {
+                FnRetTy::Ty(ref ty) => ty.clone(),
+                FnRetTy::Default(span) => {
+                    // We want to return std::hint::black_box(()).
+                    let kind = TyKind::Tup(ThinVec::new());
+                    let ty = P(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span, tokens: None });
+                    d_decl.output = FnRetTy::Ty(ty.clone());
+                    assert!(matches!(x.ret_activity, DiffActivity::None));
+                    // this won't be used below, so any type would be fine.
+                    ty
+                }
+            };
+
             if let DiffActivity::Dual = x.ret_activity {
-                let ty = match d_decl.output {
-                    FnRetTy::Ty(ref ty) => ty.clone(),
-                    FnRetTy::Default(span) => {
-                        panic!("Did not expect Default ret ty: {:?}", span);
-                    }
+                let kind = if x.width == 1 {
+                    // Dual can only be used for f32/f64 ret.
+                    // In that case we return now a tuple with two floats.
+                    TyKind::Tup(thin_vec![ty.clone(), ty.clone()])
+                } else {
+                    // We have to return [T; width+1], +1 for the primal return.
+                    let anon_const = rustc_ast::AnonConst {
+                        id: ast::DUMMY_NODE_ID,
+                        value: ecx.expr_usize(span, 1 + x.width as usize),
+                    };
+                    TyKind::Array(ty.clone(), anon_const)
                 };
-                // Dual can only be used for f32/f64 ret.
-                // In that case we return now a tuple with two floats.
-                let kind = TyKind::Tup(thin_vec![ty.clone(), ty.clone()]);
                 let ty = P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None });
                 d_decl.output = FnRetTy::Ty(ty);
             }
             if let DiffActivity::DualOnly = x.ret_activity {
                 // No need to change the return type,
-                // we will just return the shadow in place
-                // of the primal return.
+                // we will just return the shadow in place of the primal return.
+                // However, if we have a width > 1, then we don't return -> T, but -> [T; width]
+                if x.width > 1 {
+                    let anon_const = rustc_ast::AnonConst {
+                        id: ast::DUMMY_NODE_ID,
+                        value: ecx.expr_usize(span, x.width as usize),
+                    };
+                    let kind = TyKind::Array(ty.clone(), anon_const);
+                    let ty = P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None });
+                    d_decl.output = FnRetTy::Ty(ty);
+                }
             }
         }
 
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index c3656e8244f..44cf215c662 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -34,8 +34,8 @@ pub(crate) fn expand_deriving_clone(
     let is_simple;
     match item {
         Annotatable::Item(annitem) => match &annitem.kind {
-            ItemKind::Struct(_, Generics { params, .. })
-            | ItemKind::Enum(_, Generics { params, .. }) => {
+            ItemKind::Struct(_, _, Generics { params, .. })
+            | ItemKind::Enum(_, _, Generics { params, .. }) => {
                 let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
                 let has_derive_copy = cx.resolver.has_derive_copy(container_id);
                 if has_derive_copy
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 7958e037555..aa01da3151e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -21,7 +21,7 @@ pub(crate) fn expand_deriving_partial_ord(
 
     // Order in which to perform matching
     let discr_then_data = if let Annotatable::Item(item) = item
-        && let ItemKind::Enum(def, _) = &item.kind
+        && let ItemKind::Enum(_, def, _) = &item.kind
     {
         let dataful: Vec<bool> = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect();
         match dataful.iter().filter(|&&b| b).count() {
diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
index 46b79e09780..446d8afeedd 100644
--- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
@@ -30,7 +30,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
     item.visit_with(&mut DetectNonGenericPointeeAttr { cx });
 
     let (name_ident, generics) = if let Annotatable::Item(aitem) = item
-        && let ItemKind::Struct(struct_data, g) = &aitem.kind
+        && let ItemKind::Struct(ident, struct_data, g) = &aitem.kind
     {
         if !matches!(
             struct_data,
@@ -40,7 +40,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
             cx.dcx().emit_err(RequireOneField { span });
             return;
         }
-        (aitem.ident, g)
+        (*ident, g)
     } else {
         cx.dcx().emit_err(RequireTransparent { span });
         return;
@@ -108,7 +108,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
         push(Annotatable::Item(
             cx.item(
                 span,
-                Ident::empty(),
                 attrs.clone(),
                 ast::ItemKind::Impl(Box::new(ast::Impl {
                     safety: ast::Safety::Default,
@@ -153,7 +152,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
         let trait_ref = cx.trait_ref(trait_path);
         let item = cx.item(
             span,
-            Ident::empty(),
             attrs.clone(),
             ast::ItemKind::Impl(Box::new(ast::Impl {
                 safety: ast::Safety::Default,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 03ee59de70e..b9197be4442 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -487,28 +487,28 @@ impl<'a> TraitDef<'a> {
                 );
 
                 let newitem = match &item.kind {
-                    ast::ItemKind::Struct(struct_def, generics) => self.expand_struct_def(
+                    ast::ItemKind::Struct(ident, struct_def, generics) => self.expand_struct_def(
                         cx,
                         struct_def,
-                        item.ident,
+                        *ident,
                         generics,
                         from_scratch,
                         is_packed,
                     ),
-                    ast::ItemKind::Enum(enum_def, generics) => {
+                    ast::ItemKind::Enum(ident, enum_def, generics) => {
                         // We ignore `is_packed` here, because `repr(packed)`
                         // enums cause an error later on.
                         //
                         // This can only cause further compilation errors
                         // downstream in blatantly illegal code, so it is fine.
-                        self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch)
+                        self.expand_enum_def(cx, enum_def, *ident, generics, from_scratch)
                     }
-                    ast::ItemKind::Union(struct_def, generics) => {
+                    ast::ItemKind::Union(ident, struct_def, generics) => {
                         if self.supports_unions {
                             self.expand_struct_def(
                                 cx,
                                 struct_def,
-                                item.ident,
+                                *ident,
                                 generics,
                                 from_scratch,
                                 is_packed,
@@ -596,7 +596,6 @@ impl<'a> TraitDef<'a> {
             P(ast::AssocItem {
                 id: ast::DUMMY_NODE_ID,
                 span: self.span,
-                ident,
                 vis: ast::Visibility {
                     span: self.span.shrink_to_lo(),
                     kind: ast::VisibilityKind::Inherited,
@@ -605,6 +604,7 @@ impl<'a> TraitDef<'a> {
                 attrs: ast::AttrVec::new(),
                 kind: ast::AssocItemKind::Type(Box::new(ast::TyAlias {
                     defaultness: ast::Defaultness::Final,
+                    ident,
                     generics: Generics::default(),
                     where_clauses: ast::TyAliasWhereClauses::default(),
                     bounds: Vec::new(),
@@ -789,7 +789,6 @@ impl<'a> TraitDef<'a> {
 
         cx.item(
             self.span,
-            Ident::empty(),
             attrs,
             ast::ItemKind::Impl(Box::new(ast::Impl {
                 safety: ast::Safety::Default,
@@ -1033,10 +1032,10 @@ impl<'a> MethodDef<'a> {
                 kind: ast::VisibilityKind::Inherited,
                 tokens: None,
             },
-            ident: method_ident,
             kind: ast::AssocItemKind::Fn(Box::new(ast::Fn {
                 defaultness,
                 sig,
+                ident: method_ident,
                 generics: fn_generics,
                 contract: None,
                 body: Some(body_block),
diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs
index b39c9861fd6..ccfcc3079eb 100644
--- a/compiler/rustc_builtin_macros/src/edition_panic.rs
+++ b/compiler/rustc_builtin_macros/src/edition_panic.rs
@@ -74,11 +74,11 @@ pub(crate) fn use_panic_2021(mut span: Span) -> bool {
     // (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.)
     loop {
         let expn = span.ctxt().outer_expn_data();
-        if let Some(features) = expn.allow_internal_unstable {
-            if features.iter().any(|&f| f == sym::edition_panic) {
-                span = expn.call_site;
-                continue;
-            }
+        if let Some(features) = expn.allow_internal_unstable
+            && features.contains(&sym::edition_panic)
+        {
+            span = expn.call_site;
+            continue;
         }
         break expn.edition >= Edition::Edition2021;
     }
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 30597944124..4bbe212f429 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -203,6 +203,14 @@ mod autodiff {
     }
 
     #[derive(Diagnostic)]
+    #[diag(builtin_macros_autodiff_width)]
+    pub(crate) struct AutoDiffInvalidWidth {
+        #[primary_span]
+        pub(crate) span: Span,
+        pub(crate) width: u128,
+    }
+
+    #[derive(Diagnostic)]
     #[diag(builtin_macros_autodiff)]
     pub(crate) struct AutoDiffInvalidApplication {
         #[primary_span]
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 90d79235820..4b1958bce32 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -25,15 +25,15 @@ pub(crate) fn expand(
 
     // Allow using `#[global_allocator]` on an item statement
     // FIXME - if we get deref patterns, use them to reduce duplication here
-    let (item, is_stmt, ty_span) = if let Annotatable::Item(item) = &item
-        && let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind
+    let (item, ident, is_stmt, ty_span) = if let Annotatable::Item(item) = &item
+        && let ItemKind::Static(box ast::StaticItem { ident, ty, .. }) = &item.kind
     {
-        (item, false, ecx.with_def_site_ctxt(ty.span))
+        (item, *ident, false, ecx.with_def_site_ctxt(ty.span))
     } else if let Annotatable::Stmt(stmt) = &item
         && let StmtKind::Item(item) = &stmt.kind
-        && let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind
+        && let ItemKind::Static(box ast::StaticItem { ident, ty, .. }) = &item.kind
     {
-        (item, true, ecx.with_def_site_ctxt(ty.span))
+        (item, *ident, true, ecx.with_def_site_ctxt(ty.span))
     } else {
         ecx.dcx().emit_err(errors::AllocMustStatics { span: item.span() });
         return vec![orig_item];
@@ -41,7 +41,7 @@ pub(crate) fn expand(
 
     // Generate a bunch of new items using the AllocFnFactory
     let span = ecx.with_def_site_ctxt(item.span);
-    let f = AllocFnFactory { span, ty_span, global: item.ident, cx: ecx };
+    let f = AllocFnFactory { span, ty_span, global: ident, cx: ecx };
 
     // Generate item statements for the allocator methods.
     let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect();
@@ -80,17 +80,13 @@ impl AllocFnFactory<'_, '_> {
         let kind = ItemKind::Fn(Box::new(Fn {
             defaultness: ast::Defaultness::Final,
             sig,
+            ident: Ident::from_str_and_span(&global_fn_name(method.name), self.span),
             generics: Generics::default(),
             contract: None,
             body,
             define_opaque: None,
         }));
-        let item = self.cx.item(
-            self.span,
-            Ident::from_str_and_span(&global_fn_name(method.name), self.span),
-            self.attrs(),
-            kind,
-        );
+        let item = self.cx.item(self.span, self.attrs(), kind);
         self.cx.stmt_item(self.ty_span, item)
     }
 
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index ee6475c8b8e..8862965c053 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -92,7 +92,12 @@ impl<'a> CollectProcMacros<'a> {
         }
     }
 
-    fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
+    fn collect_custom_derive(
+        &mut self,
+        item: &'a ast::Item,
+        function_name: Ident,
+        attr: &'a ast::Attribute,
+    ) {
         let Some((trait_name, proc_attrs)) =
             parse_macro_name_and_helper_attrs(self.dcx, attr, "derive")
         else {
@@ -104,7 +109,7 @@ impl<'a> CollectProcMacros<'a> {
                 id: item.id,
                 span: item.span,
                 trait_name,
-                function_name: item.ident,
+                function_name,
                 attrs: proc_attrs,
             }));
         } else {
@@ -118,12 +123,12 @@ impl<'a> CollectProcMacros<'a> {
         }
     }
 
-    fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) {
+    fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
         if self.in_root && item.vis.kind.is_pub() {
             self.macros.push(ProcMacro::Attr(ProcMacroDef {
                 id: item.id,
                 span: item.span,
-                function_name: item.ident,
+                function_name,
             }));
         } else {
             let msg = if !self.in_root {
@@ -136,12 +141,12 @@ impl<'a> CollectProcMacros<'a> {
         }
     }
 
-    fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
+    fn collect_bang_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
         if self.in_root && item.vis.kind.is_pub() {
             self.macros.push(ProcMacro::Bang(ProcMacroDef {
                 id: item.id,
                 span: item.span,
-                function_name: item.ident,
+                function_name,
             }));
         } else {
             let msg = if !self.in_root {
@@ -165,12 +170,6 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
             }
         }
 
-        // First up, make sure we're checking a bare function. If we're not then
-        // we're just not interested in this item.
-        //
-        // If we find one, try to locate a `#[proc_macro_derive]` attribute on it.
-        let is_fn = matches!(item.kind, ast::ItemKind::Fn(..));
-
         let mut found_attr: Option<&'a ast::Attribute> = None;
 
         for attr in &item.attrs {
@@ -214,7 +213,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
             return;
         };
 
-        if !is_fn {
+        // Make sure we're checking a bare function. If we're not then we're
+        // just not interested any further in this item.
+        let fn_ident = if let ast::ItemKind::Fn(fn_) = &item.kind {
+            fn_.ident
+        } else {
             self.dcx
                 .create_err(errors::AttributeOnlyBeUsedOnBareFunctions {
                     span: attr.span,
@@ -222,7 +225,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
                 })
                 .emit();
             return;
-        }
+        };
 
         if self.is_test_crate {
             return;
@@ -238,12 +241,13 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
             return;
         }
 
+        // Try to locate a `#[proc_macro_derive]` attribute.
         if attr.has_name(sym::proc_macro_derive) {
-            self.collect_custom_derive(item, attr);
+            self.collect_custom_derive(item, fn_ident, attr);
         } else if attr.has_name(sym::proc_macro_attribute) {
-            self.collect_attr_proc_macro(item);
+            self.collect_attr_proc_macro(item, fn_ident);
         } else if attr.has_name(sym::proc_macro) {
-            self.collect_bang_proc_macro(item);
+            self.collect_bang_proc_macro(item, fn_ident);
         };
 
         let prev_in_root = mem::replace(&mut self.in_root, false);
@@ -278,7 +282,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
     let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
 
     let proc_macro = Ident::new(sym::proc_macro, span);
-    let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
+    let krate = cx.item(span, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, proc_macro));
 
     let bridge = Ident::new(sym::bridge, span);
     let client = Ident::new(sym::client, span);
diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index ba63b185e09..a1ee53b7ca2 100644
--- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
@@ -43,9 +43,8 @@ pub fn inject(
 
     let item = cx.item(
         span,
-        Ident::new(name, ident_span),
         thin_vec![cx.attr_word(sym::macro_use, span)],
-        ast::ItemKind::ExternCrate(None),
+        ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)),
     );
 
     krate.items.insert(0, item);
@@ -68,7 +67,6 @@ pub fn inject(
     // Inject the relevant crate's prelude.
     let use_item = cx.item(
         span,
-        Ident::empty(),
         thin_vec![cx.attr_word(sym::prelude_import, span)],
         ast::ItemKind::Use(ast::UseTree {
             prefix: cx.path(span, import_path),
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 239f8657284..1cef4f9514c 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -51,21 +51,28 @@ pub(crate) fn expand_test_case(
             return vec![];
         }
     };
-    item = item.map(|mut item| {
-        let test_path_symbol = Symbol::intern(&item_path(
-            // skip the name of the root module
-            &ecx.current_expansion.module.mod_path[1..],
-            &item.ident,
-        ));
-        item.vis = ast::Visibility {
-            span: item.vis.span,
-            kind: ast::VisibilityKind::Public,
-            tokens: None,
-        };
-        item.ident.span = item.ident.span.with_ctxt(sp.ctxt());
-        item.attrs.push(ecx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, sp));
-        item
-    });
+
+    // `#[test_case]` is valid on functions, consts, and statics. Only modify
+    // the item in those cases.
+    match &mut item.kind {
+        ast::ItemKind::Fn(box ast::Fn { ident, .. })
+        | ast::ItemKind::Const(box ast::ConstItem { ident, .. })
+        | ast::ItemKind::Static(box ast::StaticItem { ident, .. }) => {
+            ident.span = ident.span.with_ctxt(sp.ctxt());
+            let test_path_symbol = Symbol::intern(&item_path(
+                // skip the name of the root module
+                &ecx.current_expansion.module.mod_path[1..],
+                ident,
+            ));
+            item.vis = ast::Visibility {
+                span: item.vis.span,
+                kind: ast::VisibilityKind::Public,
+                tokens: None,
+            };
+            item.attrs.push(ecx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, sp));
+        }
+        _ => {}
+    }
 
     let ret = if is_stmt {
         Annotatable::Stmt(P(ecx.stmt_item(item.span, item)))
@@ -162,17 +169,17 @@ pub(crate) fn expand_test_or_bench(
     let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span());
     let attr_sp = cx.with_def_site_ctxt(attr_sp);
 
-    let test_id = Ident::new(sym::test, attr_sp);
+    let test_ident = Ident::new(sym::test, attr_sp);
 
     // creates test::$name
-    let test_path = |name| cx.path(ret_ty_sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
+    let test_path = |name| cx.path(ret_ty_sp, vec![test_ident, Ident::from_str_and_span(name, sp)]);
 
     // creates test::ShouldPanic::$name
     let should_panic_path = |name| {
         cx.path(
             sp,
             vec![
-                test_id,
+                test_ident,
                 Ident::from_str_and_span("ShouldPanic", sp),
                 Ident::from_str_and_span(name, sp),
             ],
@@ -184,7 +191,7 @@ pub(crate) fn expand_test_or_bench(
         cx.path(
             sp,
             vec![
-                test_id,
+                test_ident,
                 Ident::from_str_and_span("TestType", sp),
                 Ident::from_str_and_span(name, sp),
             ],
@@ -223,7 +230,7 @@ pub(crate) fn expand_test_or_bench(
                             // super::$test_fn(b)
                             cx.expr_call(
                                 ret_ty_sp,
-                                cx.expr_path(cx.path(sp, vec![item.ident])),
+                                cx.expr_path(cx.path(sp, vec![fn_.ident])),
                                 thin_vec![cx.expr_ident(sp, b)],
                             ),
                         ],
@@ -249,7 +256,7 @@ pub(crate) fn expand_test_or_bench(
                             // $test_fn()
                             cx.expr_call(
                                 ret_ty_sp,
-                                cx.expr_path(cx.path(sp, vec![item.ident])),
+                                cx.expr_path(cx.path(sp, vec![fn_.ident])),
                                 ThinVec::new(),
                             ), // )
                         ],
@@ -262,15 +269,14 @@ pub(crate) fn expand_test_or_bench(
     let test_path_symbol = Symbol::intern(&item_path(
         // skip the name of the root module
         &cx.current_expansion.module.mod_path[1..],
-        &item.ident,
+        &fn_.ident,
     ));
 
-    let location_info = get_location_info(cx, &item);
+    let location_info = get_location_info(cx, &fn_);
 
     let mut test_const =
         cx.item(
             sp,
-            Ident::new(item.ident.name, sp),
             thin_vec![
                 // #[cfg(test)]
                 cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
@@ -283,6 +289,7 @@ pub(crate) fn expand_test_or_bench(
             ast::ItemKind::Const(
                 ast::ConstItem {
                     defaultness: ast::Defaultness::Final,
+                    ident: Ident::new(fn_.ident.name, sp),
                     generics: ast::Generics::default(),
                     ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
                     define_opaque: None,
@@ -380,7 +387,8 @@ pub(crate) fn expand_test_or_bench(
     });
 
     // extern crate test
-    let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
+    let test_extern =
+        cx.item(sp, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, test_ident));
 
     debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
 
@@ -434,8 +442,8 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
         .emit();
 }
 
-fn get_location_info(cx: &ExtCtxt<'_>, item: &ast::Item) -> (Symbol, usize, usize, usize, usize) {
-    let span = item.ident.span;
+fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, usize, usize) {
+    let span = fn_.ident.span;
     let (source_file, lo_line, lo_col, hi_line, hi_col) =
         cx.sess.source_map().span_to_location_info(span);
 
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 768b459ec5e..56a67b0534d 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -134,7 +134,8 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
         if let Some(name) = get_test_name(&item) {
             debug!("this is a test item");
 
-            let test = Test { span: item.span, ident: item.ident, name };
+            // `unwrap` is ok because only functions, consts, and static should reach here.
+            let test = Test { span: item.span, ident: item.kind.ident().unwrap(), name };
             self.tests.push(test);
         }
 
@@ -142,19 +143,12 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
         // mods or tests inside of functions will break things
         if let ast::ItemKind::Mod(
             _,
+            _,
             ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _),
         ) = item.kind
         {
             let prev_tests = mem::take(&mut self.tests);
-            walk_item_kind(
-                &mut item.kind,
-                item.span,
-                item.id,
-                &mut item.ident,
-                &mut item.vis,
-                (),
-                self,
-            );
+            walk_item_kind(&mut item.kind, item.span, item.id, &mut item.vis, (), self);
             self.add_test_cases(item.id, span, prev_tests);
         } else {
             // But in those cases, we emit a lint to warn the user of these missing tests.
@@ -181,9 +175,9 @@ impl<'a> Visitor<'a> for InnerItemLinter<'_> {
 }
 
 fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType {
-    match item.kind {
-        ast::ItemKind::Fn(..) => {
-            rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(item.ident.name))
+    match &item.kind {
+        ast::ItemKind::Fn(fn_) => {
+            rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(fn_.ident.name))
         }
         _ => EntryPointType::None,
     }
@@ -295,7 +289,7 @@ fn generate_test_harness(
 fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     let sp = cx.def_site;
     let ecx = &cx.ext_cx;
-    let test_id = Ident::new(sym::test, sp);
+    let test_ident = Ident::new(sym::test, sp);
 
     let runner_name = match cx.panic_strategy {
         PanicStrategy::Unwind => "test_main_static",
@@ -303,10 +297,9 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     };
 
     // test::test_main_static(...)
-    let mut test_runner = cx
-        .test_runner
-        .clone()
-        .unwrap_or_else(|| ecx.path(sp, vec![test_id, Ident::from_str_and_span(runner_name, sp)]));
+    let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| {
+        ecx.path(sp, vec![test_ident, Ident::from_str_and_span(runner_name, sp)])
+    });
 
     test_runner.span = sp;
 
@@ -317,7 +310,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     // extern crate test
     let test_extern_stmt = ecx.stmt_item(
         sp,
-        ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)),
+        ecx.item(sp, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, test_ident)),
     );
 
     // #[rustc_main]
@@ -340,23 +333,24 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     let decl = ecx.fn_decl(ThinVec::new(), ast::FnRetTy::Ty(main_ret_ty));
     let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
     let defaultness = ast::Defaultness::Final;
+
+    // Honor the reexport_test_harness_main attribute
+    let main_ident = match cx.reexport_test_harness_main {
+        Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
+        None => Ident::new(sym::main, sp),
+    };
+
     let main = ast::ItemKind::Fn(Box::new(ast::Fn {
         defaultness,
         sig,
+        ident: main_ident,
         generics: ast::Generics::default(),
         contract: None,
         body: Some(main_body),
         define_opaque: None,
     }));
 
-    // Honor the reexport_test_harness_main attribute
-    let main_id = match cx.reexport_test_harness_main {
-        Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
-        None => Ident::new(sym::main, sp),
-    };
-
     let main = P(ast::Item {
-        ident: main_id,
         attrs: thin_vec![main_attr, coverage_attr, doc_hidden_attr],
         id: ast::DUMMY_NODE_ID,
         kind: main,
diff --git a/compiler/rustc_codegen_cranelift/.cirrus.yml b/compiler/rustc_codegen_cranelift/.cirrus.yml
index 1ec99eb3d17..ee5de8b42f4 100644
--- a/compiler/rustc_codegen_cranelift/.cirrus.yml
+++ b/compiler/rustc_codegen_cranelift/.cirrus.yml
@@ -1,20 +1,21 @@
-task:
-  name: freebsd
-  freebsd_instance:
-    image: freebsd-13-2-release-amd64
-  setup_rust_script:
-    - pkg install -y git-tiny binutils
-    - curl https://sh.rustup.rs -sSf --output rustup.sh
-    - sh rustup.sh --default-toolchain none -y --profile=minimal
-  target_cache:
-    folder: build/cg_clif
-  prepare_script:
-    - . $HOME/.cargo/env
-    - ./y.sh prepare
-  test_script:
-    - . $HOME/.cargo/env
-    # Disabling incr comp reduces cache size and incr comp doesn't save as much
-    # on CI anyway.
-    - export CARGO_BUILD_INCREMENTAL=false
-    # Skip rand as it fails on FreeBSD due to rust-random/rand#1355
-    - ./y.sh test --skip-test test.rust-random/rand
+# FIXME re-enable once https://github.com/rust-lang/rust/issues/134863 is fixed.
+# task:
+#   name: freebsd
+#   freebsd_instance:
+#     image: freebsd-13-2-release-amd64
+#   setup_rust_script:
+#     - pkg install -y git-tiny binutils
+#     - curl https://sh.rustup.rs -sSf --output rustup.sh
+#     - sh rustup.sh --default-toolchain none -y --profile=minimal
+#   target_cache:
+#     folder: build/cg_clif
+#   prepare_script:
+#     - . $HOME/.cargo/env
+#     - ./y.sh prepare
+#   test_script:
+#     - . $HOME/.cargo/env
+#     # Disabling incr comp reduces cache size and incr comp doesn't save as much
+#     # on CI anyway.
+#     - export CARGO_BUILD_INCREMENTAL=false
+#     # Skip rand as it fails on FreeBSD due to rust-random/rand#1355
+#     - ./y.sh test --skip-test test.rust-random/rand
diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md b/compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md
deleted file mode 100644
index c70ba8f4953..00000000000
--- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# github-release
-
-An action used to publish GitHub releases for `wasmtime`.
-
-As of the time of this writing there's a few actions floating around which
-perform github releases but they all tend to have their set of drawbacks.
-Additionally nothing handles deleting releases which we need for our rolling
-`dev` release.
-
-To handle all this this action rolls-its-own implementation using the
-actions/toolkit repository and packages published there. These run in a Docker
-container and take various inputs to orchestrate the release from the build.
-
-More comments can be found in `main.js`.
-
-Testing this is really hard. If you want to try though run `npm install` and
-then `node main.js`. You'll have to configure a bunch of env vars though to get
-anything reasonably working.
diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml b/compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml
deleted file mode 100644
index 36e5209f50c..00000000000
--- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-name: 'rustc_codegen_cranelift github releases'
-description: 'rustc_codegen_cranelift github releases'
-inputs:
-  token:
-    description: ''
-    required: true
-  files:
-    description: ''
-    required: true
-runs:
-  using: 'node16'
-  main: 'main.js'
diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js b/compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js
deleted file mode 100644
index 1eb2b7f23b2..00000000000
--- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js
+++ /dev/null
@@ -1,162 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-const core = require('@actions/core');
-const path = require("path");
-const fs = require("fs");
-const github = require('@actions/github');
-const glob = require('glob');
-
-function sleep(milliseconds) {
-  return new Promise(resolve => setTimeout(resolve, milliseconds))
-}
-
-async function runOnce() {
-  // Load all our inputs and env vars. Note that `getInput` reads from `INPUT_*`
-  const files = core.getInput('files');
-  const token = core.getInput('token');
-  const slug = process.env.GITHUB_REPOSITORY;
-  const owner = slug.split('/')[0];
-  const repo = slug.split('/')[1];
-  const sha = process.env.GITHUB_SHA;
-  let name = 'dev';
-  if (process.env.GITHUB_REF.startsWith('refs/tags/v')) {
-    name = process.env.GITHUB_REF.substring(10);
-  }
-
-  core.info(`files: ${files}`);
-  core.info(`name: ${name}`);
-  core.info(`token: ${token}`);
-
-  const octokit = github.getOctokit(token);
-
-  // For the `dev` release we may need to update the tag to point to the new
-  // commit on this branch. All other names should already have tags associated
-  // with them.
-  if (name == 'dev') {
-    let tag = null;
-    try {
-      tag = await octokit.request("GET /repos/:owner/:repo/git/refs/tags/:name", { owner, repo, name });
-      core.info(`found existing tag`);
-      console.log("tag: ", JSON.stringify(tag.data, null, 2));
-    } catch (e) {
-      // ignore if this tag doesn't exist
-      core.info(`no existing tag found`);
-    }
-
-    if (tag === null || tag.data.object.sha !== sha) {
-      core.info(`updating existing tag or creating new one`);
-
-      try {
-        core.info(`updating dev tag`);
-        await octokit.rest.git.updateRef({
-          owner,
-          repo,
-          ref: 'tags/dev',
-          sha,
-          force: true,
-        });
-      } catch (e) {
-        console.log("ERROR: ", JSON.stringify(e.response, null, 2));
-        core.info(`creating dev tag`);
-        try {
-          await octokit.rest.git.createRef({
-            owner,
-            repo,
-            ref: 'refs/tags/dev',
-            sha,
-          });
-        } catch (e) {
-          // we might race with others, so assume someone else has created the
-          // tag by this point.
-          console.log("failed to create tag: ", JSON.stringify(e.response, null, 2));
-        }
-      }
-
-      console.log("double-checking tag is correct");
-      tag = await octokit.request("GET /repos/:owner/:repo/git/refs/tags/:name", { owner, repo, name });
-      if (tag.data.object.sha !== sha) {
-        console.log("tag: ", JSON.stringify(tag.data, null, 2));
-        throw new Error("tag didn't work");
-      }
-    } else {
-      core.info(`existing tag works`);
-    }
-  }
-
-  // Delete a previous release
-  try {
-    core.info(`fetching release`);
-    let release = await octokit.rest.repos.getReleaseByTag({ owner, repo, tag: name });
-    console.log("found release: ", JSON.stringify(release.data, null, 2));
-    await octokit.rest.repos.deleteRelease({
-      owner,
-      repo,
-      release_id: release.data.id,
-    });
-    console.log("deleted release");
-  } catch (e) {
-    console.log("ERROR: ", JSON.stringify(e, null, 2));
-  }
-
-  console.log("creating a release");
-  let release = await octokit.rest.repos.createRelease({
-    owner,
-    repo,
-    tag_name: name,
-    prerelease: name === 'dev',
-  });
-
-  // Delete all assets from a previous run
-  for (const asset of release.data.assets) {
-    console.log(`deleting prior asset ${asset.id}`);
-    await octokit.rest.repos.deleteReleaseAsset({
-      owner,
-      repo,
-      asset_id: asset.id,
-    });
-  }
-
-  // Upload all the relevant assets for this release as just general blobs.
-  for (const file of glob.sync(files)) {
-    const size = fs.statSync(file).size;
-    const name = path.basename(file);
-    core.info(`upload ${file}`);
-    await octokit.rest.repos.uploadReleaseAsset({
-      data: fs.createReadStream(file),
-      headers: { 'content-length': size, 'content-type': 'application/octet-stream' },
-      name,
-      url: release.data.upload_url,
-    });
-  }
-}
-
-async function run() {
-  const retries = 10;
-  for (let i = 0; i < retries; i++) {
-    try {
-      await runOnce();
-      break;
-    } catch (e) {
-      if (i === retries - 1)
-        throw e;
-      logError(e);
-      console.log("RETRYING after 10s");
-      await sleep(10000)
-    }
-  }
-}
-
-function logError(e) {
-  console.log("ERROR: ", e.message);
-  try {
-    console.log(JSON.stringify(e, null, 2));
-  } catch (e) {
-    // ignore json errors for now
-  }
-  console.log(e.stack);
-}
-
-run().catch(err => {
-  logError(err);
-  core.setFailed(err.message);
-});
diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json b/compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json
deleted file mode 100644
index dd3b2a048f0..00000000000
--- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json
+++ /dev/null
@@ -1,571 +0,0 @@
-{
-  "name": "rustc_codegen_cranelift-github-release",
-  "version": "0.0.0",
-  "lockfileVersion": 2,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "rustc_codegen_cranelift-github-release",
-      "version": "0.0.0",
-      "dependencies": {
-        "@actions/core": "^1.9.1",
-        "@actions/github": "^5.1.0",
-        "glob": "^7.1.5"
-      }
-    },
-    "node_modules/@actions/core": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
-      "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
-      "dependencies": {
-        "@actions/http-client": "^2.0.1",
-        "uuid": "^8.3.2"
-      }
-    },
-    "node_modules/@actions/github": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.0.tgz",
-      "integrity": "sha512-tuI80F7JQIhg77ZTTgUAPpVD7ZnP9oHSPN8xw7LOwtA4vEMbAjWJNbmLBfV7xua7r016GyjzWLuec5cs8f/a8A==",
-      "dependencies": {
-        "@actions/http-client": "^2.0.1",
-        "@octokit/core": "^3.6.0",
-        "@octokit/plugin-paginate-rest": "^2.17.0",
-        "@octokit/plugin-rest-endpoint-methods": "^5.13.0"
-      }
-    },
-    "node_modules/@actions/http-client": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
-      "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
-      "dependencies": {
-        "tunnel": "^0.0.6"
-      }
-    },
-    "node_modules/@octokit/auth-token": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
-      "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
-      "dependencies": {
-        "@octokit/types": "^6.0.3"
-      }
-    },
-    "node_modules/@octokit/core": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
-      "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
-      "dependencies": {
-        "@octokit/auth-token": "^2.4.4",
-        "@octokit/graphql": "^4.5.8",
-        "@octokit/request": "^5.6.3",
-        "@octokit/request-error": "^2.0.5",
-        "@octokit/types": "^6.0.3",
-        "before-after-hook": "^2.2.0",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "node_modules/@octokit/endpoint": {
-      "version": "6.0.12",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
-      "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
-      "dependencies": {
-        "@octokit/types": "^6.0.3",
-        "is-plain-object": "^5.0.0",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "node_modules/@octokit/graphql": {
-      "version": "4.8.0",
-      "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
-      "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
-      "dependencies": {
-        "@octokit/request": "^5.6.0",
-        "@octokit/types": "^6.0.3",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "node_modules/@octokit/openapi-types": {
-      "version": "12.11.0",
-      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
-      "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
-    },
-    "node_modules/@octokit/plugin-paginate-rest": {
-      "version": "2.21.3",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
-      "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
-      "dependencies": {
-        "@octokit/types": "^6.40.0"
-      },
-      "peerDependencies": {
-        "@octokit/core": ">=2"
-      }
-    },
-    "node_modules/@octokit/plugin-rest-endpoint-methods": {
-      "version": "5.16.2",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
-      "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
-      "dependencies": {
-        "@octokit/types": "^6.39.0",
-        "deprecation": "^2.3.1"
-      },
-      "peerDependencies": {
-        "@octokit/core": ">=3"
-      }
-    },
-    "node_modules/@octokit/request": {
-      "version": "5.6.3",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
-      "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
-      "dependencies": {
-        "@octokit/endpoint": "^6.0.1",
-        "@octokit/request-error": "^2.1.0",
-        "@octokit/types": "^6.16.1",
-        "is-plain-object": "^5.0.0",
-        "node-fetch": "^2.6.7",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "node_modules/@octokit/request-error": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
-      "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
-      "dependencies": {
-        "@octokit/types": "^6.0.3",
-        "deprecation": "^2.0.0",
-        "once": "^1.4.0"
-      }
-    },
-    "node_modules/@octokit/types": {
-      "version": "6.41.0",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
-      "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
-      "dependencies": {
-        "@octokit/openapi-types": "^12.11.0"
-      }
-    },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
-    },
-    "node_modules/before-after-hook": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
-      "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
-    },
-    "node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
-    },
-    "node_modules/deprecation": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
-      "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
-    },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
-    },
-    "node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
-    },
-    "node_modules/is-plain-object": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
-      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/node-fetch": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
-      "dependencies": {
-        "whatwg-url": "^5.0.0"
-      },
-      "engines": {
-        "node": "4.x || >=6.0.0"
-      },
-      "peerDependencies": {
-        "encoding": "^0.1.0"
-      },
-      "peerDependenciesMeta": {
-        "encoding": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
-    },
-    "node_modules/tunnel": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
-      "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
-      "engines": {
-        "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
-      }
-    },
-    "node_modules/universal-user-agent": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
-      "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
-    },
-    "node_modules/uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
-      "bin": {
-        "uuid": "dist/bin/uuid"
-      }
-    },
-    "node_modules/webidl-conversions": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
-    },
-    "node_modules/whatwg-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
-      "dependencies": {
-        "tr46": "~0.0.3",
-        "webidl-conversions": "^3.0.0"
-      }
-    },
-    "node_modules/wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
-    }
-  },
-  "dependencies": {
-    "@actions/core": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
-      "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
-      "requires": {
-        "@actions/http-client": "^2.0.1",
-        "uuid": "^8.3.2"
-      }
-    },
-    "@actions/github": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.0.tgz",
-      "integrity": "sha512-tuI80F7JQIhg77ZTTgUAPpVD7ZnP9oHSPN8xw7LOwtA4vEMbAjWJNbmLBfV7xua7r016GyjzWLuec5cs8f/a8A==",
-      "requires": {
-        "@actions/http-client": "^2.0.1",
-        "@octokit/core": "^3.6.0",
-        "@octokit/plugin-paginate-rest": "^2.17.0",
-        "@octokit/plugin-rest-endpoint-methods": "^5.13.0"
-      }
-    },
-    "@actions/http-client": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
-      "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
-      "requires": {
-        "tunnel": "^0.0.6"
-      }
-    },
-    "@octokit/auth-token": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
-      "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
-      "requires": {
-        "@octokit/types": "^6.0.3"
-      }
-    },
-    "@octokit/core": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
-      "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
-      "requires": {
-        "@octokit/auth-token": "^2.4.4",
-        "@octokit/graphql": "^4.5.8",
-        "@octokit/request": "^5.6.3",
-        "@octokit/request-error": "^2.0.5",
-        "@octokit/types": "^6.0.3",
-        "before-after-hook": "^2.2.0",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "@octokit/endpoint": {
-      "version": "6.0.12",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
-      "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
-      "requires": {
-        "@octokit/types": "^6.0.3",
-        "is-plain-object": "^5.0.0",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "@octokit/graphql": {
-      "version": "4.8.0",
-      "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
-      "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
-      "requires": {
-        "@octokit/request": "^5.6.0",
-        "@octokit/types": "^6.0.3",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "@octokit/openapi-types": {
-      "version": "12.11.0",
-      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
-      "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
-    },
-    "@octokit/plugin-paginate-rest": {
-      "version": "2.21.3",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
-      "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
-      "requires": {
-        "@octokit/types": "^6.40.0"
-      }
-    },
-    "@octokit/plugin-rest-endpoint-methods": {
-      "version": "5.16.2",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
-      "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
-      "requires": {
-        "@octokit/types": "^6.39.0",
-        "deprecation": "^2.3.1"
-      }
-    },
-    "@octokit/request": {
-      "version": "5.6.3",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
-      "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
-      "requires": {
-        "@octokit/endpoint": "^6.0.1",
-        "@octokit/request-error": "^2.1.0",
-        "@octokit/types": "^6.16.1",
-        "is-plain-object": "^5.0.0",
-        "node-fetch": "^2.6.7",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "@octokit/request-error": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
-      "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
-      "requires": {
-        "@octokit/types": "^6.0.3",
-        "deprecation": "^2.0.0",
-        "once": "^1.4.0"
-      }
-    },
-    "@octokit/types": {
-      "version": "6.41.0",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
-      "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
-      "requires": {
-        "@octokit/openapi-types": "^12.11.0"
-      }
-    },
-    "balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
-    },
-    "before-after-hook": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
-      "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
-    },
-    "brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "requires": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
-    },
-    "deprecation": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
-      "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
-    },
-    "fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
-    },
-    "glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "requires": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      }
-    },
-    "inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-      "requires": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
-    },
-    "is-plain-object": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
-      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
-    },
-    "minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "requires": {
-        "brace-expansion": "^1.1.7"
-      }
-    },
-    "node-fetch": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
-      "requires": {
-        "whatwg-url": "^5.0.0"
-      }
-    },
-    "once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
-      "requires": {
-        "wrappy": "1"
-      }
-    },
-    "path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
-    },
-    "tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
-    },
-    "tunnel": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
-      "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
-    },
-    "universal-user-agent": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
-      "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
-    },
-    "uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
-    },
-    "webidl-conversions": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
-    },
-    "whatwg-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
-      "requires": {
-        "tr46": "~0.0.3",
-        "webidl-conversions": "^3.0.0"
-      }
-    },
-    "wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
-    }
-  }
-}
diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json b/compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json
deleted file mode 100644
index d9c23f8873e..00000000000
--- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "name": "rustc_codegen_cranelift-github-release",
-  "version": "0.0.0",
-  "license": "Apache-2.0 WITH LLVM-exception",
-  "main": "main.js",
-  "dependencies": {
-    "@actions/core": "^1.9.1",
-    "@actions/github": "^5.1.0",
-    "glob": "^7.1.5"
-  }
-}
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
index 30dc5cb1615..6ad041a796c 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
@@ -25,7 +25,10 @@ jobs:
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: x86_64-unknown-linux-gnu
-          - os: macos-latest
+          - os: ubuntu-24.04-arm
+            env:
+              TARGET_TRIPLE: aarch64-unknown-linux-gnu
+          - os: macos-13
             env:
               TARGET_TRIPLE: x86_64-apple-darwin
           - os: macos-latest
@@ -56,13 +59,6 @@ jobs:
       if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
       run: rustup set default-host x86_64-pc-windows-gnu
 
-    - name: Use x86_64 compiler on macOS
-      if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin'
-      run: rustup set default-host x86_64-apple-darwin
-
-    - name: Prepare dependencies
-      run: ./y.sh prepare
-
     - name: Build
       run: ./y.sh build --sysroot none
 
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
index 61a4c1270c9..6fd288d195c 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -53,13 +53,12 @@ jobs:
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: x86_64-unknown-linux-gnu
-          - os: macos-latest
-            env:
-              TARGET_TRIPLE: x86_64-apple-darwin
-          - os: ubuntu-latest
+          - os: ubuntu-24.04-arm
             env:
               TARGET_TRIPLE: aarch64-unknown-linux-gnu
-            apt_deps: gcc-aarch64-linux-gnu qemu-user
+          - os: macos-13
+            env:
+              TARGET_TRIPLE: x86_64-apple-darwin
           - os: macos-latest
             env:
               TARGET_TRIPLE: aarch64-apple-darwin
@@ -95,10 +94,6 @@ jobs:
       if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
       run: rustup set default-host x86_64-pc-windows-gnu
 
-    - name: Use x86_64 compiler on macOS
-      if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin'
-      run: rustup set default-host x86_64-apple-darwin
-
     - name: Install toolchain and emulator
       if: matrix.apt_deps != null
       run: |
@@ -170,9 +165,6 @@ jobs:
         sudo apt update
         sudo apt install -y hyperfine
 
-    - name: Prepare dependencies
-      run: ./y.sh prepare
-
     - name: Build
       run: ./y.sh build --sysroot none
 
@@ -192,7 +184,10 @@ jobs:
           - os: ubuntu-22.04
             env:
               TARGET_TRIPLE: x86_64-unknown-linux-gnu
-          - os: macos-latest
+          - os: ubuntu-24.04-arm
+            env:
+              TARGET_TRIPLE: aarch64-unknown-linux-gnu
+          - os: macos-13
             env:
               TARGET_TRIPLE: x86_64-apple-darwin
           - os: macos-latest
@@ -218,13 +213,6 @@ jobs:
       if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
       run: rustup set default-host x86_64-pc-windows-gnu
 
-    - name: Use x86_64 compiler on macOS
-      if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin'
-      run: rustup set default-host x86_64-apple-darwin
-
-    - name: Prepare dependencies
-      run: ./y.sh prepare
-
     - name: Build backend
       run: ./y.sh build --sysroot none
 
@@ -273,12 +261,9 @@ jobs:
           rmdir artifacts/ # verify all artifacts are represented in release/
           ls -R release/
 
-      - run: npm install --production
-        working-directory: .github/actions/github-release
-
-      - name: Publish Release
-        uses: ./.github/actions/github-release
-        with:
-          files: "release/*"
-          token: ${{ github.token }}
-        continue-on-error: true
+      - name: Publish release
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          gh release delete --cleanup-tag -y dev || true
+          gh release create --target $GITHUB_SHA --prerelease dev release/*
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
index 70c214ce8b1..9253ab96353 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
@@ -22,9 +22,6 @@ jobs:
         path: build/cg_clif
         key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }}
 
-    - name: Prepare dependencies
-      run: ./y.sh prepare
-
     - name: Test
       run: ./scripts/test_bootstrap.sh
 
@@ -50,8 +47,5 @@ jobs:
         sudo apt update
         sudo apt install -y ripgrep
 
-    - name: Prepare dependencies
-      run: ./y.sh prepare
-
     - name: Test
       run: ./scripts/test_rustc_tests.sh
diff --git a/compiler/rustc_codegen_cranelift/.vscode/settings.json b/compiler/rustc_codegen_cranelift/.vscode/settings.json
index 491646ce59b..68bd93aea89 100644
--- a/compiler/rustc_codegen_cranelift/.vscode/settings.json
+++ b/compiler/rustc_codegen_cranelift/.vscode/settings.json
@@ -1,41 +1,40 @@
 {
     "editor.formatOnSave": true,
-
     // in case rustc.source is disabled for performance reasons; disable the errors about this
-    "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
+    "rust-analyzer.diagnostics.disabled": [
+        "unresolved-extern-crate",
+        "unresolved-macro-call"
+    ],
     "rust-analyzer.rustc.source": "discover",
     "rust-analyzer.imports.granularity.enforce": true,
     "rust-analyzer.imports.granularity.group": "module",
     "rust-analyzer.imports.prefix": "crate",
-    "rust-analyzer.cargo.features": ["unstable-features"],
+    "rust-analyzer.cargo.features": [
+        "unstable-features"
+    ],
     "rust-analyzer.linkedProjects": [
         "./Cargo.toml",
         "./build_system/Cargo.toml",
         {
+            "sysroot_src": "./build/stdlib/library",
             "crates": [
                 {
                     "root_module": "./example/mini_core.rs",
-                    "edition": "2018",
+                    "edition": "2015",
                     "deps": [],
                     "cfg": [],
                 },
                 {
                     "root_module": "./example/mini_core_hello_world.rs",
-                    "edition": "2018",
-                    "deps": [{ "crate": 0, "name": "mini_core" }],
-                    "cfg": [],
-                },
-                {
-                    "root_module": "./example/mod_bench.rs",
-                    "edition": "2018",
-                    "deps": [],
+                    "edition": "2015",
+                    "deps": [
+                        {
+                            "crate": 0,
+                            "name": "mini_core"
+                        }
+                    ],
                     "cfg": [],
                 },
-            ]
-        },
-        {
-            "sysroot_src": "./build/stdlib/library",
-            "crates": [
                 {
                     "root_module": "./example/std_example.rs",
                     "edition": "2015",
diff --git a/compiler/rustc_codegen_cranelift/.zed/settings.json b/compiler/rustc_codegen_cranelift/.zed/settings.json
index e93bed36949..4338a347331 100644
--- a/compiler/rustc_codegen_cranelift/.zed/settings.json
+++ b/compiler/rustc_codegen_cranelift/.zed/settings.json
@@ -5,7 +5,10 @@
       "initialization_options": {
         "diagnostics": {
           // in case rustc.source is disabled for performance reasons; disable the errors about this
-          "disabled": ["unresolved-extern-crate", "unresolved-macro-call"]
+          "disabled": [
+            "unresolved-extern-crate",
+            "unresolved-macro-call"
+          ]
         },
         "rustc": {
           "source": "discover"
@@ -18,22 +21,25 @@
           "prefix": "crate"
         },
         "cargo": {
-          "features": ["unstable-features"]
+          "features": [
+            "unstable-features"
+          ]
         },
         "linkedProjects": [
           "./Cargo.toml",
           "./build_system/Cargo.toml",
           {
+            "sysroot_src": "./build/stdlib/library",
             "crates": [
               {
                 "root_module": "./example/mini_core.rs",
-                "edition": "2018",
+                "edition": "2015",
                 "deps": [],
                 "cfg": []
               },
               {
                 "root_module": "./example/mini_core_hello_world.rs",
-                "edition": "2018",
+                "edition": "2015",
                 "deps": [
                   {
                     "crate": 0,
@@ -43,17 +49,6 @@
                 "cfg": []
               },
               {
-                "root_module": "./example/mod_bench.rs",
-                "edition": "2018",
-                "deps": [],
-                "cfg": []
-              }
-            ]
-          },
-          {
-            "sysroot_src": "./build/stdlib/library",
-            "crates": [
-              {
                 "root_module": "./example/std_example.rs",
                 "edition": "2015",
                 "deps": [],
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index ca66ec5c6e9..e5f1896b923 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -42,27 +42,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
+name = "cranelift-assembler-x64"
+version = "0.118.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e4b56ebe316895d3fa37775d0a87b0c889cc933f5c8b253dbcc7c7bcb7fe7e4"
+dependencies = [
+ "cranelift-assembler-x64-meta",
+]
+
+[[package]]
+name = "cranelift-assembler-x64-meta"
+version = "0.118.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95cabbc01dfbd7dcd6c329ca44f0212910309c221797ac736a67a5bc8857fe1b"
+
+[[package]]
 name = "cranelift-bforest"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e15d04a0ce86cb36ead88ad68cf693ffd6cda47052b9e0ac114bc47fd9cd23c4"
+checksum = "76ffe46df300a45f1dc6f609dc808ce963f0e3a2e971682c479a2d13e3b9b8ef"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-bitset"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c6e3969a7ce267259ce244b7867c5d3bc9e65b0a87e81039588dfdeaede9f34"
+checksum = "b265bed7c51e1921fdae6419791d31af77d33662ee56d7b0fa0704dc8d231cab"
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c22032c4cb42558371cf516bb47f26cdad1819d3475c133e93c49f50ebf304e"
+checksum = "e606230a7e3a6897d603761baee0d19f88d077f17b996bb5089488a29ae96e41"
 dependencies = [
  "bumpalo",
+ "cranelift-assembler-x64",
  "cranelift-bforest",
  "cranelift-bitset",
  "cranelift-codegen-meta",
@@ -71,7 +87,7 @@ dependencies = [
  "cranelift-entity",
  "cranelift-isle",
  "gimli",
- "hashbrown 0.14.5",
+ "hashbrown",
  "log",
  "regalloc2",
  "rustc-hash",
@@ -82,42 +98,43 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c904bc71c61b27fc57827f4a1379f29de64fe95653b620a3db77d59655eee0b8"
+checksum = "8a63bffafc23bc60969ad528e138788495999d935f0adcfd6543cb151ca8637d"
 dependencies = [
+ "cranelift-assembler-x64",
  "cranelift-codegen-shared",
 ]
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40180f5497572f644ce88c255480981ae2ec1d7bb4d8e0c0136a13b87a2f2ceb"
+checksum = "af50281b67324b58e843170a6a5943cf6d387c06f7eeacc9f5696e4ab7ae7d7e"
 
 [[package]]
 name = "cranelift-control"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d132c6d0bd8a489563472afc171759da0707804a65ece7ceb15a8c6d7dd5ef"
+checksum = "8c20c1b38d1abfbcebb0032e497e71156c0e3b8dcb3f0a92b9863b7bcaec290c"
 dependencies = [
  "arbitrary",
 ]
 
 [[package]]
 name = "cranelift-entity"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b2d0d9618275474fbf679dd018ac6e009acbd6ae6850f6a67be33fb3b00b323"
+checksum = "0c2c67d95507c51b4a1ff3f3555fe4bfec36b9e13c1b684ccc602736f5d5f4a2"
 dependencies = [
  "cranelift-bitset",
 ]
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fac41e16729107393174b0c9e3730fb072866100e1e64e80a1a963b2e484d57"
+checksum = "4e002691cc69c38b54fc7ec93e5be5b744f627d027031d991cc845d1d512d0ce"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -127,15 +144,15 @@ dependencies = [
 
 [[package]]
 name = "cranelift-isle"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ca20d576e5070044d0a72a9effc2deacf4d6aa650403189d8ea50126483944d"
+checksum = "e93588ed1796cbcb0e2ad160403509e2c5d330d80dd6e0014ac6774c7ebac496"
 
 [[package]]
 name = "cranelift-jit"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e65c42755a719b09662b00c700daaf76cc35d5ace1f5c002ad404b591ff1978"
+checksum = "17f6682f0b193d6b7873cc8e7ed67e8776a8a26f50eeabf88534e9be618b9a03"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -153,9 +170,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-module"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d55612bebcf16ff7306c8a6f5bdb6d45662b8aa1ee058ecce8807ad87db719b"
+checksum = "ff19784c6de05116e63e6a34791012bd927b2a4eac56233039c46f1b6a4edac8"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -164,9 +181,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-native"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8dee82f3f1f2c4cba9177f1cc5e350fe98764379bcd29340caa7b01f85076c7"
+checksum = "e5b09bdd6407bf5d89661b80cf926ce731c9e8cc184bf49102267a2369a8358e"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -175,9 +192,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.116.1"
+version = "0.118.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aad5a6d3e379493c3f8b35dc61c93d0bf5f27003bbe20614e0200b0ec372ef52"
+checksum = "685e8661a30d1cb69509f589ac643adeee79c5f63c0da316431b9fad29e6d3b4"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -228,12 +245,6 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.14.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
-
-[[package]]
-name = "hashbrown"
 version = "0.15.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
@@ -248,7 +259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
 dependencies = [
  "equivalent",
- "hashbrown 0.15.2",
+ "hashbrown",
 ]
 
 [[package]]
@@ -295,7 +306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
 dependencies = [
  "crc32fast",
- "hashbrown 0.15.2",
+ "hashbrown",
  "indexmap",
  "memchr",
 ]
@@ -326,7 +337,7 @@ checksum = "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3"
 dependencies = [
  "allocator-api2",
  "bumpalo",
- "hashbrown 0.15.2",
+ "hashbrown",
  "log",
  "rustc-hash",
  "smallvec",
@@ -425,9 +436,9 @@ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
 
 [[package]]
 name = "wasmtime-jit-icache-coherence"
-version = "29.0.1"
+version = "31.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec5e8552e01692e6c2e5293171704fed8abdec79d1a6995a0870ab190e5747d1"
+checksum = "a54f6c6c7e9d7eeee32dfcc10db7f29d505ee7dd28d00593ea241d5f70698e64"
 dependencies = [
  "anyhow",
  "cfg-if",
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index 670d6f4eef5..08b60de14c1 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -8,12 +8,12 @@ crate-type = ["dylib"]
 
 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.116.0", default-features = false, features = ["std", "unwind", "all-native-arch"] }
-cranelift-frontend = { version = "0.116.0" }
-cranelift-module = { version = "0.116.0" }
-cranelift-native = { version = "0.116.0" }
-cranelift-jit = { version = "0.116.0", optional = true }
-cranelift-object = { version = "0.116.0" }
+cranelift-codegen = { version = "0.118.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
+cranelift-frontend = { version = "0.118.0" }
+cranelift-module = { version = "0.118.0" }
+cranelift-native = { version = "0.118.0" }
+cranelift-jit = { version = "0.118.0", optional = true }
+cranelift-object = { version = "0.118.0" }
 target-lexicon = "0.13"
 gimli = { version = "0.31", default-features = false, features = ["write"] }
 object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
@@ -24,12 +24,12 @@ smallvec = "1.8.1"
 
 [patch.crates-io]
 # Uncomment to use an unreleased version of cranelift
-#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
-#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
-#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
-#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
-#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
-#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
+#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
+#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
+#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
+#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
+#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
+#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
 
 # Uncomment to use local checkout of cranelift
 #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index 18a840f8a50..28edb5795ce 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/Readme.md
@@ -49,13 +49,13 @@ If you want to build the backend manually, you can download it from GitHub and b
 ```bash
 $ git clone https://github.com/rust-lang/rustc_codegen_cranelift
 $ cd rustc_codegen_cranelift
-$ ./y.sh prepare
 $ ./y.sh build
 ```
 
 To run the test suite replace the last command with:
 
 ```bash
+$ ./y.sh prepare # only needs to be run the first time
 $ ./test.sh
 ```
 
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index 11f73bdb61f..ba5cc9a29f5 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -91,6 +91,13 @@ impl GitRepo {
 
     fn verify_checksum(&self, dirs: &Dirs) {
         let download_dir = self.download_dir(dirs);
+        if !download_dir.exists() {
+            eprintln!(
+                "Missing directory {download_dir}: Please run ./y.sh prepare to download.",
+                download_dir = download_dir.display(),
+            );
+            std::process::exit(1);
+        }
         let actual_hash = format!("{:016x}", hash_dir(&download_dir));
         if actual_hash != self.content_hash {
             eprintln!(
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index ea7e94c345a..eec89c026b2 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -1,5 +1,4 @@
 use std::ffi::OsStr;
-use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
 
@@ -100,6 +99,34 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
         runner.run_out_command("gen_block_iterate", &[]);
     }),
     TestCase::build_bin_and_run("aot.raw-dylib", "example/raw-dylib.rs", &[]),
+    TestCase::custom("test.sysroot", &|runner| {
+        apply_patches(
+            &runner.dirs,
+            "sysroot_tests",
+            &runner.stdlib_source.join("library"),
+            &SYSROOT_TESTS_SRC.to_path(&runner.dirs),
+        );
+
+        SYSROOT_TESTS.clean(&runner.dirs);
+
+        let mut target_compiler = runner.target_compiler.clone();
+        // coretests and alloctests produce a bunch of warnings. When running
+        // in rust's CI warnings are denied, so we have to override that here.
+        target_compiler.rustflags.push("--cap-lints=allow".to_owned());
+        // The standard library may have been compiled with -Zrandomize-layout.
+        target_compiler.rustflags.extend(["--cfg".to_owned(), "randomized_layouts".to_owned()]);
+
+        if runner.is_native {
+            let mut test_cmd = SYSROOT_TESTS.test(&target_compiler, &runner.dirs);
+            test_cmd.args(["-p", "coretests", "-p", "alloctests", "--tests", "--", "-q"]);
+            spawn_and_wait(test_cmd);
+        } else {
+            eprintln!("Cross-Compiling: Not running tests");
+            let mut build_cmd = SYSROOT_TESTS.build(&target_compiler, &runner.dirs);
+            build_cmd.args(["-p", "coretests", "-p", "alloctests", "--tests"]);
+            spawn_and_wait(build_cmd);
+        }
+    }),
 ];
 
 pub(crate) static RAND_REPO: GitRepo = GitRepo::github(
@@ -126,9 +153,9 @@ static PORTABLE_SIMD_SRC: RelPath = RelPath::build("portable-simd");
 
 static PORTABLE_SIMD: CargoProject = CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target");
 
-static LIBCORE_TESTS_SRC: RelPath = RelPath::build("coretests");
+static SYSROOT_TESTS_SRC: RelPath = RelPath::build("sysroot_tests");
 
-static LIBCORE_TESTS: CargoProject = CargoProject::new(&LIBCORE_TESTS_SRC, "coretests_target");
+static SYSROOT_TESTS: CargoProject = CargoProject::new(&SYSROOT_TESTS_SRC, "sysroot_tests_target");
 
 const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
     TestCase::custom("test.rust-random/rand", &|runner| {
@@ -147,31 +174,6 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
             spawn_and_wait(build_cmd);
         }
     }),
-    TestCase::custom("test.libcore", &|runner| {
-        apply_patches(
-            &runner.dirs,
-            "coretests",
-            &runner.stdlib_source.join("library/coretests"),
-            &LIBCORE_TESTS_SRC.to_path(&runner.dirs),
-        );
-
-        let source_lockfile = runner.dirs.source_dir.join("patches/coretests-lock.toml");
-        let target_lockfile = LIBCORE_TESTS_SRC.to_path(&runner.dirs).join("Cargo.lock");
-        fs::copy(source_lockfile, target_lockfile).unwrap();
-
-        LIBCORE_TESTS.clean(&runner.dirs);
-
-        if runner.is_native {
-            let mut test_cmd = LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs);
-            test_cmd.arg("--").arg("-q");
-            spawn_and_wait(test_cmd);
-        } else {
-            eprintln!("Cross-Compiling: Not running tests");
-            let mut build_cmd = LIBCORE_TESTS.build(&runner.target_compiler, &runner.dirs);
-            build_cmd.arg("--tests");
-            spawn_and_wait(build_cmd);
-        }
-    }),
     TestCase::custom("test.regex", &|runner| {
         REGEX_REPO.patch(&runner.dirs);
 
@@ -330,10 +332,8 @@ impl<'a> TestRunner<'a> {
         target_compiler.rustflags.extend(rustflags_from_env("RUSTFLAGS"));
         target_compiler.rustdocflags.extend(rustflags_from_env("RUSTDOCFLAGS"));
 
-        let jit_supported = use_unstable_features
-            && is_native
-            && target_compiler.triple.contains("x86_64")
-            && !target_compiler.triple.contains("windows");
+        let jit_supported =
+            use_unstable_features && is_native && !target_compiler.triple.contains("windows");
 
         Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source }
     }
@@ -374,21 +374,7 @@ impl<'a> TestRunner<'a> {
                 TestCaseCmd::JitBin { source, args } => {
                     let mut jit_cmd = self.rustc_command([
                         "-Zunstable-options",
-                        "-Cllvm-args=mode=jit",
-                        "-Cprefer-dynamic",
-                        source,
-                        "--cfg",
-                        "jit",
-                    ]);
-                    if !args.is_empty() {
-                        jit_cmd.env("CG_CLIF_JIT_ARGS", args);
-                    }
-                    spawn_and_wait(jit_cmd);
-
-                    eprintln!("[JIT-lazy] {testname}");
-                    let mut jit_cmd = self.rustc_command([
-                        "-Zunstable-options",
-                        "-Cllvm-args=mode=jit-lazy",
+                        "-Cllvm-args=jit-mode",
                         "-Cprefer-dynamic",
                         source,
                         "--cfg",
diff --git a/compiler/rustc_codegen_cranelift/build_system/utils.rs b/compiler/rustc_codegen_cranelift/build_system/utils.rs
index c2114caf869..f2399768459 100644
--- a/compiler/rustc_codegen_cranelift/build_system/utils.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/utils.rs
@@ -105,7 +105,11 @@ impl CargoProject {
             .arg(self.manifest_path(dirs))
             .arg("--target-dir")
             .arg(self.target_dir(dirs))
-            .arg("--locked");
+            .arg("--locked")
+            // bootstrap sets both RUSTC and RUSTC_WRAPPER to the same wrapper. RUSTC is already
+            // respected by the rustc-clif wrapper, but RUSTC_WRAPPER will misinterpret rustc-clif
+            // as filename, so we need to unset it.
+            .env_remove("RUSTC_WRAPPER");
 
         if dirs.frozen {
             cmd.arg("--frozen");
diff --git a/compiler/rustc_codegen_cranelift/config.txt b/compiler/rustc_codegen_cranelift/config.txt
index f578cbef35e..6ae4767adfd 100644
--- a/compiler/rustc_codegen_cranelift/config.txt
+++ b/compiler/rustc_codegen_cranelift/config.txt
@@ -32,9 +32,9 @@ aot.issue-59326
 aot.neon
 aot.gen_block_iterate
 aot.raw-dylib
+test.sysroot
 
 testsuite.extended_sysroot
 test.rust-random/rand
-test.libcore
 test.regex
 test.portable-simd
diff --git a/compiler/rustc_codegen_cranelift/docs/usage.md b/compiler/rustc_codegen_cranelift/docs/usage.md
index 135a51ce392..dbe36109f83 100644
--- a/compiler/rustc_codegen_cranelift/docs/usage.md
+++ b/compiler/rustc_codegen_cranelift/docs/usage.md
@@ -38,14 +38,7 @@ $ $cg_clif_dir/dist/cargo-clif jit
 or
 
 ```bash
-$ $cg_clif_dir/dist/rustc-clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs
-```
-
-There is also an experimental lazy jit mode. In this mode functions are only compiled once they are
-first called.
-
-```bash
-$ $cg_clif_dir/dist/cargo-clif lazy-jit
+$ $cg_clif_dir/dist/rustc-clif -Cllvm-args=jit-mode -Cprefer-dynamic my_crate.rs
 ```
 
 ## Shell
@@ -54,7 +47,7 @@ These are a few functions that allow you to easily run rust code from the shell
 
 ```bash
 function jit_naked() {
-    echo "$@" | $cg_clif_dir/dist/rustc-clif - -Zunstable-options -Cllvm-args=mode=jit-lazy -Cprefer-dynamic
+    echo "$@" | $cg_clif_dir/dist/rustc-clif - -Zunstable-options -Cllvm-args=jit-mode-Cprefer-dynamic
 }
 
 function jit() {
diff --git a/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs b/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs
index 25bfe542d22..de9a3d550ec 100644
--- a/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs
+++ b/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs
@@ -6,16 +6,25 @@
 #![feature(gen_blocks)]
 
 fn foo() -> impl Iterator<Item = u32> {
-    gen { yield 42; for x in 3..6 { yield x } }
+    gen {
+        yield 42;
+        for x in 3..6 {
+            yield x
+        }
+    }
 }
 
 fn moved() -> impl Iterator<Item = u32> {
     let mut x = "foo".to_string();
     gen move {
         yield 42;
-        if x == "foo" { return }
+        if x == "foo" {
+            return;
+        }
         x.clear();
-        for x in 3..6 { yield x }
+        for x in 3..6 {
+            yield x
+        }
     }
 }
 
@@ -32,5 +41,4 @@ fn main() {
     let mut iter = moved();
     assert_eq!(iter.next(), Some(42));
     assert_eq!(iter.next(), None);
-
 }
diff --git a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch
index 4a06dc3f7ef..16c8488acdb 100644
--- a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch
@@ -10,20 +10,20 @@ Cranelift doesn't support them yet
  library/core/tests/atomic.rs          |  4 ---
  4 files changed, 4 insertions(+), 50 deletions(-)
 
-diff --git a/tests/lib.rs b/tests/lib.rs
+diff --git a/coretests/tests/lib.rs b/coretests/tests/lib.rs
 index 1e336bf..35e6f54 100644
---- a/tests/lib.rs
-+++ b/tests/lib.rs
+--- a/coretests/tests/lib.rs
++++ b/coretests/tests/lib.rs
 @@ -2,5 +2,4 @@
  // tidy-alphabetical-start
 -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
  #![cfg_attr(test, feature(cfg_match))]
  #![feature(alloc_layout_extra)]
  #![feature(array_chunks)]
-diff --git a/tests/atomic.rs b/tests/atomic.rs
+diff --git a/coretests/tests/atomic.rs b/coretests/tests/atomic.rs
 index b735957..ea728b6 100644
---- a/tests/atomic.rs
-+++ b/tests/atomic.rs
+--- a/coretests/tests/atomic.rs
++++ b/coretests/tests/atomic.rs
 @@ -185,10 +185,6 @@ fn atomic_alignment() {
      assert_eq!(align_of::<AtomicU64>(), size_of::<AtomicU64>());
      #[cfg(target_has_atomic = "64")]
diff --git a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
deleted file mode 100644
index f5ae66c0eb1..00000000000
--- a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001
-From: bjorn3 <bjorn3@users.noreply.github.com>
-Date: Fri, 3 Dec 2021 12:16:30 +0100
-Subject: [PATCH] Disable long running tests
-
----
- library/core/tests/slice.rs | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/tests/slice.rs b/tests/slice.rs
-index 8402833..84592e0 100644
---- a/tests/slice.rs
-+++ b/tests/slice.rs
-@@ -1809,6 +1809,7 @@ fn sort_unstable() {
-     }
- }
- 
-+/*
- #[test]
- #[cfg(not(target_arch = "wasm32"))]
- #[cfg_attr(miri, ignore)] // Miri is too slow
-@@ -1914,6 +1915,7 @@ fn select_nth_unstable() {
-     v.select_nth_unstable(0);
-     assert!(v == [0xDEADBEEF]);
- }
-+*/
- 
- #[test]
- #[should_panic(expected = "index 0 greater than length of slice")]
-@@ -2462,6 +2462,7 @@ take_tests! {
- #[cfg(not(miri))] // unused in Miri
- const EMPTY_MAX: &'static [()] = &[(); usize::MAX];
- 
-+/*
- // can't be a constant due to const mutability rules
- #[cfg(not(miri))] // unused in Miri
- macro_rules! empty_max_mut {
-@@ -2485,6 +2486,7 @@ take_tests! {
-     (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
-     (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
- }
-+*/
- 
- #[test]
- fn test_slice_from_ptr_range() {
--- 
-2.26.2.7.g19db9cfb68
-
diff --git a/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch
new file mode 100644
index 00000000000..357b8d306cf
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch
@@ -0,0 +1,105 @@
+From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001
+From: bjorn3 <bjorn3@users.noreply.github.com>
+Date: Fri, 3 Dec 2021 12:16:30 +0100
+Subject: [PATCH] Disable long running tests
+
+---
+ library/coretests/tests/slice.rs | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/coretests/tests/slice.rs b/coretests/tests/slice.rs
+index 8402833..84592e0 100644
+--- a/coretests/tests/slice.rs
++++ b/coretests/tests/slice.rs
+@@ -1809,6 +1809,7 @@ fn sort_unstable() {
+     }
+ }
+ 
++/*
+ #[test]
+ #[cfg(not(target_arch = "wasm32"))]
+ #[cfg_attr(miri, ignore)] // Miri is too slow
+@@ -1914,6 +1915,7 @@ fn select_nth_unstable() {
+     v.select_nth_unstable(0);
+     assert!(v == [0xDEADBEEF]);
+ }
++*/
+ 
+ #[test]
+ #[should_panic(expected = "index 0 greater than length of slice")]
+@@ -2462,6 +2462,7 @@ take_tests! {
+ #[cfg(not(miri))] // unused in Miri
+ const EMPTY_MAX: &'static [()] = &[(); usize::MAX];
+ 
++/*
+ // can't be a constant due to const mutability rules
+ #[cfg(not(miri))] // unused in Miri
+ macro_rules! empty_max_mut {
+@@ -2485,6 +2486,7 @@ take_tests! {
+     (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
+     (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
+ }
++*/
+ 
+ #[test]
+ fn test_slice_from_ptr_range() {
+diff --git a/alloctests/tests/sort/tests.rs b/alloctests/tests/sort/tests.rs
+index d321f8d..8b2040a 100644
+--- a/alloctests/tests/sort/tests.rs
++++ b/alloctests/tests/sort/tests.rs
+@@ -1,3 +1,5 @@
++#![cfg(any())]
++
+ use std::cell::Cell;
+ use std::cmp::Ordering;
+ use std::fmt::Debug;
+diff --git a/alloctests/tests/str.rs b/alloctests/tests/str.rs
+index 906fa2d..b82fa99 100644
+--- a/alloctests/tests/str.rs
++++ b/alloctests/tests/str.rs
+@@ -2234,7 +2234,7 @@ fn const_str_ptr() {
+     const C: *const u8 = B as *const u8;
+ 
+     // Miri does not deduplicate consts (https://github.com/rust-lang/miri/issues/131)
+-    #[cfg(not(miri))]
++    #[cfg(any())]
+     {
+         let foo = &A as *const u8;
+         assert_eq!(foo, C);
+diff --git a/alloctests/tests/task.rs b/alloctests/tests/task.rs
+index 390dec1..87df6e6 100644
+--- a/alloctests/tests/task.rs
++++ b/alloctests/tests/task.rs
+@@ -4,7 +4,7 @@ use alloc::task::{LocalWake, Wake};
+ use core::task::{LocalWaker, Waker};
+ 
+ #[test]
+-#[cfg_attr(miri, ignore)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
++#[ignore] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
+ fn test_waker_will_wake_clone() {
+     struct NoopWaker;
+ 
+@@ -20,7 +20,7 @@ fn test_waker_will_wake_clone() {
+ }
+ 
+ #[test]
+-#[cfg_attr(miri, ignore)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
++#[ignore] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
+ fn test_local_waker_will_wake_clone() {
+     struct NoopWaker;
+ 
+diff --git a/alloctests/tests/vec.rs b/alloctests/tests/vec.rs
+index f430d97..cfbd3cb 100644
+--- a/alloctests/tests/vec.rs
++++ b/alloctests/tests/vec.rs
+@@ -762,6 +762,7 @@ fn test_drain_inclusive_range() {
+ }
+ 
+ #[test]
++#[ignore]
+ fn test_drain_max_vec_size() {
+     let mut v = Vec::<()>::with_capacity(usize::MAX);
+     unsafe {
+-- 
+2.26.2.7.g19db9cfb68
+
diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
deleted file mode 100644
index 34249ea4834..00000000000
--- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 175d52c5e1779764b66777db1e6f172c2dc365ff Mon Sep 17 00:00:00 2001
-From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
-Date: Fri, 9 Aug 2024 15:44:51 +0000
-Subject: [PATCH] Disable f16 and f128 in compiler-builtins
-
----
- library/liballoc/Cargo.toml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/library/liballoc/Cargo.toml b/library/liballoc/Cargo.toml
-index 7165c3e48af..968552ad435 100644
---- a/library/alloc/Cargo.toml
-+++ b/library/alloc/Cargo.toml
-@@ -11,7 +11,7 @@ test = { path = "../test" }
- bench = false
- 
- [dependencies]
- core = { path = "../core", public = true }
--compiler_builtins = { version = "=0.1.152", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "=0.1.152", features = ['rustc-dep-of-std', 'no-f16-f128'] }
- 
- [features]
- compiler-builtins-mem = ['compiler_builtins/mem']
--- 
-2.34.1
-
diff --git a/compiler/rustc_codegen_cranelift/patches/coretests-lock.toml b/compiler/rustc_codegen_cranelift/patches/coretests-lock.toml
deleted file mode 100644
index af8f28a193b..00000000000
--- a/compiler/rustc_codegen_cranelift/patches/coretests-lock.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "coretests"
-version = "0.0.0"
-dependencies = [
- "rand",
- "rand_xorshift",
-]
-
-[[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-
-[[package]]
-name = "rand_xorshift"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
-dependencies = [
- "rand_core",
-]
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index 481903c6afb..ceff15b1180 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2025-02-15"
+channel = "nightly-2025-03-30"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
 profile = "minimal"
diff --git a/compiler/rustc_codegen_cranelift/rustfmt.toml b/compiler/rustc_codegen_cranelift/rustfmt.toml
index f31fa9c76ab..35c92663eb9 100644
--- a/compiler/rustc_codegen_cranelift/rustfmt.toml
+++ b/compiler/rustc_codegen_cranelift/rustfmt.toml
@@ -1,7 +1,3 @@
-ignore = [
-    "example/gen_block_iterate.rs", # uses edition 2024
-]
-
 # Matches rustfmt.toml of rustc
 style_edition = "2024"
 use_small_heuristics = "Max"
diff --git a/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs b/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs
index ebbb6879610..e6c63bf5e65 100644
--- a/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs
+++ b/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs
@@ -50,19 +50,7 @@ fn main() {
                 .chain([
                     "--".to_string(),
                     "-Zunstable-options".to_string(),
-                    "-Cllvm-args=mode=jit".to_string(),
-                ])
-                .collect()
-        }
-        Some("lazy-jit") => {
-            rustflags.push("-Cprefer-dynamic".to_owned());
-            args.remove(0);
-            IntoIterator::into_iter(["rustc".to_string()])
-                .chain(args)
-                .chain([
-                    "--".to_string(),
-                    "-Zunstable-options".to_string(),
-                    "-Cllvm-args=mode=jit-lazy".to_string(),
+                    "-Cllvm-args=jit-mode".to_string(),
                 ])
                 .collect()
         }
diff --git a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
index 0252d5b3340..4595063c032 100755
--- a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
+++ b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
@@ -4,7 +4,7 @@
 pushd $(dirname "$0")/../
 RUSTC="$(pwd)/dist/rustc-clif"
 popd
-PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic $0
+PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=jit-mode -Cprefer-dynamic $0
 #*/
 
 //! This program filters away uninteresting samples and trims uninteresting frames for stackcollapse
diff --git a/compiler/rustc_codegen_cranelift/scripts/rustup.sh b/compiler/rustc_codegen_cranelift/scripts/rustup.sh
index 355282911c2..152c243aa6a 100755
--- a/compiler/rustc_codegen_cranelift/scripts/rustup.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/rustup.sh
@@ -64,7 +64,7 @@ case $1 in
         cg_clif=$(pwd)
         pushd ../rust
         git fetch origin master
-        git checkout "$RUST_VERS"
+        git -c advice.detachedHead=false checkout "$RUST_VERS"
         "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust
         popd
         git merge sync_from_rust -m "Sync from rust $RUST_VERS"
diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
index 54f6baff4fe..ca6426f2ba9 100644
--- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
@@ -43,8 +43,31 @@ verbose-tests = false
 # disabled bootstrap will crash trying to copy llvm tools for the bootstrap
 # compiler.
 llvm-tools = false
+std-features = ["panic-unwind", "compiler-builtins-no-f16-f128"]
 
 EOF
+
+cat <<EOF | git apply -
+diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
+index cf4ef4ee310..fe78560fcaf 100644
+--- a/src/bootstrap/src/core/config/config.rs
++++ b/src/bootstrap/src/core/config/config.rs
+@@ -3138,13 +3138,6 @@ fn parse_download_ci_llvm(
+                     );
+                 }
+
+-                if b && self.is_running_on_ci {
+-                    // On CI, we must always rebuild LLVM if there were any modifications to it
+-                    panic!(
+-                        "\`llvm.download-ci-llvm\` cannot be set to \`true\` on CI. Use \`if-unchanged\` instead."
+-                    );
+-                }
+-
+                 // If download-ci-llvm=true we also want to check that CI llvm is available
+                 b && llvm::is_ci_llvm_available_for_target(self, asserts)
+             }
+EOF
+
 popd
 
 # Allow the testsuite to use llvm tools
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index 55230a0b598..95a4302b5e4 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -27,7 +27,6 @@ done
 git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
 git checkout -- tests/ui/proc-macro/pretty-print-hack/
 git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs
-rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR
 
 # missing features
 # ================
@@ -57,7 +56,6 @@ rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't
 rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported
 rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes
 rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo
-rm tests/ui/simd-abi-checks.rs # vector types >128bits not yet supported
 
 # requires LTO
 rm -r tests/run-make/cdylib
@@ -120,6 +118,7 @@ rm tests/ui/mir/mir_raw_fat_ptr.rs # same
 rm tests/ui/consts/issue-33537.rs # same
 rm tests/ui/consts/const-mut-refs-crate.rs # same
 rm tests/ui/abi/large-byval-align.rs # exceeds implementation limit of Cranelift
+rm tests/ui/abi/simd-abi-checks-avx.rs # attempts to declare function with two different signatures
 
 # doesn't work due to the way the rustc test suite is invoked.
 # should work when using ./x.py test the way it is intended
@@ -136,7 +135,6 @@ rm -r tests/run-make/incr-add-rust-src-component
 # ============
 rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported
 rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort
-rm tests/ui/deprecation/deprecated_inline_threshold.rs # missing deprecation warning for -Cinline-threshold
 
 # bugs in the test suite
 # ======================
@@ -150,48 +148,8 @@ rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # same
 rm tests/ui/process/process-panic-after-fork.rs # same
 
 cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist
-cp $(../dist/rustc-clif --print target-libdir)/libstd-*.so ../dist/lib/
 
-# prevent $(RUSTDOC) from picking up the sysroot built by x.py. It conflicts with the one used by
-# rustdoc-clif
 cat <<EOF | git apply -
-diff --git a/tests/run-make/tools.mk b/tests/run-make/tools.mk
-index ea06b620c4c..b969d0009c6 100644
---- a/tests/run-make/tools.mk
-+++ b/tests/run-make/tools.mk
-@@ -9,7 +9,7 @@ RUSTC_ORIGINAL := \$(RUSTC)
- BARE_RUSTC := \$(HOST_RPATH_ENV) '\$(RUSTC)'
- BARE_RUSTDOC := \$(HOST_RPATH_ENV) '\$(RUSTDOC)'
- RUSTC := \$(BARE_RUSTC) --out-dir \$(TMPDIR) -L \$(TMPDIR) \$(RUSTFLAGS) -Ainternal_features
--RUSTDOC := \$(BARE_RUSTDOC) -L \$(TARGET_RPATH_DIR)
-+RUSTDOC := \$(BARE_RUSTDOC)
- ifdef RUSTC_LINKER
- RUSTC := \$(RUSTC) -Clinker='\$(RUSTC_LINKER)'
- RUSTDOC := \$(RUSTDOC) -Clinker='\$(RUSTC_LINKER)'
-diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
-index 9607ff02f96..b7d97caf9a2 100644
---- a/src/tools/run-make-support/src/external_deps/rustdoc.rs
-+++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs
-@@ -34,7 +34,6 @@ pub fn bare() -> Self {
-     #[track_caller]
-     pub fn new() -> Self {
-         let mut cmd = setup_common();
--        cmd.arg("-L").arg(env_var_os("TARGET_RPATH_DIR"));
-         Self { cmd }
-     }
-
-diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
-index e7ae773ffa1d3..04bc2d7787da7 100644
---- a/src/tools/compiletest/src/runtest/run_make.rs
-+++ b/src/tools/compiletest/src/runtest/run_make.rs
-@@ -329,7 +329,6 @@ impl TestCx<'_> {
-             .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
-             .arg("--edition=2021")
-             .arg(&self.testpaths.file.join("rmake.rs"))
--            .arg("-Cprefer-dynamic")
-             // Provide necessary library search paths for rustc.
-             .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
-
 diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
 index 30387af428c..f7895b12961 100644
 --- a/tests/run-make/linker-warning/rmake.rs
@@ -205,7 +163,19 @@ index 30387af428c..f7895b12961 100644
                  regex::escape(run_make_support::build_root().to_str().unwrap()),
                  "/build-root",
              )
-             .run();
+             .normalize(r#""[^"]*\/symbols.o""#, "\\"/symbols.o\\"")
+diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
+index 073116933bd..c3e4578204d 100644
+--- a/src/tools/compiletest/src/runtest/run_make.rs
++++ b/src/tools/compiletest/src/runtest/run_make.rs
+@@ -109,7 +109,6 @@ pub(super) fn run_rmake_test(&self) {
+             // library or compiler features. Here, we force the stage 0 rustc to consider itself as
+             // a stable-channel compiler via \`RUSTC_BOOTSTRAP=-1\` to prevent *any* unstable
+             // library/compiler usages, even if stage 0 rustc is *actually* a nightly rustc.
+-            .env("RUSTC_BOOTSTRAP", "-1")
+             .arg("-o")
+             .arg(&recipe_bin)
+             // Specify library search paths for \`run_make_support\`.
 EOF
 
 echo "[TEST] rustc test suite"
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index e8076ce77ab..ddd119e0c61 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -641,7 +641,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
                 .flat_map(|arg_abi| arg_abi.get_abi_param(fx.tcx).into_iter()),
         );
 
-        if fx.tcx.sess.target.is_like_osx && fx.tcx.sess.target.arch == "aarch64" {
+        if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == "aarch64" {
             // Add any padding arguments needed for Apple AArch64.
             // There's no need to pad the argument list unless variadic arguments are actually being
             // passed.
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 125a9201831..adaa754491e 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -729,8 +729,10 @@ fn codegen_stmt<'tcx>(
                     let to_ty = fx.monomorphize(to_ty);
 
                     fn is_wide_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
-                        ty.builtin_deref(true)
-                            .is_some_and(|pointee_ty| has_ptr_meta(fx.tcx, pointee_ty))
+                        ty.builtin_deref(true).is_some_and(|pointee_ty| {
+                            fx.tcx
+                                .type_has_metadata(pointee_ty, ty::TypingEnv::fully_monomorphized())
+                        })
                     }
 
                     if is_wide_ptr(fx, from_ty) {
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index 766278d8718..abe2972ba0c 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -71,7 +71,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
         },
         ty::FnPtr(..) => pointer_ty(tcx),
         ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
-            if has_ptr_meta(tcx, *pointee_ty) {
+            if tcx.type_has_metadata(*pointee_ty, ty::TypingEnv::fully_monomorphized()) {
                 return None;
             } else {
                 pointer_ty(tcx)
@@ -91,7 +91,7 @@ fn clif_pair_type_from_ty<'tcx>(
             (clif_type_from_ty(tcx, types[0])?, clif_type_from_ty(tcx, types[1])?)
         }
         ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
-            if has_ptr_meta(tcx, *pointee_ty) {
+            if tcx.type_has_metadata(*pointee_ty, ty::TypingEnv::fully_monomorphized()) {
                 (pointer_ty(tcx), pointer_ty(tcx))
             } else {
                 return None;
@@ -101,20 +101,6 @@ fn clif_pair_type_from_ty<'tcx>(
     })
 }
 
-/// Is a pointer to this type a wide ptr?
-pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    if ty.is_sized(tcx, ty::TypingEnv::fully_monomorphized()) {
-        return false;
-    }
-
-    let tail = tcx.struct_tail_for_codegen(ty, ty::TypingEnv::fully_monomorphized());
-    match tail.kind() {
-        ty::Foreign(..) => false,
-        ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
-        _ => bug!("unexpected unsized tail: {:?}", tail),
-    }
-}
-
 pub(crate) fn codegen_icmp_imm(
     fx: &mut FunctionCx<'_, '_, '_>,
     intcc: IntCC,
diff --git a/compiler/rustc_codegen_cranelift/src/config.rs b/compiler/rustc_codegen_cranelift/src/config.rs
index d784f6e9d9e..d328b33a704 100644
--- a/compiler/rustc_codegen_cranelift/src/config.rs
+++ b/compiler/rustc_codegen_cranelift/src/config.rs
@@ -1,21 +1,10 @@
-/// The mode to use for compilation.
-#[derive(Copy, Clone, Debug)]
-pub enum CodegenMode {
-    /// AOT compile the crate. This is the default.
-    Aot,
-    /// JIT compile and execute the crate.
-    Jit,
-    /// JIT compile and execute the crate, but only compile functions the first time they are used.
-    JitLazy,
-}
-
 /// Configuration of cg_clif as passed in through `-Cllvm-args` and various env vars.
 #[derive(Clone, Debug)]
 pub struct BackendConfig {
     /// Should the crate be AOT compiled or JIT executed.
     ///
-    /// Defaults to AOT compilation. Can be set using `-Cllvm-args=mode=...`.
-    pub codegen_mode: CodegenMode,
+    /// Defaults to AOT compilation. Can be set using `-Cllvm-args=jit-mode`.
+    pub jit_mode: bool,
 
     /// When JIT mode is enable pass these arguments to the program.
     ///
@@ -27,7 +16,7 @@ impl BackendConfig {
     /// Parse the configuration passed in using `-Cllvm-args`.
     pub fn from_opts(opts: &[String]) -> Result<Self, String> {
         let mut config = BackendConfig {
-            codegen_mode: CodegenMode::Aot,
+            jit_mode: false,
             jit_args: match std::env::var("CG_CLIF_JIT_ARGS") {
                 Ok(args) => args.split(' ').map(|arg| arg.to_string()).collect(),
                 Err(std::env::VarError::NotPresent) => vec![],
@@ -43,20 +32,9 @@ impl BackendConfig {
                 // testing cg_clif.
                 continue;
             }
-            if let Some((name, value)) = opt.split_once('=') {
-                match name {
-                    "mode" => {
-                        config.codegen_mode = match value {
-                            "aot" => CodegenMode::Aot,
-                            "jit" => CodegenMode::Jit,
-                            "jit-lazy" => CodegenMode::JitLazy,
-                            _ => return Err(format!("Unknown codegen mode `{}`", value)),
-                        };
-                    }
-                    _ => return Err(format!("Unknown option `{}`", name)),
-                }
-            } else {
-                return Err(format!("Invalid option `{}`", opt));
+            match &**opt {
+                "jit-mode" => config.jit_mode = true,
+                _ => return Err(format!("Unknown option `{}`", opt)),
             }
         }
 
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index bcc70f4567f..c8527c3a57d 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -391,7 +391,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
         data.set_align(alloc.align.bytes());
 
         if let Some(section_name) = section_name {
-            let (segment_name, section_name) = if tcx.sess.target.is_like_osx {
+            let (segment_name, section_name) = if tcx.sess.target.is_like_darwin {
                 // See https://github.com/llvm/llvm-project/blob/main/llvm/lib/MC/MCSectionMachO.cpp
                 let mut parts = section_name.as_str().split(',');
                 let Some(segment_name) = parts.next() else {
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
index bba6567774d..286e02b986b 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
@@ -58,7 +58,7 @@ impl DebugContext {
             // FIXME this should be configurable
             // macOS doesn't seem to support DWARF > 3
             // 5 version is required for md5 file hash
-            version: if tcx.sess.target.is_like_osx {
+            version: if tcx.sess.target.is_like_darwin {
                 3
             } else {
                 // FIXME change to version 5 once the gdb and lldb shipping with the latest debian
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
index 017d7784dc0..25b922c8be4 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 
-use crate::{DebugContext, FullyMonomorphizedLayoutCx, has_ptr_meta};
+use crate::{DebugContext, FullyMonomorphizedLayoutCx};
 
 #[derive(Default)]
 pub(crate) struct TypeDebugContext<'tcx> {
@@ -129,7 +129,7 @@ impl DebugContext {
 
         let name = type_names::compute_debuginfo_type_name(tcx, ptr_type, true);
 
-        if !has_ptr_meta(tcx, ptr_type) {
+        if !tcx.type_has_metadata(ptr_type, ty::TypingEnv::fully_monomorphized()) {
             let pointer_type_id =
                 self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_pointer_type);
             let pointer_entry = self.dwarf.unit.get_mut(pointer_type_id);
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index fb7864ae612..444dc441286 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -331,7 +331,7 @@ fn produce_final_output_artifacts(
 }
 
 fn make_module(sess: &Session, name: String) -> UnwindModule<ObjectModule> {
-    let isa = crate::build_isa(sess);
+    let isa = crate::build_isa(sess, false);
 
     let mut builder =
         ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap();
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index 57c88f4b0f9..41f8bb9161c 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
@@ -1,75 +1,27 @@
 //! The JIT driver uses [`cranelift_jit`] to JIT execute programs without writing any object
 //! files.
 
-use std::cell::RefCell;
 use std::ffi::CString;
 use std::os::raw::{c_char, c_int};
-use std::sync::{Mutex, OnceLock, mpsc};
 
-use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
 use cranelift_jit::{JITBuilder, JITModule};
 use rustc_codegen_ssa::CrateInfo;
 use rustc_middle::mir::mono::MonoItem;
 use rustc_session::Session;
 use rustc_span::sym;
 
+use crate::CodegenCx;
 use crate::debuginfo::TypeDebugContext;
 use crate::prelude::*;
 use crate::unwind_module::UnwindModule;
-use crate::{CodegenCx, CodegenMode};
 
-struct JitState {
-    jit_module: UnwindModule<JITModule>,
-}
-
-thread_local! {
-    static LAZY_JIT_STATE: RefCell<Option<JitState>> = const { RefCell::new(None) };
-}
-
-/// The Sender owned by the rustc thread
-static GLOBAL_MESSAGE_SENDER: OnceLock<Mutex<mpsc::Sender<UnsafeMessage>>> = OnceLock::new();
-
-/// A message that is sent from the jitted runtime to the rustc thread.
-/// Senders are responsible for upholding `Send` semantics.
-enum UnsafeMessage {
-    /// Request that the specified `Instance` be lazily jitted.
-    ///
-    /// Nothing accessible through `instance_ptr` may be moved or mutated by the sender after
-    /// this message is sent.
-    JitFn {
-        instance_ptr: *const Instance<'static>,
-        trampoline_ptr: *const u8,
-        tx: mpsc::Sender<*const u8>,
-    },
-}
-unsafe impl Send for UnsafeMessage {}
-
-impl UnsafeMessage {
-    /// Send the message.
-    fn send(self) {
-        thread_local! {
-            /// The Sender owned by the local thread
-            static LOCAL_MESSAGE_SENDER: mpsc::Sender<UnsafeMessage> =
-                GLOBAL_MESSAGE_SENDER
-                    .get().unwrap()
-                    .lock().unwrap()
-                    .clone();
-        }
-        LOCAL_MESSAGE_SENDER.with(|sender| {
-            sender.send(self).expect("rustc thread hung up before lazy JIT request was sent")
-        })
-    }
-}
-
-fn create_jit_module(tcx: TyCtxt<'_>, hotswap: bool) -> (UnwindModule<JITModule>, CodegenCx) {
+fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule<JITModule>, CodegenCx) {
     let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
 
-    let isa = crate::build_isa(tcx.sess);
+    let isa = crate::build_isa(tcx.sess, true);
     let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
-    jit_builder.hotswap(hotswap);
     crate::compiler_builtins::register_functions_for_jit(&mut jit_builder);
     jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info));
-    jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8);
     let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false);
 
     let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name);
@@ -79,7 +31,7 @@ fn create_jit_module(tcx: TyCtxt<'_>, hotswap: bool) -> (UnwindModule<JITModule>
     (jit_module, cx)
 }
 
-pub(crate) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode, jit_args: Vec<String>) -> ! {
+pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec<String>) -> ! {
     if !tcx.sess.opts.output_types.should_codegen() {
         tcx.dcx().fatal("JIT mode doesn't work with `cargo check`");
     }
@@ -88,8 +40,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode, jit_args: Vec<
         tcx.dcx().fatal("can't jit non-executable crate");
     }
 
-    let (mut jit_module, mut cx) =
-        create_jit_module(tcx, matches!(codegen_mode, CodegenMode::JitLazy));
+    let (mut jit_module, mut cx) = create_jit_module(tcx);
     let mut cached_context = Context::new();
 
     let cgus = tcx.collect_and_partition_mono_items(()).codegen_units;
@@ -105,21 +56,15 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode, jit_args: Vec<
         super::predefine_mono_items(tcx, &mut jit_module, &mono_items);
         for (mono_item, _) in mono_items {
             match mono_item {
-                MonoItem::Fn(inst) => match codegen_mode {
-                    CodegenMode::Aot => unreachable!(),
-                    CodegenMode::Jit => {
-                        codegen_and_compile_fn(
-                            tcx,
-                            &mut cx,
-                            &mut cached_context,
-                            &mut jit_module,
-                            inst,
-                        );
-                    }
-                    CodegenMode::JitLazy => {
-                        codegen_shim(tcx, &mut cached_context, &mut jit_module, inst)
-                    }
-                },
+                MonoItem::Fn(inst) => {
+                    codegen_and_compile_fn(
+                        tcx,
+                        &mut cx,
+                        &mut cached_context,
+                        &mut jit_module,
+                        inst,
+                    );
+                }
                 MonoItem::Static(def_id) => {
                     crate::constant::codegen_static(tcx, &mut jit_module, def_id);
                 }
@@ -161,41 +106,17 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode, jit_args: Vec<
     let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap();
     let finalized_start: *const u8 = jit_module.module.get_finalized_function(start_func_id);
 
-    LAZY_JIT_STATE.with(|lazy_jit_state| {
-        let mut lazy_jit_state = lazy_jit_state.borrow_mut();
-        assert!(lazy_jit_state.is_none());
-        *lazy_jit_state = Some(JitState { jit_module });
-    });
-
     let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
         unsafe { ::std::mem::transmute(finalized_start) };
 
-    let (tx, rx) = mpsc::channel();
-    GLOBAL_MESSAGE_SENDER.set(Mutex::new(tx)).unwrap();
-
-    // Spawn the jitted runtime in a new thread so that this rustc thread can handle messages
-    // (eg to lazily JIT further functions as required)
-    std::thread::spawn(move || {
-        let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
+    let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
 
-        // Push a null pointer as a terminating argument. This is required by POSIX and
-        // useful as some dynamic linkers use it as a marker to jump over.
-        argv.push(std::ptr::null());
+    // Push a null pointer as a terminating argument. This is required by POSIX and
+    // useful as some dynamic linkers use it as a marker to jump over.
+    argv.push(std::ptr::null());
 
-        let ret = f(args.len() as c_int, argv.as_ptr());
-        std::process::exit(ret);
-    });
-
-    // Handle messages
-    loop {
-        match rx.recv().unwrap() {
-            // lazy JIT compilation request - compile requested instance and return pointer to result
-            UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx } => {
-                tx.send(jit_fn(instance_ptr, trampoline_ptr))
-                    .expect("jitted runtime hung up before response to lazy JIT request was sent");
-            }
-        }
-    }
+    let ret = f(args.len() as c_int, argv.as_ptr());
+    std::process::exit(ret);
 }
 
 pub(crate) fn codegen_and_compile_fn<'tcx>(
@@ -227,58 +148,6 @@ pub(crate) fn codegen_and_compile_fn<'tcx>(
     });
 }
 
-extern "C" fn clif_jit_fn(
-    instance_ptr: *const Instance<'static>,
-    trampoline_ptr: *const u8,
-) -> *const u8 {
-    // send the JIT request to the rustc thread, with a channel for the response
-    let (tx, rx) = mpsc::channel();
-    UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx }.send();
-
-    // block on JIT compilation result
-    rx.recv().expect("rustc thread hung up before responding to sent lazy JIT request")
-}
-
-fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> *const u8 {
-    rustc_middle::ty::tls::with(|tcx| {
-        // lift is used to ensure the correct lifetime for instance.
-        let instance = tcx.lift(unsafe { *instance_ptr }).unwrap();
-
-        LAZY_JIT_STATE.with(|lazy_jit_state| {
-            let mut lazy_jit_state = lazy_jit_state.borrow_mut();
-            let lazy_jit_state = lazy_jit_state.as_mut().unwrap();
-            let jit_module = &mut lazy_jit_state.jit_module;
-
-            let name = tcx.symbol_name(instance).name;
-            let sig = crate::abi::get_function_sig(
-                tcx,
-                jit_module.target_config().default_call_conv,
-                instance,
-            );
-            let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap();
-
-            let current_ptr = jit_module.module.read_got_entry(func_id);
-
-            // If the function's GOT entry has already been updated to point at something other
-            // than the shim trampoline, don't re-jit but just return the new pointer instead.
-            // This does not need synchronization as this code is executed only by a sole rustc
-            // thread.
-            if current_ptr != trampoline_ptr {
-                return current_ptr;
-            }
-
-            jit_module.module.prepare_for_function_redefine(func_id).unwrap();
-
-            let mut cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name);
-            codegen_and_compile_fn(tcx, &mut cx, &mut Context::new(), jit_module, instance);
-
-            assert!(cx.global_asm.is_empty());
-            jit_module.finalize_definitions();
-            jit_module.module.get_finalized_function(func_id)
-        })
-    })
-}
-
 fn dep_symbol_lookup_fn(
     sess: &Session,
     crate_info: CrateInfo,
@@ -326,57 +195,3 @@ fn dep_symbol_lookup_fn(
         None
     })
 }
-
-fn codegen_shim<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    cached_context: &mut Context,
-    module: &mut UnwindModule<JITModule>,
-    inst: Instance<'tcx>,
-) {
-    let pointer_type = module.target_config().pointer_type();
-
-    let name = tcx.symbol_name(inst).name;
-    let sig = crate::abi::get_function_sig(tcx, module.target_config().default_call_conv, inst);
-    let func_id = module.declare_function(name, Linkage::Export, &sig).unwrap();
-
-    let instance_ptr = Box::into_raw(Box::new(inst));
-
-    let jit_fn = module
-        .declare_function(
-            "__clif_jit_fn",
-            Linkage::Import,
-            &Signature {
-                call_conv: module.target_config().default_call_conv,
-                params: vec![AbiParam::new(pointer_type), AbiParam::new(pointer_type)],
-                returns: vec![AbiParam::new(pointer_type)],
-            },
-        )
-        .unwrap();
-
-    let context = cached_context;
-    context.clear();
-    let trampoline = &mut context.func;
-    trampoline.signature = sig.clone();
-
-    let mut builder_ctx = FunctionBuilderContext::new();
-    let mut trampoline_builder = FunctionBuilder::new(trampoline, &mut builder_ctx);
-
-    let trampoline_fn = module.declare_func_in_func(func_id, trampoline_builder.func);
-    let jit_fn = module.declare_func_in_func(jit_fn, trampoline_builder.func);
-    let sig_ref = trampoline_builder.func.import_signature(sig);
-
-    let entry_block = trampoline_builder.create_block();
-    trampoline_builder.append_block_params_for_function_params(entry_block);
-    let fn_args = trampoline_builder.func.dfg.block_params(entry_block).to_vec();
-
-    trampoline_builder.switch_to_block(entry_block);
-    let instance_ptr = trampoline_builder.ins().iconst(pointer_type, instance_ptr as u64 as i64);
-    let trampoline_ptr = trampoline_builder.ins().func_addr(pointer_type, trampoline_fn);
-    let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr, trampoline_ptr]);
-    let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0];
-    let call_inst = trampoline_builder.ins().call_indirect(sig_ref, jitted_fn, &fn_args);
-    let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec();
-    trampoline_builder.ins().return_(&ret_vals);
-
-    module.define_function(func_id, context).unwrap();
-}
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 310b226814d..fbc33a64285 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -612,6 +612,15 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
             generated_asm.push_str(".att_syntax\n");
         }
 
+        if self.arch == InlineAsmArch::AArch64 {
+            for feature in &self.tcx.codegen_fn_attrs(self.enclosing_def_id).target_features {
+                if feature.name == sym::neon {
+                    continue;
+                }
+                writeln!(generated_asm, ".arch_extension {}", feature.name).unwrap();
+            }
+        }
+
         // The actual inline asm
         for piece in self.template {
             match piece {
@@ -652,6 +661,20 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
                                         .emit(&mut generated_asm, InlineAsmArch::X86_64, *modifier)
                                         .unwrap(),
                                 },
+                                InlineAsmArch::AArch64 => match reg {
+                                    InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => {
+                                        // rustc emits v0 rather than q0
+                                        reg.emit(
+                                            &mut generated_asm,
+                                            InlineAsmArch::AArch64,
+                                            Some(modifier.unwrap_or('q')),
+                                        )
+                                        .unwrap()
+                                    }
+                                    _ => reg
+                                        .emit(&mut generated_asm, InlineAsmArch::AArch64, *modifier)
+                                        .unwrap(),
+                                },
                                 _ => reg.emit(&mut generated_asm, self.arch, *modifier).unwrap(),
                             }
                         }
@@ -665,6 +688,15 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
         }
         generated_asm.push('\n');
 
+        if self.arch == InlineAsmArch::AArch64 {
+            for feature in &self.tcx.codegen_fn_attrs(self.enclosing_def_id).target_features {
+                if feature.name == sym::neon {
+                    continue;
+                }
+                writeln!(generated_asm, ".arch_extension no{}", feature.name).unwrap();
+            }
+        }
+
         if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
             generated_asm.push_str(".intel_syntax noprefix\n");
         }
@@ -809,7 +841,13 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
             }
             InlineAsmArch::AArch64 => {
                 generated_asm.push_str("    str ");
-                reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap();
+                match reg {
+                    InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => {
+                        // rustc emits v0 rather than q0
+                        reg.emit(generated_asm, InlineAsmArch::AArch64, Some('q')).unwrap()
+                    }
+                    _ => reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap(),
+                }
                 writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
             }
             InlineAsmArch::RiscV64 => {
@@ -851,7 +889,13 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
             }
             InlineAsmArch::AArch64 => {
                 generated_asm.push_str("    ldr ");
-                reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap();
+                match reg {
+                    InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => {
+                        // rustc emits v0 rather than q0
+                        reg.emit(generated_asm, InlineAsmArch::AArch64, Some('q')).unwrap()
+                    }
+                    _ => reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap(),
+                }
                 writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
             }
             InlineAsmArch::RiscV64 => {
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
index 720a0d8fbf5..eb0dfbb69c3 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
@@ -54,6 +54,14 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
             );
         }
 
+        "llvm.fptosi.sat.v4i32.v4f32" => {
+            intrinsic_args!(fx, args => (a); intrinsic);
+
+            simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+                fx.bcx.ins().fcvt_to_sint_sat(types::I32, lane)
+            });
+        }
+
         _ => {
             fx.tcx
                 .dcx()
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
index 4c59c81296b..387c87d123a 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
@@ -1,5 +1,9 @@
 //! Emulate AArch64 LLVM intrinsics
 
+use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_target::asm::*;
+
+use crate::inline_asm::{CInlineAsmOperand, codegen_inline_asm_inner};
 use crate::intrinsics::*;
 use crate::prelude::*;
 
@@ -17,7 +21,7 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
             fx.bcx.ins().fence();
         }
 
-        "llvm.aarch64.neon.ld1x4.v16i8.p0i8" => {
+        "llvm.aarch64.neon.ld1x4.v16i8.p0" => {
             intrinsic_args!(fx, args => (ptr); intrinsic);
 
             let ptr = ptr.load_scalar(fx);
@@ -49,6 +53,121 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
             });
         }
 
+        "llvm.aarch64.neon.fcvtns.v4i32.v4f32" => {
+            intrinsic_args!(fx, args => (a); intrinsic);
+
+            // Note: Using inline asm instead of fcvt_to_sint as the latter rounds to zero rather than to nearest
+
+            let a_ptr = a.force_stack(fx).0.get_addr(fx);
+            let res_place = CPlace::new_stack_slot(fx, ret.layout());
+            let res_ptr = res_place.to_ptr().get_addr(fx);
+
+            codegen_inline_asm_inner(
+                fx,
+                &[InlineAsmTemplatePiece::String(
+                    "ldr     q0, [x0]
+                     fcvtns  v0.4s, v0.4s
+                     str     q0, [x1]"
+                        .into(),
+                )],
+                &[
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
+                            AArch64InlineAsmReg::x0,
+                        )),
+                        value: a_ptr,
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
+                            AArch64InlineAsmReg::x1,
+                        )),
+                        value: res_ptr,
+                    },
+                ],
+                InlineAsmOptions::NOSTACK,
+            );
+            let res = res_place.to_cvalue(fx);
+            ret.write_cvalue_transmute(fx, res);
+        }
+
+        "llvm.aarch64.neon.frecpe.v4f32" => {
+            intrinsic_args!(fx, args => (a); intrinsic);
+
+            let a_ptr = a.force_stack(fx).0.get_addr(fx);
+            let res_place = CPlace::new_stack_slot(fx, ret.layout());
+            let res_ptr = res_place.to_ptr().get_addr(fx);
+
+            codegen_inline_asm_inner(
+                fx,
+                &[InlineAsmTemplatePiece::String(
+                    "ldr     q0, [x0]
+                     frecpe  v0.4s, v0.4s
+                     str     q0, [x1]"
+                        .into(),
+                )],
+                &[
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
+                            AArch64InlineAsmReg::x0,
+                        )),
+                        value: a_ptr,
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
+                            AArch64InlineAsmReg::x1,
+                        )),
+                        value: res_ptr,
+                    },
+                ],
+                InlineAsmOptions::NOSTACK,
+            );
+            let res = res_place.to_cvalue(fx);
+            ret.write_cvalue_transmute(fx, res);
+        }
+
+        "llvm.aarch64.neon.frecps.v4f32" => {
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+
+            let a_ptr = a.force_stack(fx).0.get_addr(fx);
+            let b_ptr = b.force_stack(fx).0.get_addr(fx);
+            let res_place = CPlace::new_stack_slot(fx, ret.layout());
+            let res_ptr = res_place.to_ptr().get_addr(fx);
+
+            codegen_inline_asm_inner(
+                fx,
+                &[InlineAsmTemplatePiece::String(
+                    "ldr     q0, [x0]
+                     ldr     q1, [x1]
+                     frecps  v0.4s, v0.4s, v1.4s
+                     str     q0, [x2]"
+                        .into(),
+                )],
+                &[
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
+                            AArch64InlineAsmReg::x0,
+                        )),
+                        value: a_ptr,
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
+                            AArch64InlineAsmReg::x1,
+                        )),
+                        value: b_ptr,
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
+                            AArch64InlineAsmReg::x2,
+                        )),
+                        value: res_ptr,
+                    },
+                ],
+                InlineAsmOptions::NOSTACK,
+            );
+            let res = res_place.to_cvalue(fx);
+            ret.write_cvalue_transmute(fx, res);
+        }
+
         _ if intrinsic.starts_with("llvm.aarch64.neon.sqadd.v")
             || intrinsic.starts_with("llvm.aarch64.neon.uqadd.v") =>
         {
@@ -134,7 +253,7 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
             }
             let res = CValue::by_val(
                 fx.bcx.ins().uextend(types::I32, res_val),
-                fx.layout_of(fx.tcx.types.u32),
+                fx.layout_of(fx.tcx.types.i32),
             );
             ret.write_cvalue(fx, res);
         }
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index ab3386a9b4c..e7afaff3b42 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -42,7 +42,6 @@ use std::sync::Arc;
 use cranelift_codegen::isa::TargetIsa;
 use cranelift_codegen::settings::{self, Configurable};
 use rustc_codegen_ssa::CodegenResults;
-use rustc_codegen_ssa::back::versioned_llvm_target;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
@@ -214,15 +213,14 @@ impl CodegenBackend for CraneliftCodegenBackend {
             BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
                 .unwrap_or_else(|err| tcx.sess.dcx().fatal(err))
         });
-        match config.codegen_mode {
-            CodegenMode::Aot => driver::aot::run_aot(tcx, metadata, need_metadata_module),
-            CodegenMode::Jit | CodegenMode::JitLazy => {
-                #[cfg(feature = "jit")]
-                driver::jit::run_jit(tcx, config.codegen_mode, config.jit_args);
-
-                #[cfg(not(feature = "jit"))]
-                tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift");
-            }
+        if config.jit_mode {
+            #[cfg(feature = "jit")]
+            driver::jit::run_jit(tcx, config.jit_args);
+
+            #[cfg(not(feature = "jit"))]
+            tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift");
+        } else {
+            driver::aot::run_aot(tcx, metadata, need_metadata_module)
         }
     }
 
@@ -247,21 +245,19 @@ fn enable_verifier(sess: &Session) -> bool {
 }
 
 fn target_triple(sess: &Session) -> target_lexicon::Triple {
-    // FIXME(madsmtm): Use `sess.target.llvm_target` once target-lexicon supports unversioned macOS.
-    // See <https://github.com/bytecodealliance/target-lexicon/pull/113>
-    match versioned_llvm_target(sess).parse() {
+    match sess.target.llvm_target.parse() {
         Ok(triple) => triple,
         Err(err) => sess.dcx().fatal(format!("target not recognized: {}", err)),
     }
 }
 
-fn build_isa(sess: &Session) -> Arc<dyn TargetIsa + 'static> {
+fn build_isa(sess: &Session, jit: bool) -> Arc<dyn TargetIsa + 'static> {
     use target_lexicon::BinaryFormat;
 
     let target_triple = crate::target_triple(sess);
 
     let mut flags_builder = settings::builder();
-    flags_builder.enable("is_pic").unwrap();
+    flags_builder.set("is_pic", if jit { "false" } else { "true" }).unwrap();
     let enable_verifier = if enable_verifier(sess) { "true" } else { "false" };
     flags_builder.set("enable_verifier", enable_verifier).unwrap();
     flags_builder.set("regalloc_checker", enable_verifier).unwrap();
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs
index f44e2459a78..2a4d1e3ae57 100644
--- a/compiler/rustc_codegen_cranelift/src/num.rs
+++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -395,8 +395,12 @@ pub(crate) fn codegen_ptr_binop<'tcx>(
     in_lhs: CValue<'tcx>,
     in_rhs: CValue<'tcx>,
 ) -> CValue<'tcx> {
-    let is_thin_ptr =
-        in_lhs.layout().ty.builtin_deref(true).map(|ty| !has_ptr_meta(fx.tcx, ty)).unwrap_or(true);
+    let is_thin_ptr = in_lhs
+        .layout()
+        .ty
+        .builtin_deref(true)
+        .map(|ty| !fx.tcx.type_has_metadata(ty, ty::TypingEnv::fully_monomorphized()))
+        .unwrap_or(true);
 
     if is_thin_ptr {
         match bin_op {
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index cc739fefcd0..f8a19589fdd 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -746,7 +746,7 @@ impl<'tcx> CPlace<'tcx> {
         };
 
         let (field_ptr, field_layout) = codegen_field(fx, base, extra, layout, field);
-        if has_ptr_meta(fx.tcx, field_layout.ty) {
+        if fx.tcx.type_has_metadata(field_layout.ty, ty::TypingEnv::fully_monomorphized()) {
             CPlace::for_ptr_with_extra(field_ptr, extra.unwrap(), field_layout)
         } else {
             CPlace::for_ptr(field_ptr, field_layout)
@@ -832,7 +832,7 @@ impl<'tcx> CPlace<'tcx> {
 
     pub(crate) fn place_deref(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CPlace<'tcx> {
         let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap());
-        if has_ptr_meta(fx.tcx, inner_layout.ty) {
+        if fx.tcx.type_has_metadata(inner_layout.ty, ty::TypingEnv::fully_monomorphized()) {
             let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
             CPlace::for_ptr_with_extra(Pointer::new(addr), extra, inner_layout)
         } else {
@@ -845,7 +845,7 @@ impl<'tcx> CPlace<'tcx> {
         fx: &mut FunctionCx<'_, '_, 'tcx>,
         layout: TyAndLayout<'tcx>,
     ) -> CValue<'tcx> {
-        if has_ptr_meta(fx.tcx, self.layout().ty) {
+        if fx.tcx.type_has_metadata(self.layout().ty, ty::TypingEnv::fully_monomorphized()) {
             let (ptr, extra) = self.to_ptr_unsized();
             CValue::by_val_pair(ptr.get_addr(fx), extra, layout)
         } else {
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index 474475f311f..acb39374628 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -131,7 +131,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
             // will use load-unaligned instructions instead, and thus avoiding the crash.
             //
             // We could remove this hack whenever we decide to drop macOS 10.10 support.
-            if self.tcx.sess.target.options.is_like_osx {
+            if self.tcx.sess.target.options.is_like_darwin {
                 // The `inspect` method is okay here because we checked for provenance, and
                 // because we are doing this access to inspect the final interpreter state
                 // (not as part of the interpreter execution).
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index 17f2e7ca9f7..41391b096cc 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -56,6 +56,8 @@ codegen_llvm_prepare_thin_lto_module_with_llvm_err = failed to prepare thin LTO
 codegen_llvm_run_passes = failed to run LLVM passes
 codegen_llvm_run_passes_with_llvm_err = failed to run LLVM passes: {$llvm_err}
 
+codegen_llvm_sanitizer_kcfi_arity_requires_llvm_21_0_0 = `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later.
+
 codegen_llvm_sanitizer_memtag_requires_mte =
     `-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`
 
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 71059338151..8294e29d07d 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -17,14 +17,13 @@ use rustc_target::callconv::{
 use rustc_target::spec::SanitizerSet;
 use smallvec::SmallVec;
 
-use crate::attributes::llfn_attrs_from_instance;
+use crate::attributes::{self, llfn_attrs_from_instance};
 use crate::builder::Builder;
 use crate::context::CodegenCx;
 use crate::llvm::{self, Attribute, AttributePlace};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use crate::{attributes, llvm_util};
 
 trait ArgAttributesExt {
     fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value);
@@ -437,7 +436,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
 
         let apply_range_attr = |idx: AttributePlace, scalar: rustc_abi::Scalar| {
             if cx.sess().opts.optimize != config::OptLevel::No
-                && llvm_util::get_version() >= (19, 0, 0)
                 && matches!(scalar.primitive(), Primitive::Int(..))
                 // If the value is a boolean, the range is 0..2 and that ultimately
                 // become 0..0 when the type becomes i1, which would be rejected
@@ -571,19 +569,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             }
             _ => {}
         }
-        if bx.cx.sess().opts.optimize != config::OptLevel::No
-                && llvm_util::get_version() < (19, 0, 0)
-                && let BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr
-                && matches!(scalar.primitive(), Primitive::Int(..))
-                // If the value is a boolean, the range is 0..2 and that ultimately
-                // become 0..0 when the type becomes i1, which would be rejected
-                // by the LLVM verifier.
-                && !scalar.is_bool()
-                // LLVM also rejects full range.
-                && !scalar.is_always_valid(bx)
-        {
-            bx.range_metadata(callsite, scalar.valid_range(bx));
-        }
         for arg in self.args.iter() {
             match &arg.mode {
                 PassMode::Ignore => {}
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 3d7afa17bdf..e8c42d16733 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -407,30 +407,28 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         // Do not set sanitizer attributes for naked functions.
         to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
 
-        if llvm_util::get_version() >= (19, 0, 0) {
-            // For non-naked functions, set branch protection attributes on aarch64.
-            if let Some(BranchProtection { bti, pac_ret }) =
-                cx.sess().opts.unstable_opts.branch_protection
-            {
-                assert!(cx.sess().target.arch == "aarch64");
-                if bti {
-                    to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
-                }
-                if let Some(PacRet { leaf, pc, key }) = pac_ret {
-                    if pc {
-                        to_add.push(llvm::CreateAttrString(cx.llcx, "branch-protection-pauth-lr"));
-                    }
-                    to_add.push(llvm::CreateAttrStringValue(
-                        cx.llcx,
-                        "sign-return-address",
-                        if leaf { "all" } else { "non-leaf" },
-                    ));
-                    to_add.push(llvm::CreateAttrStringValue(
-                        cx.llcx,
-                        "sign-return-address-key",
-                        if key == PAuthKey::A { "a_key" } else { "b_key" },
-                    ));
+        // For non-naked functions, set branch protection attributes on aarch64.
+        if let Some(BranchProtection { bti, pac_ret }) =
+            cx.sess().opts.unstable_opts.branch_protection
+        {
+            assert!(cx.sess().target.arch == "aarch64");
+            if bti {
+                to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
+            }
+            if let Some(PacRet { leaf, pc, key }) = pac_ret {
+                if pc {
+                    to_add.push(llvm::CreateAttrString(cx.llcx, "branch-protection-pauth-lr"));
                 }
+                to_add.push(llvm::CreateAttrStringValue(
+                    cx.llcx,
+                    "sign-return-address",
+                    if leaf { "all" } else { "non-leaf" },
+                ));
+                to_add.push(llvm::CreateAttrStringValue(
+                    cx.llcx,
+                    "sign-return-address-key",
+                    if key == PAuthKey::A { "a_key" } else { "b_key" },
+                ));
             }
         }
     }
@@ -510,12 +508,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
             InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
             InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
         }))
-        // HACK: LLVM versions 19+ do not have the FPMR feature and treat it as always enabled
-        // It only exists as a feature in LLVM 18, cannot be passed down for any other version
-        .chain(match &*cx.tcx.sess.target.arch {
-            "aarch64" if llvm_util::get_version().0 == 18 => vec!["+fpmr".to_string()],
-            _ => vec![],
-        })
         .collect::<Vec<String>>();
 
     if cx.tcx.sess.target.is_like_wasm {
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index f083cfbd7d3..a8b49e9552c 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -610,6 +610,8 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff], module: &mut ModuleCodegen<
             }
             // We handle this below
             config::AutoDiff::PrintModAfter => {}
+            // We handle this below
+            config::AutoDiff::PrintModFinal => {}
             // This is required and already checked
             config::AutoDiff::Enable => {}
         }
@@ -657,14 +659,20 @@ pub(crate) fn run_pass_manager(
     }
 
     if cfg!(llvm_enzyme) && enable_ad {
+        // This is the post-autodiff IR, mainly used for testing and educational purposes.
+        if config.autodiff.contains(&config::AutoDiff::PrintModAfter) {
+            unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) };
+        }
+
         let opt_stage = llvm::OptStage::FatLTO;
         let stage = write::AutodiffStage::PostAD;
         unsafe {
             write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?;
         }
 
-        // This is the final IR, so people should be able to inspect the optimized autodiff output.
-        if config.autodiff.contains(&config::AutoDiff::PrintModAfter) {
+        // This is the final IR, so people should be able to inspect the optimized autodiff output,
+        // for manual inspection.
+        if config.autodiff.contains(&config::AutoDiff::PrintModFinal) {
             unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) };
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index bead4c82a81..bf6138142b6 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -1024,7 +1024,7 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data:
 }
 
 pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) -> &'static CStr {
-    if cgcx.target_is_like_osx {
+    if cgcx.target_is_like_darwin {
         c"__LLVM,__bitcode"
     } else if cgcx.target_is_like_aix {
         c".ipa"
@@ -1077,7 +1077,7 @@ unsafe fn embed_bitcode(
     // and COFF we emit the sections using module level inline assembly for that
     // reason (see issue #90326 for historical background).
     unsafe {
-        if cgcx.target_is_like_osx
+        if cgcx.target_is_like_darwin
             || cgcx.target_is_like_aix
             || cgcx.target_arch == "wasm32"
             || cgcx.target_arch == "wasm64"
@@ -1096,7 +1096,7 @@ unsafe fn embed_bitcode(
             let llglobal =
                 llvm::add_global(llmod, common::val_ty(llconst), c"rustc.embedded.cmdline");
             llvm::set_initializer(llglobal, llconst);
-            let section = if cgcx.target_is_like_osx {
+            let section = if cgcx.target_is_like_darwin {
                 c"__LLVM,__cmdline"
             } else if cgcx.target_is_like_aix {
                 c".info"
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 297f104d124..35134e9f5a0 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -30,6 +30,7 @@ use smallvec::SmallVec;
 use tracing::{debug, instrument};
 
 use crate::abi::FnAbiLlvmExt;
+use crate::attributes;
 use crate::common::Funclet;
 use crate::context::{CodegenCx, FullCx, GenericCx, SCx};
 use crate::llvm::{
@@ -38,7 +39,6 @@ use crate::llvm::{
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use crate::{attributes, llvm_util};
 
 #[must_use]
 pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SCx<'ll>>> {
@@ -927,11 +927,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         debug_assert_ne!(self.val_ty(val), dest_ty);
 
         let trunc = self.trunc(val, dest_ty);
-        if llvm_util::get_version() >= (19, 0, 0) {
-            unsafe {
-                if llvm::LLVMIsAInstruction(trunc).is_some() {
-                    llvm::LLVMSetNUW(trunc, True);
-                }
+        unsafe {
+            if llvm::LLVMIsAInstruction(trunc).is_some() {
+                llvm::LLVMSetNUW(trunc, True);
             }
         }
         trunc
@@ -941,11 +939,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         debug_assert_ne!(self.val_ty(val), dest_ty);
 
         let trunc = self.trunc(val, dest_ty);
-        if llvm_util::get_version() >= (19, 0, 0) {
-            unsafe {
-                if llvm::LLVMIsAInstruction(trunc).is_some() {
-                    llvm::LLVMSetNSW(trunc, True);
-                }
+        unsafe {
+            if llvm::LLVMIsAInstruction(trunc).is_some() {
+                llvm::LLVMSetNSW(trunc, True);
             }
         }
         trunc
@@ -1899,10 +1895,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         hash: &'ll Value,
         bitmap_bits: &'ll Value,
     ) {
-        assert!(
-            crate::llvm_util::get_version() >= (19, 0, 0),
-            "MCDC intrinsics require LLVM 19 or later"
-        );
         self.call_intrinsic("llvm.instrprof.mcdc.parameters", &[fn_name, hash, bitmap_bits]);
     }
 
@@ -1914,10 +1906,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         bitmap_index: &'ll Value,
         mcdc_temp: &'ll Value,
     ) {
-        assert!(
-            crate::llvm_util::get_version() >= (19, 0, 0),
-            "MCDC intrinsics require LLVM 19 or later"
-        );
         let args = &[fn_name, hash, bitmap_index, mcdc_temp];
         self.call_intrinsic("llvm.instrprof.mcdc.tvbitmap.update", args);
     }
@@ -1929,10 +1917,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
 
     #[instrument(level = "debug", skip(self))]
     pub(crate) fn mcdc_condbitmap_update(&mut self, cond_index: &'ll Value, mcdc_temp: &'ll Value) {
-        assert!(
-            crate::llvm_util::get_version() >= (19, 0, 0),
-            "MCDC intrinsics require LLVM 19 or later"
-        );
         let align = self.tcx.data_layout.i32_align.abi;
         let current_tv_index = self.load(self.cx.type_i32(), mcdc_temp, align);
         let new_tv_index = self.add(current_tv_index, cond_index);
diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
index 7cd4ee539d8..7d264ba4d00 100644
--- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
+++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
@@ -3,8 +3,10 @@ use std::ptr;
 use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, AutoDiffItem, DiffActivity, DiffMode};
 use rustc_codegen_ssa::ModuleCodegen;
 use rustc_codegen_ssa::back::write::ModuleConfig;
-use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
+use rustc_codegen_ssa::common::TypeKind;
+use rustc_codegen_ssa::traits::BaseTypeCodegenMethods;
 use rustc_errors::FatalError;
+use rustc_middle::bug;
 use tracing::{debug, trace};
 
 use crate::back::write::llvm_err;
@@ -18,21 +20,42 @@ use crate::value::Value;
 use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, llvm};
 
 fn get_params(fnc: &Value) -> Vec<&Value> {
+    let param_num = llvm::LLVMCountParams(fnc) as usize;
+    let mut fnc_args: Vec<&Value> = vec![];
+    fnc_args.reserve(param_num);
     unsafe {
-        let param_num = llvm::LLVMCountParams(fnc) as usize;
-        let mut fnc_args: Vec<&Value> = vec![];
-        fnc_args.reserve(param_num);
         llvm::LLVMGetParams(fnc, fnc_args.as_mut_ptr());
         fnc_args.set_len(param_num);
-        fnc_args
     }
+    fnc_args
 }
 
+fn has_sret(fnc: &Value) -> bool {
+    let num_args = llvm::LLVMCountParams(fnc) as usize;
+    if num_args == 0 {
+        false
+    } else {
+        unsafe { llvm::LLVMRustHasAttributeAtIndex(fnc, 0, llvm::AttributeKind::StructRet) }
+    }
+}
+
+// When we call the `__enzyme_autodiff` or `__enzyme_fwddiff` function, we need to pass all the
+// original inputs, as well as metadata and the additional shadow arguments.
+// This function matches the arguments from the outer function to the inner enzyme call.
+//
+// This function also considers that Rust level arguments not always match the llvm-ir level
+// arguments. A slice, `&[f32]`, for example, is represented as a pointer and a length on
+// llvm-ir level. The number of activities matches the number of Rust level arguments, so we
+// need to match those.
+// FIXME(ZuseZ4): This logic is a bit more complicated than it should be, can we simplify it
+// using iterators and peek()?
 fn match_args_from_caller_to_enzyme<'ll>(
     cx: &SimpleCx<'ll>,
+    width: u32,
     args: &mut Vec<&'ll llvm::Value>,
     inputs: &[DiffActivity],
     outer_args: &[&'ll llvm::Value],
+    has_sret: bool,
 ) {
     debug!("matching autodiff arguments");
     // We now handle the issue that Rust level arguments not always match the llvm-ir level
@@ -44,6 +67,14 @@ fn match_args_from_caller_to_enzyme<'ll>(
     let mut outer_pos: usize = 0;
     let mut activity_pos = 0;
 
+    if has_sret {
+        // Then the first outer arg is the sret pointer. Enzyme doesn't know about sret, so the
+        // inner function will still return something. We increase our outer_pos by one,
+        // and once we're done with all other args we will take the return of the inner call and
+        // update the sret pointer with it
+        outer_pos = 1;
+    }
+
     let enzyme_const = cx.create_metadata("enzyme_const".to_string()).unwrap();
     let enzyme_out = cx.create_metadata("enzyme_out".to_string()).unwrap();
     let enzyme_dup = cx.create_metadata("enzyme_dup".to_string()).unwrap();
@@ -92,23 +123,20 @@ fn match_args_from_caller_to_enzyme<'ll>(
                 // (..., metadata! enzyme_dup, ptr, ptr, int1, ...).
                 // FIXME(ZuseZ4): We will upstream a safety check later which asserts that
                 // int2 >= int1, which means the shadow vector is large enough to store the gradient.
-                assert!(unsafe {
-                    llvm::LLVMRustGetTypeKind(next_outer_ty) == llvm::TypeKind::Integer
-                });
-                let next_outer_arg2 = outer_args[outer_pos + 2];
-                let next_outer_ty2 = cx.val_ty(next_outer_arg2);
-                assert!(unsafe {
-                    llvm::LLVMRustGetTypeKind(next_outer_ty2) == llvm::TypeKind::Pointer
-                });
-                let next_outer_arg3 = outer_args[outer_pos + 3];
-                let next_outer_ty3 = cx.val_ty(next_outer_arg3);
-                assert!(unsafe {
-                    llvm::LLVMRustGetTypeKind(next_outer_ty3) == llvm::TypeKind::Integer
-                });
-                args.push(next_outer_arg2);
+                assert_eq!(cx.type_kind(next_outer_ty), TypeKind::Integer);
+
+                for i in 0..(width as usize) {
+                    let next_outer_arg2 = outer_args[outer_pos + 2 * (i + 1)];
+                    let next_outer_ty2 = cx.val_ty(next_outer_arg2);
+                    assert_eq!(cx.type_kind(next_outer_ty2), TypeKind::Pointer);
+                    let next_outer_arg3 = outer_args[outer_pos + 2 * (i + 1) + 1];
+                    let next_outer_ty3 = cx.val_ty(next_outer_arg3);
+                    assert_eq!(cx.type_kind(next_outer_ty3), TypeKind::Integer);
+                    args.push(next_outer_arg2);
+                }
                 args.push(cx.get_metadata_value(enzyme_const));
                 args.push(next_outer_arg);
-                outer_pos += 4;
+                outer_pos += 2 + 2 * width as usize;
                 activity_pos += 2;
             } else {
                 // A duplicated pointer will have the following two outer_fn arguments:
@@ -116,15 +144,19 @@ fn match_args_from_caller_to_enzyme<'ll>(
                 // (..., metadata! enzyme_dup, ptr, ptr, ...).
                 if matches!(diff_activity, DiffActivity::Duplicated | DiffActivity::DuplicatedOnly)
                 {
-                    assert!(
-                        unsafe { llvm::LLVMRustGetTypeKind(next_outer_ty) }
-                            == llvm::TypeKind::Pointer
-                    );
+                    assert_eq!(cx.type_kind(next_outer_ty), TypeKind::Pointer);
                 }
                 // In the case of Dual we don't have assumptions, e.g. f32 would be valid.
                 args.push(next_outer_arg);
                 outer_pos += 2;
                 activity_pos += 1;
+
+                // Now, if width > 1, we need to account for that
+                for _ in 1..width {
+                    let next_outer_arg = outer_args[outer_pos];
+                    args.push(next_outer_arg);
+                    outer_pos += 1;
+                }
             }
         } else {
             // We do not differentiate with resprect to this argument.
@@ -135,6 +167,76 @@ fn match_args_from_caller_to_enzyme<'ll>(
     }
 }
 
+// On LLVM-IR, we can luckily declare __enzyme_ functions without specifying the input
+// arguments. We do however need to declare them with their correct return type.
+// We already figured the correct return type out in our frontend, when generating the outer_fn,
+// so we can now just go ahead and use that. This is not always trivial, e.g. because sret.
+// Beyond sret, this article describes our challenges nicely:
+// <https://yorickpeterse.com/articles/the-mess-that-is-handling-structure-arguments-and-returns-in-llvm/>
+// I.e. (i32, f32) will get merged into i64, but we don't handle that yet.
+fn compute_enzyme_fn_ty<'ll>(
+    cx: &SimpleCx<'ll>,
+    attrs: &AutoDiffAttrs,
+    fn_to_diff: &'ll Value,
+    outer_fn: &'ll Value,
+) -> &'ll llvm::Type {
+    let fn_ty = cx.get_type_of_global(outer_fn);
+    let mut ret_ty = cx.get_return_type(fn_ty);
+
+    let has_sret = has_sret(outer_fn);
+
+    if has_sret {
+        // Now we don't just forward the return type, so we have to figure it out based on the
+        // primal return type, in combination with the autodiff settings.
+        let fn_ty = cx.get_type_of_global(fn_to_diff);
+        let inner_ret_ty = cx.get_return_type(fn_ty);
+
+        let void_ty = unsafe { llvm::LLVMVoidTypeInContext(cx.llcx) };
+        if inner_ret_ty == void_ty {
+            // This indicates that even the inner function has an sret.
+            // Right now I only look for an sret in the outer function.
+            // This *probably* needs some extra handling, but I never ran
+            // into such a case. So I'll wait for user reports to have a test case.
+            bug!("sret in inner function");
+        }
+
+        if attrs.width == 1 {
+            todo!("Handle sret for scalar ad");
+        } else {
+            // First we check if we also have to deal with the primal return.
+            match attrs.mode {
+                DiffMode::Forward => match attrs.ret_activity {
+                    DiffActivity::Dual => {
+                        let arr_ty =
+                            unsafe { llvm::LLVMArrayType2(inner_ret_ty, attrs.width as u64 + 1) };
+                        ret_ty = arr_ty;
+                    }
+                    DiffActivity::DualOnly => {
+                        let arr_ty =
+                            unsafe { llvm::LLVMArrayType2(inner_ret_ty, attrs.width as u64) };
+                        ret_ty = arr_ty;
+                    }
+                    DiffActivity::Const => {
+                        todo!("Not sure, do we need to do something here?");
+                    }
+                    _ => {
+                        bug!("unreachable");
+                    }
+                },
+                DiffMode::Reverse => {
+                    todo!("Handle sret for reverse mode");
+                }
+                _ => {
+                    bug!("unreachable");
+                }
+            }
+        }
+    }
+
+    // LLVM can figure out the input types on it's own, so we take a shortcut here.
+    unsafe { llvm::LLVMFunctionType(ret_ty, ptr::null(), 0, True) }
+}
+
 /// When differentiating `fn_to_diff`, take a `outer_fn` and generate another
 /// function with expected naming and calling conventions[^1] which will be
 /// discovered by the enzyme LLVM pass and its body populated with the differentiated
@@ -197,17 +299,9 @@ fn generate_enzyme_call<'ll>(
     // }
     // ```
     unsafe {
-        // On LLVM-IR, we can luckily declare __enzyme_ functions without specifying the input
-        // arguments. We do however need to declare them with their correct return type.
-        // We already figured the correct return type out in our frontend, when generating the outer_fn,
-        // so we can now just go ahead and use that. FIXME(ZuseZ4): This doesn't handle sret yet.
-        let fn_ty = llvm::LLVMGlobalGetValueType(outer_fn);
-        let ret_ty = llvm::LLVMGetReturnType(fn_ty);
-
-        // LLVM can figure out the input types on it's own, so we take a shortcut here.
-        let enzyme_ty = llvm::LLVMFunctionType(ret_ty, ptr::null(), 0, True);
+        let enzyme_ty = compute_enzyme_fn_ty(cx, &attrs, fn_to_diff, outer_fn);
 
-        //FIXME(ZuseZ4): the CC/Addr/Vis values are best effort guesses, we should look at tests and
+        // FIXME(ZuseZ4): the CC/Addr/Vis values are best effort guesses, we should look at tests and
         // think a bit more about what should go here.
         let cc = llvm::LLVMGetFunctionCallConv(outer_fn);
         let ad_fn = declare_simple_fn(
@@ -240,14 +334,27 @@ fn generate_enzyme_call<'ll>(
         if matches!(attrs.ret_activity, DiffActivity::Dual | DiffActivity::Active) {
             args.push(cx.get_metadata_value(enzyme_primal_ret));
         }
+        if attrs.width > 1 {
+            let enzyme_width = cx.create_metadata("enzyme_width".to_string()).unwrap();
+            args.push(cx.get_metadata_value(enzyme_width));
+            args.push(cx.get_const_i64(attrs.width as u64));
+        }
 
+        let has_sret = has_sret(outer_fn);
         let outer_args: Vec<&llvm::Value> = get_params(outer_fn);
-        match_args_from_caller_to_enzyme(&cx, &mut args, &attrs.input_activity, &outer_args);
+        match_args_from_caller_to_enzyme(
+            &cx,
+            attrs.width,
+            &mut args,
+            &attrs.input_activity,
+            &outer_args,
+            has_sret,
+        );
 
         let call = builder.call(enzyme_ty, ad_fn, &args, None);
 
         // This part is a bit iffy. LLVM requires that a call to an inlineable function has some
-        // metadata attachted to it, but we just created this code oota. Given that the
+        // metadata attached to it, but we just created this code oota. Given that the
         // differentiated function already has partly confusing metadata, and given that this
         // affects nothing but the auttodiff IR, we take a shortcut and just steal metadata from the
         // dummy code which we inserted at a higher level.
@@ -268,7 +375,22 @@ fn generate_enzyme_call<'ll>(
         // Now that we copied the metadata, get rid of dummy code.
         llvm::LLVMRustEraseInstUntilInclusive(entry, last_inst);
 
-        if cx.val_ty(call) == cx.type_void() {
+        if cx.val_ty(call) == cx.type_void() || has_sret {
+            if has_sret {
+                // This is what we already have in our outer_fn (shortened):
+                // define void @_foo(ptr <..> sret([32 x i8]) initializes((0, 32)) %0, <...>) {
+                //   %7 = call [4 x double] (...) @__enzyme_fwddiff_foo(ptr @square, metadata !"enzyme_width", i64 4, <...>)
+                //   <Here we are, we want to add the following two lines>
+                //   store [4 x double] %7, ptr %0, align 8
+                //   ret void
+                // }
+
+                // now store the result of the enzyme call into the sret pointer.
+                let sret_ptr = outer_args[0];
+                let call_ty = cx.val_ty(call);
+                assert_eq!(cx.type_kind(call_ty), TypeKind::Array);
+                llvm::LLVMBuildStore(&builder.llbuilder, call, sret_ptr);
+            }
             builder.ret_void();
         } else {
             builder.ret(call);
@@ -300,8 +422,7 @@ pub(crate) fn differentiate<'ll>(
     if !diff_items.is_empty()
         && !cgcx.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable)
     {
-        let dcx = cgcx.create_dcx();
-        return Err(dcx.handle().emit_almost_fatal(AutoDiffWithoutEnable));
+        return Err(diag_handler.handle().emit_almost_fatal(AutoDiffWithoutEnable));
     }
 
     // Before dumping the module, we want all the TypeTrees to become part of the module.
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 7675e75338a..bf81eb648f8 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -430,7 +430,7 @@ impl<'ll> CodegenCx<'ll, '_> {
             let val_llty = self.val_ty(v);
 
             let g = self.get_static_inner(def_id, val_llty);
-            let llty = llvm::LLVMGlobalGetValueType(g);
+            let llty = self.get_type_of_global(g);
 
             let g = if val_llty == llty {
                 g
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index f7b096ff976..4ec69995518 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -8,6 +8,7 @@ use std::str;
 use rustc_abi::{HasDataLayout, Size, TargetDataLayout, VariantIdx};
 use rustc_codegen_ssa::back::versioned_llvm_target;
 use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
+use rustc_codegen_ssa::common::TypeKind;
 use rustc_codegen_ssa::errors as ssa_errors;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
@@ -38,7 +39,7 @@ use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
 use crate::llvm::Metadata;
 use crate::type_::Type;
 use crate::value::Value;
-use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};
+use crate::{attributes, common, coverageinfo, debuginfo, llvm, llvm_util};
 
 /// `TyCtxt` (and related cache datastructures) can't be move between threads.
 /// However, there are various cx related functions which we want to be available to the builder and
@@ -163,23 +164,6 @@ pub(crate) unsafe fn create_module<'ll>(
     let mut target_data_layout = sess.target.data_layout.to_string();
     let llvm_version = llvm_util::get_version();
 
-    if llvm_version < (19, 0, 0) {
-        if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") {
-            // LLVM 19 sets -Fn32 in its data layout string for 64-bit ARM
-            // Earlier LLVMs leave this default, so remove it.
-            // See https://github.com/llvm/llvm-project/pull/90702
-            target_data_layout = target_data_layout.replace("-Fn32", "");
-        }
-    }
-
-    if llvm_version < (19, 0, 0) {
-        if sess.target.arch == "loongarch64" {
-            // LLVM 19 updates the LoongArch64 data layout.
-            // See https://github.com/llvm/llvm-project/pull/93814
-            target_data_layout = target_data_layout.replace("-n32:64", "-n64");
-        }
-    }
-
     if llvm_version < (20, 0, 0) {
         if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") {
             // LLVM 20 defines three additional address spaces for alternate
@@ -327,6 +311,22 @@ pub(crate) unsafe fn create_module<'ll>(
                 pfe.prefix().into(),
             );
         }
+
+        // Add "kcfi-arity" module flag if KCFI arity indicator is enabled. (See
+        // https://github.com/llvm/llvm-project/pull/117121.)
+        if sess.is_sanitizer_kcfi_arity_enabled() {
+            // KCFI arity indicator requires LLVM 21.0.0 or later.
+            if llvm_version < (21, 0, 0) {
+                tcx.dcx().emit_err(crate::errors::SanitizerKcfiArityRequiresLLVM2100);
+            }
+
+            llvm::add_module_flag_u32(
+                llmod,
+                llvm::ModuleFlagMergeBehavior::Override,
+                "kcfi-arity",
+                1,
+            );
+        }
     }
 
     // Control Flow Guard is currently only supported by MSVC and LLVM on Windows.
@@ -643,7 +643,18 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
         llvm::set_section(g, c"llvm.metadata");
     }
 }
-
+impl<'ll> SimpleCx<'ll> {
+    pub(crate) fn get_return_type(&self, ty: &'ll Type) -> &'ll Type {
+        assert_eq!(self.type_kind(ty), TypeKind::Function);
+        unsafe { llvm::LLVMGetReturnType(ty) }
+    }
+    pub(crate) fn get_type_of_global(&self, val: &'ll Value) -> &'ll Type {
+        unsafe { llvm::LLVMGlobalGetValueType(val) }
+    }
+    pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type {
+        common::val_ty(v)
+    }
+}
 impl<'ll> SimpleCx<'ll> {
     pub(crate) fn new(
         llmod: &'ll llvm::Module,
@@ -660,6 +671,13 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
         llvm::LLVMMetadataAsValue(self.llcx(), metadata)
     }
 
+    // FIXME(autodiff): We should split `ConstCodegenMethods` to pull the reusable parts
+    // onto a trait that is also implemented for GenericCx.
+    pub(crate) fn get_const_i64(&self, n: u64) -> &'ll Value {
+        let ty = unsafe { llvm::LLVMInt64TypeInContext(self.llcx()) };
+        unsafe { llvm::LLVMConstInt(ty, n, llvm::False) }
+    }
+
     pub(crate) fn get_function(&self, name: &str) -> Option<&'ll Value> {
         let name = SmallCStr::new(name);
         unsafe { llvm::LLVMGetNamedFunction((**self).borrow().llmod, name.as_ptr()) }
@@ -1183,10 +1201,8 @@ impl<'ll> CodegenCx<'ll, '_> {
 
         if self.sess().instrument_coverage() {
             ifn!("llvm.instrprof.increment", fn(ptr, t_i64, t_i32, t_i32) -> void);
-            if crate::llvm_util::get_version() >= (19, 0, 0) {
-                ifn!("llvm.instrprof.mcdc.parameters", fn(ptr, t_i64, t_i32) -> void);
-                ifn!("llvm.instrprof.mcdc.tvbitmap.update", fn(ptr, t_i64, t_i32, ptr) -> void);
-            }
+            ifn!("llvm.instrprof.mcdc.parameters", fn(ptr, t_i64, t_i32) -> void);
+            ifn!("llvm.instrprof.mcdc.tvbitmap.update", fn(ptr, t_i64, t_i32, ptr) -> void);
         }
 
         ifn!("llvm.type.test", fn(ptr, t_metadata) -> i1);
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 4c5a78ca74f..ecf108f988f 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -217,3 +217,7 @@ pub(crate) struct MismatchedDataLayout<'a> {
 pub(crate) struct FixedX18InvalidArch<'a> {
     pub arch: &'a str,
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_llvm_sanitizer_kcfi_arity_requires_llvm_21_0_0)]
+pub(crate) struct SanitizerKcfiArityRequiresLLVM2100;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
index 79e4cc8aa77..a9b3bdf7344 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
@@ -4,7 +4,7 @@
 use libc::{c_char, c_uint};
 
 use super::MetadataKindId;
-use super::ffi::{BasicBlock, Metadata, Module, Type, Value};
+use super::ffi::{AttributeKind, BasicBlock, Metadata, Module, Type, Value};
 use crate::llvm::Bool;
 
 #[link(name = "llvm-wrapper", kind = "static")]
@@ -17,6 +17,8 @@ unsafe extern "C" {
     pub(crate) fn LLVMRustEraseInstFromParent(V: &Value);
     pub(crate) fn LLVMRustGetTerminator<'a>(B: &BasicBlock) -> &'a Value;
     pub(crate) fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool;
+    pub(crate) fn LLVMRustHasAttributeAtIndex(V: &Value, i: c_uint, Kind: AttributeKind) -> bool;
+    pub(crate) fn LLVMRustGetArrayNumElements(Ty: &Type) -> u64;
 }
 
 unsafe extern "C" {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 3ce3761944b..9ff04f72903 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1180,7 +1180,7 @@ unsafe extern "C" {
 
     // Operations on parameters
     pub(crate) fn LLVMIsAArgument(Val: &Value) -> Option<&Value>;
-    pub(crate) fn LLVMCountParams(Fn: &Value) -> c_uint;
+    pub(crate) safe fn LLVMCountParams(Fn: &Value) -> c_uint;
     pub(crate) fn LLVMGetParam(Fn: &Value, Index: c_uint) -> &Value;
 
     // Operations on basic blocks
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 4a166b0872d..36e35f81392 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -256,7 +256,6 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
         ("aarch64", "pmuv3") => Some(LLVMFeature::new("perfmon")),
         ("aarch64", "paca") => Some(LLVMFeature::new("pauth")),
         ("aarch64", "pacg") => Some(LLVMFeature::new("pauth")),
-        ("aarch64", "pauth-lr") if get_version().0 < 19 => None,
         // Before LLVM 20 those two features were packaged together as b16b16
         ("aarch64", "sve-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
         ("aarch64", "sme-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
@@ -270,18 +269,9 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
         ("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
         ("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")),
         // Filter out features that are not supported by the current LLVM version
-        ("aarch64", "fpmr") if get_version().0 != 18 => None,
+        ("aarch64", "fpmr") => None, // only existed in 18
         ("arm", "fp16") => Some(LLVMFeature::new("fullfp16")),
-        // In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single
-        // feature called `fast-unaligned-access`. In LLVM 19, it was split back out.
-        ("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
-            Some(LLVMFeature::new("fast-unaligned-access"))
-        }
         // Filter out features that are not supported by the current LLVM version
-        ("riscv32" | "riscv64", "zaamo") if get_version().0 < 19 => None,
-        ("riscv32" | "riscv64", "zabha") if get_version().0 < 19 => None,
-        ("riscv32" | "riscv64", "zalrsc") if get_version().0 < 19 => None,
-        ("riscv32" | "riscv64", "zama16b") if get_version().0 < 19 => None,
         ("riscv32" | "riscv64", "zacas") if get_version().0 < 20 => None,
         // Enable the evex512 target feature if an avx512 target feature is enabled.
         ("x86", s) if s.starts_with("avx512") => {
@@ -293,11 +283,17 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
         ("sparc", "leoncasa") => Some(LLVMFeature::new("hasleoncasa")),
         // In LLVM 19, there is no `v8plus` feature and `v9` means "SPARC-V9 instruction available and SPARC-V8+ ABI used".
         // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L27-L28
-        // Before LLVM 19, there is no `v8plus` feature and `v9` means "SPARC-V9 instruction available".
+        // Before LLVM 19, there was no `v8plus` feature and `v9` means "SPARC-V9 instruction available".
         // https://github.com/llvm/llvm-project/blob/llvmorg-18.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L26
         ("sparc", "v8plus") if get_version().0 == 19 => Some(LLVMFeature::new("v9")),
-        ("sparc", "v8plus") if get_version().0 < 19 => None,
         ("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")),
+        // These new `amx` variants and `movrs` were introduced in LLVM20
+        ("x86", "amx-avx512" | "amx-fp8" | "amx-movrs" | "amx-tf32" | "amx-transpose")
+            if get_version().0 < 20 =>
+        {
+            None
+        }
+        ("x86", "movrs") if get_version().0 < 20 => None,
         (_, s) => Some(LLVMFeature::new(s)),
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index a64627eaf59..fdf62a08065 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -120,7 +120,7 @@ impl CodegenCx<'_, '_> {
         }
 
         // Match clang by only supporting COFF and ELF for now.
-        if self.tcx.sess.target.is_like_osx {
+        if self.tcx.sess.target.is_like_darwin {
             return false;
         }
 
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 8baa69cefe1..c216f0f4a09 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -399,7 +399,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
             emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), false)
         }
         // macOS / iOS AArch64
-        "aarch64" if target.is_like_osx => {
+        "aarch64" if target.is_like_darwin => {
             emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), true)
         }
         "aarch64" => emit_aapcs_va_arg(bx, addr, target_ty),
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index 954a6014809..1dabf01ffd6 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -4,12 +4,6 @@ codegen_ssa_add_native_library = failed to add native library {$library_path}: {
 
 codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work
 
-codegen_ssa_apple_deployment_target_invalid =
-    failed to parse deployment target specified in {$env_var}: {$error}
-
-codegen_ssa_apple_deployment_target_too_low =
-    deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
-
 codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
 
 codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs
index 2c8b0ec418d..d242efaf4fd 100644
--- a/compiler/rustc_codegen_ssa/src/back/apple.rs
+++ b/compiler/rustc_codegen_ssa/src/back/apple.rs
@@ -1,7 +1,4 @@
-use std::env;
 use std::ffi::OsString;
-use std::fmt::{Display, from_fn};
-use std::num::ParseIntError;
 use std::path::PathBuf;
 use std::process::Command;
 
@@ -9,9 +6,10 @@ use itertools::Itertools;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
 use rustc_session::Session;
 use rustc_target::spec::Target;
+pub(super) use rustc_target::spec::apple::OSVersion;
 use tracing::debug;
 
-use crate::errors::{AppleDeploymentTarget, XcrunError, XcrunSdkPathWarning};
+use crate::errors::{XcrunError, XcrunSdkPathWarning};
 use crate::fluent_generated as fluent;
 
 #[cfg(test)]
@@ -134,124 +132,6 @@ pub(super) fn add_data_and_relocation(
     Ok(())
 }
 
-/// Deployment target or SDK version.
-///
-/// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
-type OSVersion = (u16, u8, u8);
-
-/// Parse an OS version triple (SDK version or deployment target).
-fn parse_version(version: &str) -> Result<OSVersion, ParseIntError> {
-    if let Some((major, minor)) = version.split_once('.') {
-        let major = major.parse()?;
-        if let Some((minor, patch)) = minor.split_once('.') {
-            Ok((major, minor.parse()?, patch.parse()?))
-        } else {
-            Ok((major, minor.parse()?, 0))
-        }
-    } else {
-        Ok((version.parse()?, 0, 0))
-    }
-}
-
-pub fn pretty_version(version: OSVersion) -> impl Display {
-    let (major, minor, patch) = version;
-    from_fn(move |f| {
-        write!(f, "{major}.{minor}")?;
-        if patch != 0 {
-            write!(f, ".{patch}")?;
-        }
-        Ok(())
-    })
-}
-
-/// Minimum operating system versions currently supported by `rustc`.
-fn os_minimum_deployment_target(os: &str) -> OSVersion {
-    // When bumping a version in here, remember to update the platform-support docs too.
-    //
-    // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the
-    // default deployment target, prefer:
-    // ```
-    // $ rustc --print deployment-target
-    // ```
-    match os {
-        "macos" => (10, 12, 0),
-        "ios" => (10, 0, 0),
-        "tvos" => (10, 0, 0),
-        "watchos" => (5, 0, 0),
-        "visionos" => (1, 0, 0),
-        _ => unreachable!("tried to get deployment target for non-Apple platform"),
-    }
-}
-
-/// The deployment target for the given target.
-///
-/// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense
-/// to raise the minimum OS version.
-///
-/// This matches what LLVM does, see in part:
-/// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
-fn minimum_deployment_target(target: &Target) -> OSVersion {
-    match (&*target.os, &*target.arch, &*target.abi) {
-        ("macos", "aarch64", _) => (11, 0, 0),
-        ("ios", "aarch64", "macabi") => (14, 0, 0),
-        ("ios", "aarch64", "sim") => (14, 0, 0),
-        ("ios", _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0),
-        // Mac Catalyst defaults to 13.1 in Clang.
-        ("ios", _, "macabi") => (13, 1, 0),
-        ("tvos", "aarch64", "sim") => (14, 0, 0),
-        ("watchos", "aarch64", "sim") => (7, 0, 0),
-        (os, _, _) => os_minimum_deployment_target(os),
-    }
-}
-
-/// Name of the environment variable used to fetch the deployment target on the given OS.
-pub fn deployment_target_env_var(os: &str) -> &'static str {
-    match os {
-        "macos" => "MACOSX_DEPLOYMENT_TARGET",
-        "ios" => "IPHONEOS_DEPLOYMENT_TARGET",
-        "watchos" => "WATCHOS_DEPLOYMENT_TARGET",
-        "tvos" => "TVOS_DEPLOYMENT_TARGET",
-        "visionos" => "XROS_DEPLOYMENT_TARGET",
-        _ => unreachable!("tried to get deployment target env var for non-Apple platform"),
-    }
-}
-
-/// Get the deployment target based on the standard environment variables, or fall back to the
-/// minimum version supported by `rustc`.
-pub fn deployment_target(sess: &Session) -> OSVersion {
-    let min = minimum_deployment_target(&sess.target);
-    let env_var = deployment_target_env_var(&sess.target.os);
-
-    if let Ok(deployment_target) = env::var(env_var) {
-        match parse_version(&deployment_target) {
-            Ok(version) => {
-                let os_min = os_minimum_deployment_target(&sess.target.os);
-                // It is common that the deployment target is set a bit too low, for example on
-                // macOS Aarch64 to also target older x86_64. So we only want to warn when variable
-                // is lower than the minimum OS supported by rustc, not when the variable is lower
-                // than the minimum for a specific target.
-                if version < os_min {
-                    sess.dcx().emit_warn(AppleDeploymentTarget::TooLow {
-                        env_var,
-                        version: pretty_version(version).to_string(),
-                        os_min: pretty_version(os_min).to_string(),
-                    });
-                }
-
-                // Raise the deployment target to the minimum supported.
-                version.max(min)
-            }
-            Err(error) => {
-                sess.dcx().emit_err(AppleDeploymentTarget::Invalid { env_var, error });
-                min
-            }
-        }
-    } else {
-        // If no deployment target variable is set, default to the minimum found above.
-        min
-    }
-}
-
 pub(super) fn add_version_to_llvm_target(
     llvm_target: &str,
     deployment_target: OSVersion,
@@ -263,18 +143,17 @@ pub(super) fn add_version_to_llvm_target(
     let environment = components.next();
     assert_eq!(components.next(), None, "too many LLVM triple components");
 
-    let (major, minor, patch) = deployment_target;
-
     assert!(
         !os.contains(|c: char| c.is_ascii_digit()),
         "LLVM target must not already be versioned"
     );
 
+    let version = deployment_target.fmt_full();
     if let Some(env) = environment {
         // Insert version into OS, before environment
-        format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}-{env}")
+        format!("{arch}-{vendor}-{os}{version}-{env}")
     } else {
-        format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}")
+        format!("{arch}-{vendor}-{os}{version}")
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/apple/tests.rs b/compiler/rustc_codegen_ssa/src/back/apple/tests.rs
index 8df740a4bcf..5afe79b7195 100644
--- a/compiler/rustc_codegen_ssa/src/back/apple/tests.rs
+++ b/compiler/rustc_codegen_ssa/src/back/apple/tests.rs
@@ -3,24 +3,16 @@ use super::*;
 #[test]
 fn test_add_version_to_llvm_target() {
     assert_eq!(
-        add_version_to_llvm_target("aarch64-apple-macosx", (10, 14, 1)),
+        add_version_to_llvm_target("aarch64-apple-macosx", OSVersion::new(10, 14, 1)),
         "aarch64-apple-macosx10.14.1"
     );
     assert_eq!(
-        add_version_to_llvm_target("aarch64-apple-ios-simulator", (16, 1, 0)),
+        add_version_to_llvm_target("aarch64-apple-ios-simulator", OSVersion::new(16, 1, 0)),
         "aarch64-apple-ios16.1.0-simulator"
     );
 }
 
 #[test]
-fn test_parse_version() {
-    assert_eq!(parse_version("10"), Ok((10, 0, 0)));
-    assert_eq!(parse_version("10.12"), Ok((10, 12, 0)));
-    assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6)));
-    assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99)));
-}
-
-#[test]
 #[cfg_attr(not(target_os = "macos"), ignore = "xcode-select is only available on macOS")]
 fn lookup_developer_dir() {
     let _developer_dir = xcode_select_developer_dir().unwrap();
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index b59d73a9aae..1d05c4eee4d 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -294,7 +294,7 @@ fn link_rlib<'a>(
             let (metadata, metadata_position) = create_wrapper_file(
                 sess,
                 ".rmeta".to_string(),
-                codegen_results.metadata.raw_data(),
+                codegen_results.metadata.stub_or_full(),
             );
             let metadata = emit_wrapper_file(sess, &metadata, tmpdir, METADATA_FILENAME);
             match metadata_position {
@@ -959,9 +959,9 @@ fn link_natively(
                 }
             }
 
-            let (level, src) = codegen_results.crate_info.lint_levels.linker_messages;
+            let level = codegen_results.crate_info.lint_levels.linker_messages;
             let lint = |msg| {
-                lint_level(sess, LINKER_MESSAGES, level, src, None, |diag| {
+                lint_level(sess, LINKER_MESSAGES, level, None, |diag| {
                     LinkerOutput { inner: msg }.decorate_lint(diag)
                 })
             };
@@ -1012,7 +1012,7 @@ fn link_natively(
         // On macOS the external `dsymutil` tool is used to create the packed
         // debug information. Note that this will read debug information from
         // the objects on the filesystem which we'll clean up later.
-        SplitDebuginfo::Packed if sess.target.is_like_osx => {
+        SplitDebuginfo::Packed if sess.target.is_like_darwin => {
             let prog = Command::new("dsymutil").arg(out_filename).output();
             match prog {
                 Ok(prog) => {
@@ -1043,7 +1043,7 @@ fn link_natively(
 
     let strip = sess.opts.cg.strip;
 
-    if sess.target.is_like_osx {
+    if sess.target.is_like_darwin {
         let stripcmd = "rust-objcopy";
         match (strip, crate_type) {
             (Strip::Debuginfo, _) => {
@@ -1241,7 +1241,7 @@ fn add_sanitizer_libraries(
     // Everywhere else the runtimes are currently distributed as static
     // libraries which should be linked to executables only.
     if matches!(crate_type, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro)
-        && !(sess.target.is_like_osx || sess.target.is_like_msvc)
+        && !(sess.target.is_like_darwin || sess.target.is_like_msvc)
     {
         return;
     }
@@ -1294,7 +1294,7 @@ fn link_sanitizer_runtime(
     let channel =
         option_env!("CFG_RELEASE_CHANNEL").map(|channel| format!("-{channel}")).unwrap_or_default();
 
-    if sess.target.is_like_osx {
+    if sess.target.is_like_darwin {
         // On Apple platforms, the sanitizer is always built as a dylib, and
         // LLVM will link to `@rpath/*.dylib`, so we need to specify an
         // rpath to the library as well (the rpath should be absolute, see
@@ -2182,7 +2182,7 @@ fn add_rpath_args(
         let rpath_config = RPathConfig {
             libs: &*libs,
             out_filename: out_filename.to_path_buf(),
-            is_like_osx: sess.target.is_like_osx,
+            is_like_darwin: sess.target.is_like_darwin,
             linker_is_gnu: sess.target.linker_flavor.is_gnu(),
         };
         cmd.link_args(&rpath::get_rpath_linker_args(&rpath_config));
@@ -3044,7 +3044,7 @@ pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool
 /// - The deployment target.
 /// - The SDK version.
 fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
-    if !sess.target.is_like_osx {
+    if !sess.target.is_like_darwin {
         return;
     }
     let LinkerFlavor::Darwin(cc, _) = flavor else {
@@ -3115,8 +3115,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
             _ => bug!("invalid OS/ABI combination for Apple target: {target_os}, {target_abi}"),
         };
 
-        let (major, minor, patch) = apple::deployment_target(sess);
-        let min_version = format!("{major}.{minor}.{patch}");
+        let min_version = sess.apple_deployment_target().fmt_full().to_string();
 
         // The SDK version is used at runtime when compiling with a newer SDK / version of Xcode:
         // - By dyld to give extra warnings and errors, see e.g.:
@@ -3185,10 +3184,10 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
 
             // The presence of `-mmacosx-version-min` makes CC default to
             // macOS, and it sets the deployment target.
-            let (major, minor, patch) = apple::deployment_target(sess);
+            let version = sess.apple_deployment_target().fmt_full();
             // Intentionally pass this as a single argument, Clang doesn't
             // seem to like it otherwise.
-            cmd.cc_arg(&format!("-mmacosx-version-min={major}.{minor}.{patch}"));
+            cmd.cc_arg(&format!("-mmacosx-version-min={version}"));
 
             // macOS has no environment, so with these two, we've told CC the
             // four desired parameters.
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index bcf18cf57be..a09eec5dd74 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -373,7 +373,7 @@ impl<'a> GccLinker<'a> {
         // * On OSX they have their own linker, not binutils'
         // * For WebAssembly the only functional linker is LLD, which doesn't
         //   support hint flags
-        !self.sess.target.is_like_osx && !self.sess.target.is_like_wasm
+        !self.sess.target.is_like_darwin && !self.sess.target.is_like_wasm
     }
 
     // Some platforms take hints about whether a library is static or dynamic.
@@ -425,7 +425,7 @@ impl<'a> GccLinker<'a> {
 
     fn build_dylib(&mut self, crate_type: CrateType, out_filename: &Path) {
         // On mac we need to tell the linker to let this library be rpathed
-        if self.sess.target.is_like_osx {
+        if self.sess.target.is_like_darwin {
             if self.is_cc() {
                 // `-dynamiclib` makes `cc` pass `-dylib` to the linker.
                 self.cc_arg("-dynamiclib");
@@ -471,7 +471,7 @@ impl<'a> GccLinker<'a> {
 
     fn with_as_needed(&mut self, as_needed: bool, f: impl FnOnce(&mut Self)) {
         if !as_needed {
-            if self.sess.target.is_like_osx {
+            if self.sess.target.is_like_darwin {
                 // FIXME(81490): ld64 doesn't support these flags but macOS 11
                 // has -needed-l{} / -needed_library {}
                 // but we have no way to detect that here.
@@ -486,7 +486,7 @@ impl<'a> GccLinker<'a> {
         f(self);
 
         if !as_needed {
-            if self.sess.target.is_like_osx {
+            if self.sess.target.is_like_darwin {
                 // See above FIXME comment
             } else if self.is_gnu && !self.sess.target.is_like_windows {
                 self.link_arg("--as-needed");
@@ -619,7 +619,7 @@ impl<'a> Linker for GccLinker<'a> {
         let colon = if verbatim && self.is_gnu { ":" } else { "" };
         if !whole_archive {
             self.link_or_cc_arg(format!("-l{colon}{name}"));
-        } else if self.sess.target.is_like_osx {
+        } else if self.sess.target.is_like_darwin {
             // -force_load is the macOS equivalent of --whole-archive, but it
             // involves passing the full path to the library to link.
             self.link_arg("-force_load");
@@ -635,7 +635,7 @@ impl<'a> Linker for GccLinker<'a> {
         self.hint_static();
         if !whole_archive {
             self.link_or_cc_arg(path);
-        } else if self.sess.target.is_like_osx {
+        } else if self.sess.target.is_like_darwin {
             self.link_arg("-force_load").link_arg(path);
         } else {
             self.link_arg("--whole-archive").link_arg(path).link_arg("--no-whole-archive");
@@ -670,7 +670,7 @@ impl<'a> Linker for GccLinker<'a> {
         // -dead_strip can't be part of the pre_link_args because it's also used
         // for partial linking when using multiple codegen units (-r). So we
         // insert it here.
-        if self.sess.target.is_like_osx {
+        if self.sess.target.is_like_darwin {
             self.link_arg("-dead_strip");
 
         // If we're building a dylib, we don't use --gc-sections because LLVM
@@ -728,7 +728,7 @@ impl<'a> Linker for GccLinker<'a> {
 
     fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
         // MacOS linker doesn't support stripping symbols directly anymore.
-        if self.sess.target.is_like_osx {
+        if self.sess.target.is_like_darwin {
             return;
         }
 
@@ -795,7 +795,7 @@ impl<'a> Linker for GccLinker<'a> {
 
         debug!("EXPORTED SYMBOLS:");
 
-        if self.sess.target.is_like_osx {
+        if self.sess.target.is_like_darwin {
             // Write a plain, newline-separated list of symbols
             let res: io::Result<()> = try {
                 let mut f = File::create_buffered(&path)?;
@@ -841,7 +841,7 @@ impl<'a> Linker for GccLinker<'a> {
             }
         }
 
-        if self.sess.target.is_like_osx {
+        if self.sess.target.is_like_darwin {
             self.link_arg("-exported_symbols_list").link_arg(path);
         } else if self.sess.target.is_like_solaris {
             self.link_arg("-M").link_arg(path);
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 68b453ff424..ebcccf1b97d 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -214,7 +214,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
 
     let mut file = write::Object::new(binary_format, architecture, endianness);
     file.set_sub_architecture(sub_architecture);
-    if sess.target.is_like_osx {
+    if sess.target.is_like_darwin {
         if macho_is_arm64e(&sess.target) {
             file.set_macho_cpu_subtype(object::macho::CPU_SUBTYPE_ARM64E);
         }
@@ -388,13 +388,13 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
 fn macho_object_build_version_for_target(sess: &Session) -> object::write::MachOBuildVersion {
     /// The `object` crate demands "X.Y.Z encoded in nibbles as xxxx.yy.zz"
     /// e.g. minOS 14.0 = 0x000E0000, or SDK 16.2 = 0x00100200
-    fn pack_version((major, minor, patch): (u16, u8, u8)) -> u32 {
+    fn pack_version(apple::OSVersion { major, minor, patch }: apple::OSVersion) -> u32 {
         let (major, minor, patch) = (major as u32, minor as u32, patch as u32);
         (major << 16) | (minor << 8) | patch
     }
 
     let platform = apple::macho_platform(&sess.target);
-    let min_os = apple::deployment_target(sess);
+    let min_os = sess.apple_deployment_target();
 
     let mut build_version = object::write::MachOBuildVersion::default();
     build_version.platform = platform;
@@ -540,8 +540,8 @@ pub fn create_compressed_metadata_file(
     symbol_name: &str,
 ) -> Vec<u8> {
     let mut packed_metadata = rustc_metadata::METADATA_HEADER.to_vec();
-    packed_metadata.write_all(&(metadata.raw_data().len() as u64).to_le_bytes()).unwrap();
-    packed_metadata.extend(metadata.raw_data());
+    packed_metadata.write_all(&(metadata.stub_or_full().len() as u64).to_le_bytes()).unwrap();
+    packed_metadata.extend(metadata.stub_or_full());
 
     let Some(mut file) = create_object_file(sess) else {
         if sess.target.is_like_wasm {
diff --git a/compiler/rustc_codegen_ssa/src/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs
index 64b5d4569ec..8d1adb99930 100644
--- a/compiler/rustc_codegen_ssa/src/back/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/back/mod.rs
@@ -19,8 +19,8 @@ pub mod write;
 ///
 /// Certain optimizations also depend on the deployment target.
 pub fn versioned_llvm_target(sess: &Session) -> Cow<'_, str> {
-    if sess.target.is_like_osx {
-        apple::add_version_to_llvm_target(&sess.target.llvm_target, apple::deployment_target(sess))
+    if sess.target.is_like_darwin {
+        apple::add_version_to_llvm_target(&sess.target.llvm_target, sess.apple_deployment_target())
             .into()
     } else {
         // FIXME(madsmtm): Certain other targets also include a version,
diff --git a/compiler/rustc_codegen_ssa/src/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs
index d633cc98ac8..7bb8979e882 100644
--- a/compiler/rustc_codegen_ssa/src/back/rpath.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs
@@ -9,7 +9,7 @@ use tracing::debug;
 pub(super) struct RPathConfig<'a> {
     pub libs: &'a [&'a Path],
     pub out_filename: PathBuf,
-    pub is_like_osx: bool,
+    pub is_like_darwin: bool,
     pub linker_is_gnu: bool,
 }
 
@@ -63,7 +63,7 @@ fn get_rpaths_relative_to_output(config: &RPathConfig<'_>) -> Vec<OsString> {
 
 fn get_rpath_relative_to_output(config: &RPathConfig<'_>, lib: &Path) -> OsString {
     // Mac doesn't appear to support $ORIGIN
-    let prefix = if config.is_like_osx { "@loader_path" } else { "$ORIGIN" };
+    let prefix = if config.is_like_darwin { "@loader_path" } else { "$ORIGIN" };
 
     // Strip filenames
     let lib = lib.parent().unwrap();
diff --git a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
index f1a30105c59..ab8fbedb812 100644
--- a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
@@ -28,7 +28,7 @@ fn test_rpath_relative() {
     if cfg!(target_os = "macos") {
         let config = &mut RPathConfig {
             libs: &[],
-            is_like_osx: true,
+            is_like_darwin: true,
             linker_is_gnu: false,
             out_filename: PathBuf::from("bin/rustc"),
         };
@@ -38,7 +38,7 @@ fn test_rpath_relative() {
         let config = &mut RPathConfig {
             libs: &[],
             out_filename: PathBuf::from("bin/rustc"),
-            is_like_osx: false,
+            is_like_darwin: false,
             linker_is_gnu: true,
         };
         let res = get_rpath_relative_to_output(config, Path::new("lib/libstd.so"));
@@ -51,7 +51,7 @@ fn test_rpath_relative_issue_119571() {
     let config = &mut RPathConfig {
         libs: &[],
         out_filename: PathBuf::from("rustc"),
-        is_like_osx: false,
+        is_like_darwin: false,
         linker_is_gnu: true,
     };
     // Should not panic when out_filename only contains filename.
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 216a18e72ed..e816e71379a 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -352,7 +352,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
     pub is_pe_coff: bool,
     pub target_can_use_split_dwarf: bool,
     pub target_arch: String,
-    pub target_is_like_osx: bool,
+    pub target_is_like_darwin: bool,
     pub target_is_like_aix: bool,
     pub split_debuginfo: rustc_target::spec::SplitDebuginfo,
     pub split_dwarf_kind: rustc_session::config::SplitDwarfKind,
@@ -1216,7 +1216,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
         is_pe_coff: tcx.sess.target.is_like_windows,
         target_can_use_split_dwarf: tcx.sess.target_can_use_split_dwarf(),
         target_arch: tcx.sess.target.arch.to_string(),
-        target_is_like_osx: tcx.sess.target.is_like_osx,
+        target_is_like_darwin: tcx.sess.target.is_like_darwin,
         target_is_like_aix: tcx.sess.target.is_like_aix,
         split_debuginfo: tcx.sess.split_debuginfo(),
         split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind,
@@ -2186,7 +2186,7 @@ fn msvc_imps_needed(tcx: TyCtxt<'_>) -> bool {
     // indirectly from ThinLTO. In theory these are not needed as ThinLTO could resolve
     // these, but it currently does not do so.
     let can_have_static_objects =
-        tcx.sess.lto() == Lto::Thin || tcx.crate_types().iter().any(|ct| *ct == CrateType::Rlib);
+        tcx.sess.lto() == Lto::Thin || tcx.crate_types().contains(&CrateType::Rlib);
 
     tcx.sess.target.is_like_windows &&
     can_have_static_objects   &&
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index d16d4ed2283..ddb61188983 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -2,7 +2,7 @@ use std::str::FromStr;
 
 use rustc_abi::ExternAbi;
 use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
-use rustc_ast::{MetaItem, MetaItemInner, attr};
+use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
 use rustc_attr_parsing::ReprAttr::ReprAlign;
 use rustc_attr_parsing::{AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr};
 use rustc_data_structures::fx::FxHashMap;
@@ -213,7 +213,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                         // somewhat, and is subject to change in the future (which
                         // is a good thing, because this would ideally be a bit
                         // more firmed up).
-                        let is_like_elf = !(tcx.sess.target.is_like_osx
+                        let is_like_elf = !(tcx.sess.target.is_like_darwin
                             || tcx.sess.target.is_like_windows
                             || tcx.sess.target.is_like_wasm);
                         codegen_fn_attrs.flags |= if is_like_elf {
@@ -604,7 +604,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     if let Some((name, _)) = lang_items::extract(attrs)
         && let Some(lang_item) = LangItem::from_name(name)
     {
-        if WEAK_LANG_ITEMS.iter().any(|&l| l == lang_item) {
+        if WEAK_LANG_ITEMS.contains(&lang_item) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
         }
         if let Some(link_name) = lang_item.link_name() {
@@ -805,8 +805,8 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
         return Some(AutoDiffAttrs::source());
     }
 
-    let [mode, input_activities @ .., ret_activity] = &list[..] else {
-        span_bug!(attr.span(), "rustc_autodiff attribute must contain mode and activities");
+    let [mode, width_meta, input_activities @ .., ret_activity] = &list[..] else {
+        span_bug!(attr.span(), "rustc_autodiff attribute must contain mode, width and activities");
     };
     let mode = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = mode {
         p1.segments.first().unwrap().ident
@@ -823,6 +823,30 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
         }
     };
 
+    let width: u32 = match width_meta {
+        MetaItemInner::MetaItem(MetaItem { path: p1, .. }) => {
+            let w = p1.segments.first().unwrap().ident;
+            match w.as_str().parse() {
+                Ok(val) => val,
+                Err(_) => {
+                    span_bug!(w.span, "rustc_autodiff width should fit u32");
+                }
+            }
+        }
+        MetaItemInner::Lit(lit) => {
+            if let LitKind::Int(val, _) = lit.kind {
+                match val.get().try_into() {
+                    Ok(val) => val,
+                    Err(_) => {
+                        span_bug!(lit.span, "rustc_autodiff width should fit u32");
+                    }
+                }
+            } else {
+                span_bug!(lit.span, "rustc_autodiff width should be an integer");
+            }
+        }
+    };
+
     // First read the ret symbol from the attribute
     let ret_symbol = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity {
         p1.segments.first().unwrap().ident
@@ -860,7 +884,7 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
         }
     }
 
-    Some(AutoDiffAttrs { mode, ret_activity, input_activity: arg_activities })
+    Some(AutoDiffAttrs { mode, width, ret_activity, input_activity: arg_activities })
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index f52d29baf9d..b33de8802d8 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -3,7 +3,6 @@
 use std::borrow::Cow;
 use std::ffi::OsString;
 use std::io::Error;
-use std::num::ParseIntError;
 use std::path::{Path, PathBuf};
 use std::process::ExitStatus;
 
@@ -739,14 +738,6 @@ pub enum ExtractBundledLibsError<'a> {
 }
 
 #[derive(Diagnostic)]
-pub(crate) enum AppleDeploymentTarget {
-    #[diag(codegen_ssa_apple_deployment_target_invalid)]
-    Invalid { env_var: &'static str, error: ParseIntError },
-    #[diag(codegen_ssa_apple_deployment_target_too_low)]
-    TooLow { env_var: &'static str, version: String, os_min: String },
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_ssa_read_file)]
 pub(crate) struct ReadFileError {
     pub message: std::io::Error,
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index d26d6edf314..67217927a87 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -7,7 +7,6 @@
 #![doc(rust_logo)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
-#![feature(debug_closure_helpers)]
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
@@ -34,7 +33,7 @@ use rustc_hir::CRATE_HIR_ID;
 use rustc_hir::def_id::CrateNum;
 use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_middle::dep_graph::WorkProduct;
-use rustc_middle::lint::LintLevelSource;
+use rustc_middle::lint::LevelAndSource;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::dependency_format::Dependencies;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -45,7 +44,6 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_session::Session;
 use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
 use rustc_session::cstore::{self, CrateSource};
-use rustc_session::lint::Level;
 use rustc_session::lint::builtin::LINKER_MESSAGES;
 use rustc_session::utils::NativeLibKind;
 use rustc_span::Symbol;
@@ -341,7 +339,7 @@ impl CodegenResults {
 /// Instead, encode exactly the information we need.
 #[derive(Copy, Clone, Debug, Encodable, Decodable)]
 pub struct CodegenLintLevels {
-    linker_messages: (Level, LintLevelSource),
+    linker_messages: LevelAndSource,
 }
 
 impl CodegenLintLevels {
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 90002d3f109..2b74c849f1a 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -335,7 +335,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
             self.tcx.dcx().span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`");
         }
         if let Some(def_id) = def_id.as_local()
-            && let Err(guar) = self.tcx.at(span).check_well_formed(hir::OwnerId { def_id })
+            && let Err(guar) = self.tcx.ensure_ok().check_well_formed(hir::OwnerId { def_id })
         {
             self.error_emitted = Some(guar);
         }
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 496f6c86f71..61a7ec13511 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -546,7 +546,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
                         rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL,
                         hir_id,
                     )
-                    .0
+                    .level
                     .is_error();
                 let span = ecx.cur_span();
                 ecx.tcx.emit_node_span_lint(
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 3776fb55c2e..34239ae1d15 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -256,7 +256,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
         Err(err) => {
             let did = cid.instance.def_id();
             let global_const_id = cid.display(tcx);
-            let span = tcx.hir().span_if_local(did);
+            let span = tcx.hir_span_if_local(did);
             match err {
                 ValTreeCreationError::NodesOverflow => {
                     let handled =
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 8f286971e63..d077900587e 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -8,8 +8,9 @@
 
 use std::assert_matches::assert_matches;
 use std::borrow::{Borrow, Cow};
+use std::cell::Cell;
 use std::collections::VecDeque;
-use std::{fmt, mem, ptr};
+use std::{fmt, ptr};
 
 use rustc_abi::{Align, HasDataLayout, Size};
 use rustc_ast::Mutability;
@@ -131,7 +132,7 @@ pub struct Memory<'tcx, M: Machine<'tcx>> {
     /// This stores whether we are currently doing reads purely for the purpose of validation.
     /// Those reads do not trigger the machine's hooks for memory reads.
     /// Needless to say, this must only be set with great care!
-    validation_in_progress: bool,
+    validation_in_progress: Cell<bool>,
 }
 
 /// A reference to some allocation that was already bounds-checked for the given region
@@ -158,7 +159,7 @@ impl<'tcx, M: Machine<'tcx>> Memory<'tcx, M> {
             alloc_map: M::MemoryMap::default(),
             extra_fn_ptr_map: FxIndexMap::default(),
             dead_alloc_map: FxIndexMap::default(),
-            validation_in_progress: false,
+            validation_in_progress: Cell::new(false),
         }
     }
 
@@ -715,7 +716,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         // We want to call the hook on *all* accesses that involve an AllocId, including zero-sized
         // accesses. That means we cannot rely on the closure above or the `Some` branch below. We
         // do this after `check_and_deref_ptr` to ensure some basic sanity has already been checked.
-        if !self.memory.validation_in_progress {
+        if !self.memory.validation_in_progress.get() {
             if let Ok((alloc_id, ..)) = self.ptr_try_get_alloc_id(ptr, size_i64) {
                 M::before_alloc_read(self, alloc_id)?;
             }
@@ -723,7 +724,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
         if let Some((alloc_id, offset, prov, alloc)) = ptr_and_alloc {
             let range = alloc_range(offset, size);
-            if !self.memory.validation_in_progress {
+            if !self.memory.validation_in_progress.get() {
                 M::before_memory_read(
                     self.tcx,
                     &self.machine,
@@ -801,7 +802,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     ) -> InterpResult<'tcx, Option<AllocRefMut<'a, 'tcx, M::Provenance, M::AllocExtra, M::Bytes>>>
     {
         let tcx = self.tcx;
-        let validation_in_progress = self.memory.validation_in_progress;
+        let validation_in_progress = self.memory.validation_in_progress.get();
 
         let size_i64 = i64::try_from(size.bytes()).unwrap(); // it would be an error to even ask for more than isize::MAX bytes
         let ptr_and_alloc = Self::check_and_deref_ptr(
@@ -1087,23 +1088,43 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     ///
     /// We do this so Miri's allocation access tracking does not show the validation
     /// reads as spurious accesses.
-    pub fn run_for_validation<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
+    pub fn run_for_validation_mut<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
         // This deliberately uses `==` on `bool` to follow the pattern
         // `assert!(val.replace(new) == old)`.
         assert!(
-            mem::replace(&mut self.memory.validation_in_progress, true) == false,
+            self.memory.validation_in_progress.replace(true) == false,
             "`validation_in_progress` was already set"
         );
         let res = f(self);
         assert!(
-            mem::replace(&mut self.memory.validation_in_progress, false) == true,
+            self.memory.validation_in_progress.replace(false) == true,
+            "`validation_in_progress` was unset by someone else"
+        );
+        res
+    }
+
+    /// Runs the closure in "validation" mode, which means the machine's memory read hooks will be
+    /// suppressed. Needless to say, this must only be set with great care! Cannot be nested.
+    ///
+    /// We do this so Miri's allocation access tracking does not show the validation
+    /// reads as spurious accesses.
+    pub fn run_for_validation_ref<R>(&self, f: impl FnOnce(&Self) -> R) -> R {
+        // This deliberately uses `==` on `bool` to follow the pattern
+        // `assert!(val.replace(new) == old)`.
+        assert!(
+            self.memory.validation_in_progress.replace(true) == false,
+            "`validation_in_progress` was already set"
+        );
+        let res = f(self);
+        assert!(
+            self.memory.validation_in_progress.replace(false) == true,
             "`validation_in_progress` was unset by someone else"
         );
         res
     }
 
     pub(super) fn validation_in_progress(&self) -> bool {
-        self.memory.validation_in_progress
+        self.memory.validation_in_progress.get()
     }
 }
 
@@ -1375,7 +1396,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         };
         let src_alloc = self.get_alloc_raw(src_alloc_id)?;
         let src_range = alloc_range(src_offset, size);
-        assert!(!self.memory.validation_in_progress, "we can't be copying during validation");
+        assert!(!self.memory.validation_in_progress.get(), "we can't be copying during validation");
         // For the overlapping case, it is crucial that we trigger the read hook
         // before the write hook -- the aliasing model cares about the order.
         M::before_memory_read(
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index eb3f552cd27..fb7ba6d7ef5 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -1322,7 +1322,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         trace!("validate_operand_internal: {:?}, {:?}", *val, val.layout.ty);
 
         // Run the visitor.
-        self.run_for_validation(|ecx| {
+        self.run_for_validation_mut(|ecx| {
             let reset_padding = reset_provenance_and_padding && {
                 // Check if `val` is actually stored in memory. If not, padding is not even
                 // represented and we need not reset it.
diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs
index 80e72250470..f0db9623b67 100644
--- a/compiler/rustc_data_structures/src/fx.rs
+++ b/compiler/rustc_data_structures/src/fx.rs
@@ -9,6 +9,8 @@ pub type FxIndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
 pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>;
 pub type IndexOccupiedEntry<'a, K, V> = indexmap::map::OccupiedEntry<'a, K, V>;
 
+pub use indexmap::set::MutableValues;
+
 #[macro_export]
 macro_rules! define_id_collections {
     ($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 37755e7d61d..595ac1edd28 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -34,7 +34,6 @@ use std::time::{Instant, SystemTime};
 use std::{env, str};
 
 use rustc_ast as ast;
-use rustc_codegen_ssa::back::apple;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::{CodegenErrors, CodegenResults};
 use rustc_data_structures::profiling::{
@@ -64,6 +63,7 @@ use rustc_session::lint::{Lint, LintId};
 use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target};
 use rustc_session::{EarlyDiagCtxt, Session, config, filesearch};
 use rustc_span::FileName;
+use rustc_span::def_id::LOCAL_CRATE;
 use rustc_target::json::ToJson;
 use rustc_target::spec::{Target, TargetTuple};
 use time::OffsetDateTime;
@@ -392,14 +392,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
 }
 
 fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &Path) {
-    let output_filenames = tcxt.output_filenames(());
-    let mut metrics_file_name = std::ffi::OsString::from("unstable_feature_usage_metrics-");
-    let mut metrics_path = output_filenames.with_directory_and_extension(metrics_dir, "json");
-    let metrics_file_stem =
-        metrics_path.file_name().expect("there should be a valid default output filename");
-    metrics_file_name.push(metrics_file_stem);
-    metrics_path.pop();
-    metrics_path.push(metrics_file_name);
+    let hash = tcxt.crate_hash(LOCAL_CRATE);
+    let crate_name = tcxt.crate_name(LOCAL_CRATE);
+    let metrics_file_name = format!("unstable_feature_usage_metrics-{crate_name}-{hash}.json");
+    let metrics_path = metrics_dir.join(metrics_file_name);
     if let Err(error) = tcxt.features().dump_feature_usage_metrics(metrics_path) {
         // FIXME(yaahc): once metrics can be enabled by default we will want "failure to emit
         // default metrics" to only produce a warning when metrics are enabled by default and emit
@@ -691,6 +687,34 @@ fn print_crate_info(
                 };
                 println_info!("{}", passes::get_crate_name(sess, attrs));
             }
+            CrateRootLintLevels => {
+                let Some(attrs) = attrs.as_ref() else {
+                    // no crate attributes, print out an error and exit
+                    return Compilation::Continue;
+                };
+                let crate_name = passes::get_crate_name(sess, attrs);
+                let lint_store = crate::unerased_lint_store(sess);
+                let registered_tools = rustc_resolve::registered_tools_ast(sess.dcx(), attrs);
+                let features = rustc_expand::config::features(sess, attrs, crate_name);
+                let lint_levels = rustc_lint::LintLevelsBuilder::crate_root(
+                    sess,
+                    &features,
+                    true,
+                    lint_store,
+                    &registered_tools,
+                    attrs,
+                );
+                for lint in lint_store.get_lints() {
+                    if let Some(feature_symbol) = lint.feature_gate
+                        && !features.enabled(feature_symbol)
+                    {
+                        // lint is unstable and feature gate isn't active, don't print
+                        continue;
+                    }
+                    let level = lint_levels.lint_level(lint).level;
+                    println_info!("{}={}", lint.name_lower(), level.as_str());
+                }
+            }
             Cfg => {
                 let mut cfgs = sess
                     .psess
@@ -779,11 +803,11 @@ fn print_crate_info(
                 }
             }
             DeploymentTarget => {
-                if sess.target.is_like_osx {
+                if sess.target.is_like_darwin {
                     println_info!(
                         "{}={}",
-                        apple::deployment_target_env_var(&sess.target.os),
-                        apple::pretty_version(apple::deployment_target(sess)),
+                        rustc_target::spec::apple::deployment_target_env_var(&sess.target.os),
+                        sess.apple_deployment_target().fmt_pretty(),
                     )
                 } else {
                     #[allow(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index f0636b600b7..f3aeb8d224b 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -91,13 +91,13 @@ fn annotation_level_for_level(level: Level) -> annotate_snippets::Level {
         Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => {
             annotate_snippets::Level::Error
         }
-        Level::ForceWarning(_) | Level::Warning => annotate_snippets::Level::Warning,
+        Level::ForceWarning | Level::Warning => annotate_snippets::Level::Warning,
         Level::Note | Level::OnceNote => annotate_snippets::Level::Note,
         Level::Help | Level::OnceHelp => annotate_snippets::Level::Help,
         // FIXME(#59346): Not sure how to map this level
         Level::FailureNote => annotate_snippets::Level::Error,
         Level::Allow => panic!("Should not call with Allow"),
-        Level::Expect(_) => panic!("Should not call with Expect"),
+        Level::Expect => panic!("Should not call with Expect"),
     }
 }
 
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 9f4d2ea5c1a..794502d7aae 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -9,7 +9,7 @@ use std::thread::panicking;
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_error_messages::{FluentValue, fluent_value_from_str_list_sep_by_and};
-use rustc_lint_defs::Applicability;
+use rustc_lint_defs::{Applicability, LintExpectationId};
 use rustc_macros::{Decodable, Encodable};
 use rustc_span::source_map::Spanned;
 use rustc_span::{DUMMY_SP, Span, Symbol};
@@ -296,6 +296,7 @@ pub struct DiagInner {
 
     pub messages: Vec<(DiagMessage, Style)>,
     pub code: Option<ErrCode>,
+    pub lint_id: Option<LintExpectationId>,
     pub span: MultiSpan,
     pub children: Vec<Subdiag>,
     pub suggestions: Suggestions,
@@ -324,6 +325,7 @@ impl DiagInner {
     pub fn new_with_messages(level: Level, messages: Vec<(DiagMessage, Style)>) -> Self {
         DiagInner {
             level,
+            lint_id: None,
             messages,
             code: None,
             span: MultiSpan::new(),
@@ -346,7 +348,7 @@ impl DiagInner {
         match self.level {
             Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true,
 
-            Level::ForceWarning(_)
+            Level::ForceWarning
             | Level::Warning
             | Level::Note
             | Level::OnceNote
@@ -354,7 +356,7 @@ impl DiagInner {
             | Level::OnceHelp
             | Level::FailureNote
             | Level::Allow
-            | Level::Expect(_) => false,
+            | Level::Expect => false,
         }
     }
 
@@ -365,7 +367,7 @@ impl DiagInner {
 
     pub(crate) fn is_force_warn(&self) -> bool {
         match self.level {
-            Level::ForceWarning(_) => {
+            Level::ForceWarning => {
                 assert!(self.is_lint.is_some());
                 true
             }
@@ -1259,6 +1261,17 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
         self
     } }
 
+    with_fn! { with_lint_id,
+    /// Add an argument.
+    #[rustc_lint_diagnostics]
+    pub fn lint_id(
+        &mut self,
+        id: LintExpectationId,
+    ) -> &mut Self {
+        self.lint_id = Some(id);
+        self
+    } }
+
     with_fn! { with_primary_message,
     /// Add a primary message.
     #[rustc_lint_diagnostics]
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 7d7f364fec2..a6583407b7e 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -144,7 +144,7 @@ impl Emitter for JsonEmitter {
                 //
                 // So to avoid ICEs and confused users we "upgrade" the lint level for
                 // those `FutureBreakageItem` to warn.
-                if matches!(diag.level, crate::Level::Allow | crate::Level::Expect(..)) {
+                if matches!(diag.level, crate::Level::Allow | crate::Level::Expect) {
                     diag.level = crate::Level::Warning;
                 }
                 FutureBreakageItem {
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 80e43ede445..f5f7618285e 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -905,8 +905,8 @@ impl<'a> DiagCtxtHandle<'a> {
             DelayedBug => {
                 return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
             }
-            ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
-            | Expect(_) => None,
+            ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
+            | Expect => None,
         };
 
         // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
@@ -1045,7 +1045,7 @@ impl<'a> DiagCtxtHandle<'a> {
                 // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
                 // configuration like `--cap-lints allow --force-warn bare_trait_objects`.
                 inner.emit_diagnostic(
-                    DiagInner::new(ForceWarning(None), DiagMessage::Str(warnings)),
+                    DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
                     None,
                 );
             }
@@ -1450,7 +1450,7 @@ impl<'a> DiagCtxtHandle<'a> {
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
-        Diag::new(self, Expect(id), msg)
+        Diag::new(self, Expect, msg).with_lint_id(id)
     }
 }
 
@@ -1510,7 +1510,7 @@ impl DiagCtxtInner {
             // Future breakages aren't emitted if they're `Level::Allow` or
             // `Level::Expect`, but they still need to be constructed and
             // stashed below, so they'll trigger the must_produce_diag check.
-            assert_matches!(diagnostic.level, Error | Warning | Allow | Expect(_));
+            assert_matches!(diagnostic.level, Error | Warning | Allow | Expect);
             self.future_breakage_diagnostics.push(diagnostic.clone());
         }
 
@@ -1558,7 +1558,7 @@ impl DiagCtxtInner {
                     };
                 }
             }
-            ForceWarning(None) => {} // `ForceWarning(Some(...))` is below, with `Expect`
+            ForceWarning if diagnostic.lint_id.is_none() => {} // `ForceWarning(Some(...))` is below, with `Expect`
             Warning => {
                 if !self.flags.can_emit_warnings {
                     // We are not emitting warnings.
@@ -1580,9 +1580,9 @@ impl DiagCtxtInner {
                 }
                 return None;
             }
-            Expect(expect_id) | ForceWarning(Some(expect_id)) => {
-                self.fulfilled_expectations.insert(expect_id);
-                if let Expect(_) = diagnostic.level {
+            Expect | ForceWarning => {
+                self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
+                if let Expect = diagnostic.level {
                     // Nothing emitted here for expected lints.
                     TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
                     self.suppressed_expected_diag = true;
@@ -1631,7 +1631,7 @@ impl DiagCtxtInner {
 
                 if is_error {
                     self.deduplicated_err_count += 1;
-                } else if matches!(diagnostic.level, ForceWarning(_) | Warning) {
+                } else if matches!(diagnostic.level, ForceWarning | Warning) {
                     self.deduplicated_warn_count += 1;
                 }
                 self.has_printed = true;
@@ -1899,9 +1899,9 @@ pub enum Level {
     /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
     /// from finishing.
     ///
-    /// The [`LintExpectationId`] is used for expected lint diagnostics. In all other cases this
+    /// Requires a [`LintExpectationId`] for expected lint diagnostics. In all other cases this
     /// should be `None`.
-    ForceWarning(Option<LintExpectationId>),
+    ForceWarning,
 
     /// A warning about the code being compiled. Does not prevent compilation from finishing.
     /// Will be skipped if `can_emit_warnings` is false.
@@ -1926,8 +1926,8 @@ pub enum Level {
     /// Only used for lints.
     Allow,
 
-    /// Only used for lints.
-    Expect(LintExpectationId),
+    /// Only used for lints. Requires a [`LintExpectationId`] for silencing the lints.
+    Expect,
 }
 
 impl fmt::Display for Level {
@@ -1943,7 +1943,7 @@ impl Level {
             Bug | Fatal | Error | DelayedBug => {
                 spec.set_fg(Some(Color::Red)).set_intense(true);
             }
-            ForceWarning(_) | Warning => {
+            ForceWarning | Warning => {
                 spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows));
             }
             Note | OnceNote => {
@@ -1953,7 +1953,7 @@ impl Level {
                 spec.set_fg(Some(Color::Cyan)).set_intense(true);
             }
             FailureNote => {}
-            Allow | Expect(_) => unreachable!(),
+            Allow | Expect => unreachable!(),
         }
         spec
     }
@@ -1962,11 +1962,11 @@ impl Level {
         match self {
             Bug | DelayedBug => "error: internal compiler error",
             Fatal | Error => "error",
-            ForceWarning(_) | Warning => "warning",
+            ForceWarning | Warning => "warning",
             Note | OnceNote => "note",
             Help | OnceHelp => "help",
             FailureNote => "failure-note",
-            Allow | Expect(_) => unreachable!(),
+            Allow | Expect => unreachable!(),
         }
     }
 
@@ -1977,8 +1977,7 @@ impl Level {
     // Can this level be used in a subdiagnostic message?
     fn can_be_subdiag(&self) -> bool {
         match self {
-            Bug | DelayedBug | Fatal | Error | ForceWarning(_) | FailureNote | Allow
-            | Expect(_) => false,
+            Bug | DelayedBug | Fatal | Error | ForceWarning | FailureNote | Allow | Expect => false,
 
             Warning | Note | Help | OnceNote | OnceHelp => true,
         }
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 990d0f2e028..d14e476ba32 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1424,12 +1424,11 @@ pub fn parse_macro_name_and_helper_attrs(
 /// See #73345 and #83125 for more details.
 /// FIXME(#73933): Remove this eventually.
 fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) {
-    let name = item.ident.name;
-    if name == sym::ProceduralMasqueradeDummyType
-        && let ast::ItemKind::Enum(enum_def, _) = &item.kind
+    if let ast::ItemKind::Enum(ident, enum_def, _) = &item.kind
+        && ident.name == sym::ProceduralMasqueradeDummyType
         && let [variant] = &*enum_def.variants
         && variant.ident.name == sym::Input
-        && let FileName::Real(real) = psess.source_map().span_to_filename(item.ident.span)
+        && let FileName::Real(real) = psess.source_map().span_to_filename(ident.span)
         && let Some(c) = real
             .local_path()
             .unwrap_or(Path::new(""))
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 89a750bb39f..f68172c1f67 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -662,15 +662,8 @@ impl<'a> ExtCtxt<'a> {
         P(ast::FnDecl { inputs, output })
     }
 
-    pub fn item(
-        &self,
-        span: Span,
-        name: Ident,
-        attrs: ast::AttrVec,
-        kind: ast::ItemKind,
-    ) -> P<ast::Item> {
+    pub fn item(&self, span: Span, attrs: ast::AttrVec, kind: ast::ItemKind) -> P<ast::Item> {
         P(ast::Item {
-            ident: name,
             attrs,
             id: ast::DUMMY_NODE_ID,
             kind,
@@ -687,17 +680,17 @@ impl<'a> ExtCtxt<'a> {
     pub fn item_static(
         &self,
         span: Span,
-        name: Ident,
+        ident: Ident,
         ty: P<ast::Ty>,
         mutability: ast::Mutability,
         expr: P<ast::Expr>,
     ) -> P<ast::Item> {
         self.item(
             span,
-            name,
             AttrVec::new(),
             ast::ItemKind::Static(
                 ast::StaticItem {
+                    ident,
                     ty,
                     safety: ast::Safety::Default,
                     mutability,
@@ -712,18 +705,18 @@ impl<'a> ExtCtxt<'a> {
     pub fn item_const(
         &self,
         span: Span,
-        name: Ident,
+        ident: Ident,
         ty: P<ast::Ty>,
         expr: P<ast::Expr>,
     ) -> P<ast::Item> {
         let defaultness = ast::Defaultness::Final;
         self.item(
             span,
-            name,
             AttrVec::new(),
             ast::ItemKind::Const(
                 ast::ConstItem {
                     defaultness,
+                    ident,
                     // FIXME(generic_const_items): Pass the generics as a parameter.
                     generics: ast::Generics::default(),
                     ty,
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 22da1179feb..bca846d2ec4 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -744,6 +744,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                                     item_inner.kind,
                                     ItemKind::Mod(
                                         _,
+                                        _,
                                         ModKind::Unloaded | ModKind::Loaded(_, Inline::No, _, _),
                                     )
                                 ) =>
@@ -911,7 +912,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
             fn visit_item(&mut self, item: &'ast ast::Item) {
                 match &item.kind {
-                    ItemKind::Mod(_, mod_kind)
+                    ItemKind::Mod(_, _, mod_kind)
                         if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _)) =>
                     {
                         feature_err(
@@ -1221,9 +1222,8 @@ impl InvocationCollectorNode for P<ast::Item> {
         }
 
         // Work around borrow checker not seeing through `P`'s deref.
-        let (ident, span, mut attrs) = (node.ident, node.span, mem::take(&mut node.attrs));
-        let ItemKind::Mod(_, mod_kind) = &mut node.kind else { unreachable!() };
-
+        let (span, mut attrs) = (node.span, mem::take(&mut node.attrs));
+        let ItemKind::Mod(_, ident, ref mut mod_kind) = node.kind else { unreachable!() };
         let ecx = &mut collector.cx;
         let (file_path, dir_path, dir_ownership) = match mod_kind {
             ModKind::Loaded(_, inline, _, _) => {
@@ -1305,6 +1305,7 @@ impl InvocationCollectorNode for P<ast::Item> {
         collector.cx.current_expansion.module = orig_module;
         res
     }
+
     fn declared_names(&self) -> Vec<Ident> {
         if let ItemKind::Use(ut) = &self.kind {
             fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
@@ -1324,7 +1325,7 @@ impl InvocationCollectorNode for P<ast::Item> {
             return idents;
         }
 
-        vec![self.ident]
+        if let Some(ident) = self.kind.ident() { vec![ident] } else { vec![] }
     }
 }
 
@@ -1844,11 +1845,11 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>(
             id: ast::DUMMY_NODE_ID,
             span: if from_glob { item_span } else { ident.span },
             vis: item.vis.clone(),
-            ident: rename.unwrap_or(ident),
             kind: Node::delegation_item_kind(Box::new(ast::Delegation {
                 id: ast::DUMMY_NODE_ID,
                 qself: deleg.qself.clone(),
                 path,
+                ident: rename.unwrap_or(ident),
                 rename,
                 body: deleg.body.clone(),
                 from_glob,
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index cffa4af6ac3..6e47ed6eb67 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -3,11 +3,10 @@ use std::sync::Arc;
 
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::token::{
-    self, Delimiter, IdentIsRaw, InvisibleOrigin, Lit, LitKind, MetaVarKind, Nonterminal, Token,
-    TokenKind,
+    self, Delimiter, IdentIsRaw, InvisibleOrigin, Lit, LitKind, MetaVarKind, Token, TokenKind,
 };
 use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
-use rustc_ast::{ExprKind, StmtKind, TyKind};
+use rustc_ast::{ExprKind, StmtKind, TyKind, UnOp};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
 use rustc_parse::lexer::nfc_normalize;
@@ -340,6 +339,30 @@ pub(super) fn transcribe<'a>(
                             MetaVarKind::Pat(*pat_kind),
                             TokenStream::from_ast(pat),
                         ),
+                        MatchedSingle(ParseNtResult::Expr(expr, kind)) => {
+                            let (can_begin_literal_maybe_minus, can_begin_string_literal) =
+                                match &expr.kind {
+                                    ExprKind::Lit(_) => (true, true),
+                                    ExprKind::Unary(UnOp::Neg, e)
+                                        if matches!(&e.kind, ExprKind::Lit(_)) =>
+                                    {
+                                        (true, false)
+                                    }
+                                    _ => (false, false),
+                                };
+                            mk_delimited(
+                                expr.span,
+                                MetaVarKind::Expr {
+                                    kind: *kind,
+                                    can_begin_literal_maybe_minus,
+                                    can_begin_string_literal,
+                                },
+                                TokenStream::from_ast(expr),
+                            )
+                        }
+                        MatchedSingle(ParseNtResult::Literal(lit)) => {
+                            mk_delimited(lit.span, MetaVarKind::Literal, TokenStream::from_ast(lit))
+                        }
                         MatchedSingle(ParseNtResult::Ty(ty)) => {
                             let is_path = matches!(&ty.kind, TyKind::Path(None, _path));
                             mk_delimited(
@@ -869,10 +892,8 @@ fn extract_symbol_from_pnr<'a>(
             },
             _,
         )) => Ok(*symbol),
-        ParseNtResult::Nt(nt)
-            if let Nonterminal::NtLiteral(expr) = &**nt
-                && let ExprKind::Lit(Lit { kind: LitKind::Str, symbol, suffix: None }) =
-                    &expr.kind =>
+        ParseNtResult::Literal(expr)
+            if let ExprKind::Lit(Lit { kind: LitKind::Str, symbol, suffix: None }) = &expr.kind =>
         {
             Ok(*symbol)
         }
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index a60a87244cc..0136292decb 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -26,7 +26,7 @@ pub(crate) fn placeholder(
         })
     }
 
-    let ident = Ident::empty();
+    let ident = Ident::dummy();
     let attrs = ast::AttrVec::new();
     let vis = vis.unwrap_or(ast::Visibility {
         span: DUMMY_SP,
@@ -62,7 +62,6 @@ pub(crate) fn placeholder(
         AstFragmentKind::Items => AstFragment::Items(smallvec![P(ast::Item {
             id,
             span,
-            ident,
             vis,
             attrs,
             kind: ast::ItemKind::MacCall(mac_placeholder()),
@@ -71,7 +70,6 @@ pub(crate) fn placeholder(
         AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![P(ast::AssocItem {
             id,
             span,
-            ident,
             vis,
             attrs,
             kind: ast::AssocItemKind::MacCall(mac_placeholder()),
@@ -80,7 +78,6 @@ pub(crate) fn placeholder(
         AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![P(ast::AssocItem {
             id,
             span,
-            ident,
             vis,
             attrs,
             kind: ast::AssocItemKind::MacCall(mac_placeholder()),
@@ -90,7 +87,6 @@ pub(crate) fn placeholder(
             AstFragment::TraitImplItems(smallvec![P(ast::AssocItem {
                 id,
                 span,
-                ident,
                 vis,
                 attrs,
                 kind: ast::AssocItemKind::MacCall(mac_placeholder()),
@@ -101,7 +97,6 @@ pub(crate) fn placeholder(
             AstFragment::ForeignItems(smallvec![P(ast::ForeignItem {
                 id,
                 span,
-                ident,
                 vis,
                 attrs,
                 kind: ast::ForeignItemKind::MacCall(mac_placeholder()),
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 6fe65c88f71..1e33e2e9393 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -1087,9 +1087,9 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         WarnFollowing, EncodeCrossCrate::No
     ),
     rustc_attr!(
-        TEST, rustc_error, Normal,
-        template!(Word, List: "delayed_bug_from_inside_query"),
-        WarnFollowingWordOnly, EncodeCrossCrate::Yes
+        TEST, rustc_delayed_bug_from_inside_query, Normal,
+        template!(Word),
+        WarnFollowing, EncodeCrossCrate::No
     ),
     rustc_attr!(
         TEST, rustc_dump_user_args, Normal, template!(Word),
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 47e4f9a2fe8..6ba7b22a0df 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -142,6 +142,9 @@ declare_features! (
     /// Allows inferring `'static` outlives requirements (RFC 2093).
     (removed, infer_static_outlives_requirements, "1.63.0", Some(54185),
      Some("removed as it caused some confusion and discussion was inactive for years")),
+    /// Allow anonymous constants from an inline `const` block in pattern position
+    (removed, inline_const_pat, "CURRENT_RUSTC_VERSION", Some(76001),
+     Some("removed due to implementation concerns as it requires significant refactorings")),
     /// Lazily evaluate constants. This allows constants to depend on type parameters.
     (removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")),
     /// Changes `impl Trait` to capture all lifetimes in scope.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 72468dd4714..710e129b609 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -324,6 +324,7 @@ declare_features! (
     (unstable, loongarch_target_feature, "1.73.0", Some(44839)),
     (unstable, m68k_target_feature, "1.85.0", Some(134328)),
     (unstable, mips_target_feature, "1.27.0", Some(44839)),
+    (unstable, movrs_target_feature, "CURRENT_RUSTC_VERSION", Some(137976)),
     (unstable, powerpc_target_feature, "1.27.0", Some(44839)),
     (unstable, prfchw_target_feature, "1.78.0", Some(44839)),
     (unstable, riscv_target_feature, "1.45.0", Some(44839)),
@@ -531,8 +532,6 @@ declare_features! (
     (unstable, import_trait_associated_functions, "1.86.0", Some(134691)),
     /// Allows associated types in inherent impls.
     (incomplete, inherent_associated_types, "1.52.0", Some(8995)),
-    /// Allow anonymous constants from an inline `const` block in pattern position
-    (unstable, inline_const_pat, "1.58.0", Some(76001)),
     /// Allows using `pointer` and `reference` in intra-doc links
     (unstable, intra_doc_pointers, "1.51.0", Some(80896)),
     // Allows using the `kl` and `widekl` target features and the associated intrinsics
@@ -630,6 +629,8 @@ declare_features! (
     (unstable, strict_provenance_lints, "1.61.0", Some(130351)),
     /// Allows string patterns to dereference values to match them.
     (unstable, string_deref_patterns, "1.67.0", Some(87121)),
+    /// Allows `super let` statements.
+    (incomplete, super_let, "CURRENT_RUSTC_VERSION", Some(139076)),
     /// Allows subtrait items to shadow supertrait items.
     (unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
     /// Allows using `#[thread_local]` on `static` items.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 5f8941d4754..dc00b52a593 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -294,7 +294,7 @@ impl DefKind {
             DefKind::GlobalAsm => DefPathData::GlobalAsm,
             DefKind::Impl { .. } => DefPathData::Impl,
             DefKind::Closure => DefPathData::Closure,
-            DefKind::SyntheticCoroutineBody => DefPathData::Closure,
+            DefKind::SyntheticCoroutineBody => DefPathData::SyntheticCoroutineBody,
         }
     }
 
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 61f5efd9978..c52954aa96f 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -291,6 +291,8 @@ pub enum DefPathData {
     /// An existential `impl Trait` type node.
     /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name.
     OpaqueTy,
+    /// A synthetic body for a coroutine's by-move body.
+    SyntheticCoroutineBody,
 }
 
 impl Definitions {
@@ -415,8 +417,16 @@ impl DefPathData {
 
             ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
 
-            Impl | ForeignMod | CrateRoot | Use | GlobalAsm | Closure | Ctor | AnonConst
-            | OpaqueTy => None,
+            Impl
+            | ForeignMod
+            | CrateRoot
+            | Use
+            | GlobalAsm
+            | Closure
+            | Ctor
+            | AnonConst
+            | OpaqueTy
+            | SyntheticCoroutineBody => None,
         }
     }
 
@@ -441,6 +451,7 @@ impl DefPathData {
             Ctor => DefPathDataName::Anon { namespace: sym::constructor },
             AnonConst => DefPathDataName::Anon { namespace: sym::constant },
             OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque },
+            SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic },
         }
     }
 }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e3e96894ed1..1a6c15b66a4 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -10,9 +10,9 @@ use rustc_ast::{
     LitKind, TraitObjectSyntax, UintTy, UnsafeBinderCastKind,
 };
 pub use rustc_ast::{
-    AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity,
-    ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto, MetaItemInner, MetaItemLit, Movability,
-    Mutability, UnOp,
+    AssignOp, AssignOpKind, AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind,
+    BoundConstness, BoundPolarity, ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto,
+    MetaItemInner, MetaItemLit, Movability, Mutability, UnOp,
 };
 use rustc_attr_data_structures::AttributeKind;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -2123,7 +2123,7 @@ pub type Lit = Spanned<LitKind>;
 /// explicit discriminant values for enum variants.
 ///
 /// You can check if this anon const is a default in a const param
-/// `const N: usize = { ... }` with `tcx.hir().opt_const_param_default_param_def_id(..)`
+/// `const N: usize = { ... }` with `tcx.hir_opt_const_param_default_param_def_id(..)`
 #[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub struct AnonConst {
     #[stable_hasher(ignore)]
@@ -2648,7 +2648,7 @@ pub enum ExprKind<'hir> {
     /// An assignment with an operator.
     ///
     /// E.g., `a += 1`.
-    AssignOp(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
+    AssignOp(AssignOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
     /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
     Field(&'hir Expr<'hir>, Ident),
     /// An indexing operation (`foo[2]`).
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index 3fa06620ea8..b48a081d371 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -83,6 +83,12 @@ pub struct HirId {
     pub local_id: ItemLocalId,
 }
 
+// To ensure correctness of incremental compilation,
+// `HirId` must not implement `Ord` or `PartialOrd`.
+// See https://github.com/rust-lang/rust/issues/90317.
+impl !Ord for HirId {}
+impl !PartialOrd for HirId {}
+
 impl Debug for HirId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // Example: HirId(DefId(0:1 ~ aa[7697]::{use#0}).10)
@@ -116,10 +122,6 @@ impl HirId {
     pub fn make_owner(owner: LocalDefId) -> Self {
         Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO }
     }
-
-    pub fn index(self) -> (usize, usize) {
-        (rustc_index::Idx::index(self.owner.def_id), rustc_index::Idx::index(self.local_id))
-    }
 }
 
 impl fmt::Display for HirId {
@@ -128,18 +130,6 @@ impl fmt::Display for HirId {
     }
 }
 
-impl Ord for HirId {
-    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
-        (self.index()).cmp(&(other.index()))
-    }
-}
-
-impl PartialOrd for HirId {
-    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
 rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId);
 rustc_data_structures::define_id_collections!(
     ItemLocalMap,
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index e625514e9ff..90fab01ba2d 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -433,6 +433,12 @@ language_item_table! {
     // Experimental lang items for implementing contract pre- and post-condition checking.
     ContractBuildCheckEnsures, sym::contract_build_check_ensures, contract_build_check_ensures_fn, Target::Fn, GenericRequirement::None;
     ContractCheckRequires,     sym::contract_check_requires,      contract_check_requires_fn,      Target::Fn, GenericRequirement::None;
+
+    // Experimental lang items for `MCP: Low level components for async drop`(https://github.com/rust-lang/compiler-team/issues/727)
+    DefaultTrait4,           sym::default_trait4,      default_trait4_trait,       Target::Trait,          GenericRequirement::None;
+    DefaultTrait3,           sym::default_trait3,      default_trait3_trait,       Target::Trait,          GenericRequirement::None;
+    DefaultTrait2,           sym::default_trait2,      default_trait2_trait,       Target::Trait,          GenericRequirement::None;
+    DefaultTrait1,           sym::default_trait1,      default_trait1_trait,       Target::Trait,          GenericRequirement::None;
 }
 
 /// The requirement imposed on the generics of a lang item
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 4a839d40571..6bc0f797cca 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -11,6 +11,7 @@
 #![feature(debug_closure_helpers)]
 #![feature(exhaustive_patterns)]
 #![feature(let_chains)]
+#![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(variant_count)]
diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs
index 8a841a11556..58c3020f60e 100644
--- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs
+++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs
@@ -36,10 +36,8 @@ use crate::hir::def_id::{DefId, LocalDefId};
 ///    cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
 pub(crate) fn check_drop_impl(
     tcx: TyCtxt<'_>,
-    drop_impl_did: DefId,
+    drop_impl_did: LocalDefId,
 ) -> Result<(), ErrorGuaranteed> {
-    let drop_impl_did = drop_impl_did.expect_local();
-
     match tcx.impl_polarity(drop_impl_did) {
         ty::ImplPolarity::Positive => {}
         ty::ImplPolarity::Negative => {
@@ -56,9 +54,9 @@ pub(crate) fn check_drop_impl(
 
     tcx.ensure_ok().orphan_check_impl(drop_impl_did)?;
 
-    let dtor_impl_trait_ref = tcx.impl_trait_ref(drop_impl_did).unwrap().instantiate_identity();
+    let self_ty = tcx.type_of(drop_impl_did).instantiate_identity();
 
-    match dtor_impl_trait_ref.self_ty().kind() {
+    match self_ty.kind() {
         ty::Adt(adt_def, adt_to_impl_args) => {
             ensure_impl_params_and_item_params_correspond(
                 tcx,
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 07b5837bd87..a0798656763 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -578,10 +578,8 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
                 }
             }
             _ => {
-                tcx.dcx().span_delayed_bug(
-                    tcx.hir().span(hir_id),
-                    "parameter should have been resolved",
-                );
+                tcx.dcx()
+                    .span_delayed_bug(tcx.hir_span(hir_id), "parameter should have been resolved");
             }
         }
     }
@@ -1049,7 +1047,7 @@ fn check_impl_items_against_trait<'tcx>(
                 leaf_def.as_ref().is_some_and(|node_item| !node_item.defining_node.is_from_trait());
 
             if !is_implemented_here {
-                let full_impl_span = tcx.hir().span_with_body(tcx.local_def_id_to_hir_id(impl_id));
+                let full_impl_span = tcx.hir_span_with_body(tcx.local_def_id_to_hir_id(impl_id));
                 match tcx.eval_default_body_stability(trait_item_id, full_impl_span) {
                     EvalResult::Deny { feature, reason, issue, .. } => default_body_is_unstable(
                         tcx,
@@ -1105,7 +1103,7 @@ fn check_impl_items_against_trait<'tcx>(
         }
 
         if !missing_items.is_empty() {
-            let full_impl_span = tcx.hir().span_with_body(tcx.local_def_id_to_hir_id(impl_id));
+            let full_impl_span = tcx.hir_span_with_body(tcx.local_def_id_to_hir_id(impl_id));
             missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
         }
 
@@ -1321,7 +1319,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
         let typing_env = ty::TypingEnv::non_body_analysis(tcx, field.did);
         let layout = tcx.layout_of(typing_env.as_query_input(ty));
         // We are currently checking the type this field came from, so it must be local
-        let span = tcx.hir().span_if_local(field.did).unwrap();
+        let span = tcx.hir_span_if_local(field.did).unwrap();
         let trivial = layout.is_ok_and(|layout| layout.is_1zst());
         if !trivial {
             return (span, trivial, None);
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 84d07c711fa..5e68bb31001 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -12,7 +12,6 @@ use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisi
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::util::ExplicitSelf;
 use rustc_middle::ty::{
     self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
     TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast,
@@ -995,6 +994,26 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
     }
 }
 
+/// Gets the string for an explicit self declaration, e.g. "self", "&self",
+/// etc.
+fn get_self_string<'tcx, P>(self_arg_ty: Ty<'tcx>, is_self_ty: P) -> String
+where
+    P: Fn(Ty<'tcx>) -> bool,
+{
+    if is_self_ty(self_arg_ty) {
+        "self".to_owned()
+    } else if let ty::Ref(_, ty, mutbl) = self_arg_ty.kind()
+        && is_self_ty(*ty)
+    {
+        match mutbl {
+            hir::Mutability::Not => "&self".to_owned(),
+            hir::Mutability::Mut => "&mut self".to_owned(),
+        }
+    } else {
+        format!("self: {self_arg_ty}")
+    }
+}
+
 fn report_trait_method_mismatch<'tcx>(
     infcx: &InferCtxt<'tcx>,
     mut cause: ObligationCause<'tcx>,
@@ -1020,12 +1039,7 @@ fn report_trait_method_mismatch<'tcx>(
             if trait_m.fn_has_self_parameter =>
         {
             let ty = trait_sig.inputs()[0];
-            let sugg = match ExplicitSelf::determine(ty, |ty| ty == impl_trait_ref.self_ty()) {
-                ExplicitSelf::ByValue => "self".to_owned(),
-                ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
-                ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
-                _ => format!("self: {ty}"),
-            };
+            let sugg = get_self_string(ty, |ty| ty == impl_trait_ref.self_ty());
 
             // When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
             // span points only at the type `Box<Self`>, but we want to cover the whole
@@ -1208,7 +1222,7 @@ fn extract_spans_for_error_reporting<'tcx>(
         TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => {
             (impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
         }
-        _ => (cause.span, tcx.hir().span_if_local(trait_m.def_id)),
+        _ => (cause.span, tcx.hir_span_if_local(trait_m.def_id)),
     }
 }
 
@@ -1238,12 +1252,7 @@ fn compare_self_type<'tcx>(
             .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id));
         let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
         let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty);
-        match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
-            ExplicitSelf::ByValue => "self".to_owned(),
-            ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
-            ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
-            _ => format!("self: {self_arg_ty}"),
-        }
+        get_self_string(self_arg_ty, can_eq_self)
     };
 
     match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
@@ -1261,7 +1270,7 @@ fn compare_self_type<'tcx>(
                 self_descr
             );
             err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
-            if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
+            if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
                 err.span_label(span, format!("trait method declared without `{self_descr}`"));
             } else {
                 err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
@@ -1281,7 +1290,7 @@ fn compare_self_type<'tcx>(
                 self_descr
             );
             err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
-            if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
+            if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
                 err.span_label(span, format!("`{self_descr}` used in trait"));
             } else {
                 err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
@@ -1389,7 +1398,7 @@ fn compare_number_of_generics<'tcx>(
                     .collect();
                 (Some(arg_spans), impl_trait_spans)
             } else {
-                let trait_span = tcx.hir().span_if_local(trait_.def_id);
+                let trait_span = tcx.hir_span_if_local(trait_.def_id);
                 (trait_span.map(|s| vec![s]), vec![])
             };
 
@@ -1481,7 +1490,7 @@ fn compare_number_of_method_arguments<'tcx>(
                     }
                 })
             })
-            .or_else(|| tcx.hir().span_if_local(trait_m.def_id));
+            .or_else(|| tcx.hir_span_if_local(trait_m.def_id));
 
         let (impl_m_sig, _) = &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
         let pos = impl_number_args.saturating_sub(1);
@@ -2366,7 +2375,7 @@ fn try_report_async_mismatch<'tcx>(
             return Err(tcx.sess.dcx().emit_err(MethodShouldReturnFuture {
                 span: tcx.def_span(impl_m.def_id),
                 method_name: tcx.item_ident(impl_m.def_id),
-                trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
+                trait_item_span: tcx.hir_span_if_local(trait_m.def_id),
             }));
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index d63165f0f16..32a582aadc1 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -29,6 +29,7 @@ enum NonAsmTypeReason<'tcx> {
     Invalid(Ty<'tcx>),
     InvalidElement(DefId, Ty<'tcx>),
     NotSizedPtr(Ty<'tcx>),
+    EmptySIMDArray(Ty<'tcx>),
 }
 
 impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
@@ -102,6 +103,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             }
             ty::Adt(adt, args) if adt.repr().simd() => {
                 let fields = &adt.non_enum_variant().fields;
+                if fields.is_empty() {
+                    return Err(NonAsmTypeReason::EmptySIMDArray(ty));
+                }
                 let field = &fields[FieldIdx::ZERO];
                 let elem_ty = field.ty(self.tcx(), args);
 
@@ -226,6 +230,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                             can be used as arguments for inline assembly",
                         ).emit();
                     }
+                    NonAsmTypeReason::EmptySIMDArray(ty) => {
+                        let msg = format!("use of empty SIMD vector `{ty}`");
+                        self.infcx.dcx().struct_span_err(expr.span, msg).emit();
+                    }
                 }
                 return None;
             }
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index d8ae4214527..7c5d7b33a34 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -114,11 +114,11 @@ pub fn provide(providers: &mut Providers) {
 }
 
 fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor> {
-    tcx.calculate_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
+    tcx.calculate_dtor(def_id, always_applicable::check_drop_impl)
 }
 
 fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {
-    tcx.calculate_async_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
+    tcx.calculate_async_dtor(def_id, always_applicable::check_drop_impl)
 }
 
 /// Given a `DefId` for an opaque type in return position, find its parent item's return
@@ -243,7 +243,7 @@ fn missing_items_err(
             tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(),
         ));
         let code = format!("{padding}{snippet}\n{padding}");
-        if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
+        if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) {
             missing_trait_item_label
                 .push(errors::MissingTraitItemLabel { span, item: trait_item.name });
             missing_trait_item.push(errors::MissingTraitItemSuggestion {
@@ -341,9 +341,8 @@ fn bounds_from_generic_predicates<'tcx>(
             ty::ClauseKind::Trait(trait_predicate) => {
                 let entry = types.entry(trait_predicate.self_ty()).or_default();
                 let def_id = trait_predicate.def_id();
-                if Some(def_id) != tcx.lang_items().sized_trait() {
-                    // Type params are `Sized` by default, do not add that restriction to the list
-                    // if it is a positive requirement.
+                if !tcx.is_default_trait(def_id) {
+                    // Do not add that restriction to the list if it is a positive requirement.
                     entry.push(trait_predicate.def_id());
                 }
             }
@@ -534,7 +533,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d
     let variant_spans: Vec<_> = adt
         .variants()
         .iter()
-        .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
+        .map(|variant| tcx.hir_span_if_local(variant.def_id).unwrap())
         .collect();
     let (mut spans, mut many) = (Vec::new(), None);
     if let [start @ .., end] = &*variant_spans {
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index ba8124b11fc..cf66ab708bb 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -8,7 +8,6 @@
 
 use std::mem;
 
-use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, Visitor};
@@ -23,18 +22,11 @@ use tracing::debug;
 
 #[derive(Debug, Copy, Clone)]
 struct Context {
-    /// The scope that contains any new variables declared, plus its depth in
-    /// the scope tree.
+    /// The scope that contains any new variables declared.
     var_parent: Option<Scope>,
 
-    /// Region parent of expressions, etc., plus its depth in the scope tree.
-    parent: Option<(Scope, ScopeDepth)>,
-}
-
-impl Context {
-    fn set_var_parent(&mut self) {
-        self.var_parent = self.parent.map(|(p, _)| p);
-    }
+    /// Region parent of expressions, etc.
+    parent: Option<Scope>,
 }
 
 struct ScopeResolutionVisitor<'tcx> {
@@ -52,28 +44,6 @@ struct ScopeResolutionVisitor<'tcx> {
     scope_tree: ScopeTree,
 
     cx: Context,
-
-    /// `terminating_scopes` is a set containing the ids of each
-    /// statement, or conditional/repeating expression. These scopes
-    /// are calling "terminating scopes" because, when attempting to
-    /// find the scope of a temporary, by default we search up the
-    /// enclosing scopes until we encounter the terminating scope. A
-    /// conditional/repeating expression is one which is not
-    /// guaranteed to execute exactly once upon entering the parent
-    /// scope. This could be because the expression only executes
-    /// conditionally, such as the expression `b` in `a && b`, or
-    /// because the expression may execute many times, such as a loop
-    /// body. The reason that we distinguish such expressions is that,
-    /// upon exiting the parent scope, we cannot statically know how
-    /// many times the expression executed, and thus if the expression
-    /// creates temporaries we cannot know statically how many such
-    /// temporaries we would have to cleanup. Therefore, we ensure that
-    /// the temporaries never outlast the conditional/repeating
-    /// expression, preventing the need for dynamic checks and/or
-    /// arbitrary amounts of stack space. Terminating scopes end
-    /// up being contained in a DestructionScope that contains the
-    /// destructor's execution.
-    terminating_scopes: FxHashSet<hir::ItemLocalId>,
 }
 
 /// Records the lifetime of a local variable as `cx.var_parent`
@@ -88,7 +58,11 @@ fn record_var_lifetime(visitor: &mut ScopeResolutionVisitor<'_>, var_id: hir::It
     }
 }
 
-fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hir::Block<'tcx>) {
+fn resolve_block<'tcx>(
+    visitor: &mut ScopeResolutionVisitor<'tcx>,
+    blk: &'tcx hir::Block<'tcx>,
+    terminating: bool,
+) {
     debug!("resolve_block(blk.hir_id={:?})", blk.hir_id);
 
     let prev_cx = visitor.cx;
@@ -118,8 +92,8 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
     // `other_argument()` has run and also the call to `quux(..)`
     // itself has returned.
 
-    visitor.enter_node_scope_with_dtor(blk.hir_id.local_id);
-    visitor.cx.set_var_parent();
+    visitor.enter_node_scope_with_dtor(blk.hir_id.local_id, terminating);
+    visitor.cx.var_parent = visitor.cx.parent;
 
     {
         // This block should be kept approximately in sync with
@@ -138,7 +112,7 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
                         local_id: blk.hir_id.local_id,
                         data: ScopeData::Remainder(FirstStatementIndex::new(i)),
                     });
-                    visitor.cx.set_var_parent();
+                    visitor.cx.var_parent = visitor.cx.parent;
                     visitor.visit_stmt(statement);
                     // We need to back out temporarily to the last enclosing scope
                     // for the `else` block, so that even the temporaries receiving
@@ -147,8 +121,7 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
                     // the sequence of visits agree with the order in the default
                     // `hir::intravisit` visitor.
                     mem::swap(&mut prev_cx, &mut visitor.cx);
-                    visitor.terminating_scopes.insert(els.hir_id.local_id);
-                    visitor.visit_block(els);
+                    resolve_block(visitor, els, true);
                     // From now on, we continue normally.
                     visitor.cx = prev_cx;
                 }
@@ -163,7 +136,7 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
                         local_id: blk.hir_id.local_id,
                         data: ScopeData::Remainder(FirstStatementIndex::new(i)),
                     });
-                    visitor.cx.set_var_parent();
+                    visitor.cx.var_parent = visitor.cx.parent;
                     visitor.visit_stmt(statement)
                 }
                 hir::StmtKind::Item(..) => {
@@ -176,12 +149,12 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
         if let Some(tail_expr) = blk.expr {
             let local_id = tail_expr.hir_id.local_id;
             let edition = blk.span.edition();
-            if edition.at_least_rust_2024() {
-                visitor.terminating_scopes.insert(local_id);
-            } else if !visitor
-                .tcx
-                .lints_that_dont_need_to_run(())
-                .contains(&lint::LintId::of(lint::builtin::TAIL_EXPR_DROP_ORDER))
+            let terminating = edition.at_least_rust_2024();
+            if !terminating
+                && !visitor
+                    .tcx
+                    .lints_that_dont_need_to_run(())
+                    .contains(&lint::LintId::of(lint::builtin::TAIL_EXPR_DROP_ORDER))
             {
                 // If this temporary scope will be changing once the codebase adopts Rust 2024,
                 // and we are linting about possible semantic changes that would result,
@@ -192,7 +165,7 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
                     .backwards_incompatible_scope
                     .insert(local_id, Scope { local_id, data: ScopeData::Node });
             }
-            visitor.visit_expr(tail_expr);
+            resolve_expr(visitor, tail_expr, terminating);
         }
     }
 
@@ -210,18 +183,14 @@ fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir:
 
     let prev_cx = visitor.cx;
 
-    visitor.terminating_scopes.insert(arm.hir_id.local_id);
+    visitor.enter_node_scope_with_dtor(arm.hir_id.local_id, true);
+    visitor.cx.var_parent = visitor.cx.parent;
 
-    visitor.enter_node_scope_with_dtor(arm.hir_id.local_id);
-    visitor.cx.set_var_parent();
-
-    if let Some(expr) = arm.guard
-        && !has_let_expr(expr)
-    {
-        visitor.terminating_scopes.insert(expr.hir_id.local_id);
+    resolve_pat(visitor, arm.pat);
+    if let Some(guard) = arm.guard {
+        resolve_expr(visitor, guard, !has_let_expr(guard));
     }
-
-    intravisit::walk_arm(visitor, arm);
+    resolve_expr(visitor, arm.body, false);
 
     visitor.cx = prev_cx;
 }
@@ -250,126 +219,24 @@ fn resolve_stmt<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, stmt: &'tcx hi
     // associated destruction scope that represents the scope of the
     // statement plus its destructors, and thus the scope for which
     // regions referenced by the destructors need to survive.
-    visitor.terminating_scopes.insert(stmt_id);
 
     let prev_parent = visitor.cx.parent;
-    visitor.enter_node_scope_with_dtor(stmt_id);
+    visitor.enter_node_scope_with_dtor(stmt_id, true);
 
     intravisit::walk_stmt(visitor, stmt);
 
     visitor.cx.parent = prev_parent;
 }
 
-fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
+fn resolve_expr<'tcx>(
+    visitor: &mut ScopeResolutionVisitor<'tcx>,
+    expr: &'tcx hir::Expr<'tcx>,
+    terminating: bool,
+) {
     debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr);
 
     let prev_cx = visitor.cx;
-    visitor.enter_node_scope_with_dtor(expr.hir_id.local_id);
-
-    {
-        let terminating_scopes = &mut visitor.terminating_scopes;
-        let mut terminating = |id: hir::ItemLocalId| {
-            terminating_scopes.insert(id);
-        };
-        match expr.kind {
-            // Conditional or repeating scopes are always terminating
-            // scopes, meaning that temporaries cannot outlive them.
-            // This ensures fixed size stacks.
-            hir::ExprKind::Binary(
-                source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
-                l,
-                r,
-            ) => {
-                // expr is a short circuiting operator (|| or &&). As its
-                // functionality can't be overridden by traits, it always
-                // processes bool sub-expressions. bools are Copy and thus we
-                // can drop any temporaries in evaluation (read) order
-                // (with the exception of potentially failing let expressions).
-                // We achieve this by enclosing the operands in a terminating
-                // scope, both the LHS and the RHS.
-
-                // We optimize this a little in the presence of chains.
-                // Chains like a && b && c get lowered to AND(AND(a, b), c).
-                // In here, b and c are RHS, while a is the only LHS operand in
-                // that chain. This holds true for longer chains as well: the
-                // leading operand is always the only LHS operand that is not a
-                // binop itself. Putting a binop like AND(a, b) into a
-                // terminating scope is not useful, thus we only put the LHS
-                // into a terminating scope if it is not a binop.
-
-                let terminate_lhs = match l.kind {
-                    // let expressions can create temporaries that live on
-                    hir::ExprKind::Let(_) => false,
-                    // binops already drop their temporaries, so there is no
-                    // need to put them into a terminating scope.
-                    // This is purely an optimization to reduce the number of
-                    // terminating scopes.
-                    hir::ExprKind::Binary(
-                        source_map::Spanned {
-                            node: hir::BinOpKind::And | hir::BinOpKind::Or, ..
-                        },
-                        ..,
-                    ) => false,
-                    // otherwise: mark it as terminating
-                    _ => true,
-                };
-                if terminate_lhs {
-                    terminating(l.hir_id.local_id);
-                }
-
-                // `Let` expressions (in a let-chain) shouldn't be terminating, as their temporaries
-                // should live beyond the immediate expression
-                if !matches!(r.kind, hir::ExprKind::Let(_)) {
-                    terminating(r.hir_id.local_id);
-                }
-            }
-            hir::ExprKind::If(_, then, Some(otherwise)) => {
-                terminating(then.hir_id.local_id);
-                terminating(otherwise.hir_id.local_id);
-            }
-
-            hir::ExprKind::If(_, then, None) => {
-                terminating(then.hir_id.local_id);
-            }
-
-            hir::ExprKind::Loop(body, _, _, _) => {
-                terminating(body.hir_id.local_id);
-            }
-
-            hir::ExprKind::DropTemps(expr) => {
-                // `DropTemps(expr)` does not denote a conditional scope.
-                // Rather, we want to achieve the same behavior as `{ let _t = expr; _t }`.
-                terminating(expr.hir_id.local_id);
-            }
-
-            hir::ExprKind::AssignOp(..)
-            | hir::ExprKind::Index(..)
-            | hir::ExprKind::Unary(..)
-            | hir::ExprKind::Call(..)
-            | hir::ExprKind::MethodCall(..) => {
-                // FIXME(https://github.com/rust-lang/rfcs/issues/811) Nested method calls
-                //
-                // The lifetimes for a call or method call look as follows:
-                //
-                // call.id
-                // - arg0.id
-                // - ...
-                // - argN.id
-                // - call.callee_id
-                //
-                // The idea is that call.callee_id represents *the time when
-                // the invoked function is actually running* and call.id
-                // represents *the time to prepare the arguments and make the
-                // call*. See the section "Borrows in Calls" borrowck/README.md
-                // for an extended explanation of why this distinction is
-                // important.
-                //
-                // record_superlifetime(new_cx, expr.callee_id);
-            }
-
-            _ => {}
-        }
-    }
+    visitor.enter_node_scope_with_dtor(expr.hir_id.local_id, terminating);
 
     let prev_pessimistic = visitor.pessimistic_yield;
 
@@ -424,6 +291,53 @@ fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hi
     // properly, we can't miss any types.
 
     match expr.kind {
+        // Conditional or repeating scopes are always terminating
+        // scopes, meaning that temporaries cannot outlive them.
+        // This ensures fixed size stacks.
+        hir::ExprKind::Binary(
+            source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
+            left,
+            right,
+        ) => {
+            // expr is a short circuiting operator (|| or &&). As its
+            // functionality can't be overridden by traits, it always
+            // processes bool sub-expressions. bools are Copy and thus we
+            // can drop any temporaries in evaluation (read) order
+            // (with the exception of potentially failing let expressions).
+            // We achieve this by enclosing the operands in a terminating
+            // scope, both the LHS and the RHS.
+
+            // We optimize this a little in the presence of chains.
+            // Chains like a && b && c get lowered to AND(AND(a, b), c).
+            // In here, b and c are RHS, while a is the only LHS operand in
+            // that chain. This holds true for longer chains as well: the
+            // leading operand is always the only LHS operand that is not a
+            // binop itself. Putting a binop like AND(a, b) into a
+            // terminating scope is not useful, thus we only put the LHS
+            // into a terminating scope if it is not a binop.
+
+            let terminate_lhs = match left.kind {
+                // let expressions can create temporaries that live on
+                hir::ExprKind::Let(_) => false,
+                // binops already drop their temporaries, so there is no
+                // need to put them into a terminating scope.
+                // This is purely an optimization to reduce the number of
+                // terminating scopes.
+                hir::ExprKind::Binary(
+                    source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
+                    ..,
+                ) => false,
+                // otherwise: mark it as terminating
+                _ => true,
+            };
+
+            // `Let` expressions (in a let-chain) shouldn't be terminating, as their temporaries
+            // should live beyond the immediate expression
+            let terminate_rhs = !matches!(right.kind, hir::ExprKind::Let(_));
+
+            resolve_expr(visitor, left, terminate_lhs);
+            resolve_expr(visitor, right, terminate_rhs);
+        }
         // Manually recurse over closures, because they are nested bodies
         // that share the parent environment. We handle const blocks in
         // `visit_inline_const`.
@@ -490,11 +404,11 @@ fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hi
                 ScopeData::IfThen
             };
             visitor.enter_scope(Scope { local_id: then.hir_id.local_id, data });
-            visitor.cx.set_var_parent();
+            visitor.cx.var_parent = visitor.cx.parent;
             visitor.visit_expr(cond);
-            visitor.visit_expr(then);
+            resolve_expr(visitor, then, true);
             visitor.cx = expr_cx;
-            visitor.visit_expr(otherwise);
+            resolve_expr(visitor, otherwise, true);
         }
 
         hir::ExprKind::If(cond, then, None) => {
@@ -505,12 +419,22 @@ fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hi
                 ScopeData::IfThen
             };
             visitor.enter_scope(Scope { local_id: then.hir_id.local_id, data });
-            visitor.cx.set_var_parent();
+            visitor.cx.var_parent = visitor.cx.parent;
             visitor.visit_expr(cond);
-            visitor.visit_expr(then);
+            resolve_expr(visitor, then, true);
             visitor.cx = expr_cx;
         }
 
+        hir::ExprKind::Loop(body, _, _, _) => {
+            resolve_block(visitor, body, true);
+        }
+
+        hir::ExprKind::DropTemps(expr) => {
+            // `DropTemps(expr)` does not denote a conditional scope.
+            // Rather, we want to achieve the same behavior as `{ let _t = expr; _t }`.
+            resolve_expr(visitor, expr, true);
+        }
+
         _ => intravisit::walk_expr(visitor, expr),
     }
 
@@ -545,7 +469,7 @@ fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hi
             // Keep traversing up while we can.
             match visitor.scope_tree.parent_map.get(&scope) {
                 // Don't cross from closure bodies to their parent.
-                Some(&(superscope, _)) => match superscope.data {
+                Some(&superscope) => match superscope.data {
                     ScopeData::CallSite => break,
                     _ => scope = superscope,
                 },
@@ -781,28 +705,24 @@ fn resolve_local<'tcx>(
 
 impl<'tcx> ScopeResolutionVisitor<'tcx> {
     /// Records the current parent (if any) as the parent of `child_scope`.
-    /// Returns the depth of `child_scope`.
-    fn record_child_scope(&mut self, child_scope: Scope) -> ScopeDepth {
+    fn record_child_scope(&mut self, child_scope: Scope) {
         let parent = self.cx.parent;
         self.scope_tree.record_scope_parent(child_scope, parent);
-        // If `child_scope` has no parent, it must be the root node, and so has
-        // a depth of 1. Otherwise, its depth is one more than its parent's.
-        parent.map_or(1, |(_p, d)| d + 1)
     }
 
     /// Records the current parent (if any) as the parent of `child_scope`,
     /// and sets `child_scope` as the new current parent.
     fn enter_scope(&mut self, child_scope: Scope) {
-        let child_depth = self.record_child_scope(child_scope);
-        self.cx.parent = Some((child_scope, child_depth));
+        self.record_child_scope(child_scope);
+        self.cx.parent = Some(child_scope);
     }
 
-    fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
+    fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId, terminating: bool) {
         // If node was previously marked as a terminating scope during the
         // recursive visit of its parent node in the HIR, then we need to
         // account for the destruction scope representing the scope of
         // the destructors that run immediately after it completes.
-        if self.terminating_scopes.contains(&id) {
+        if terminating {
             self.enter_scope(Scope { local_id: id, data: ScopeData::Destruction });
         }
         self.enter_scope(Scope { local_id: id, data: ScopeData::Node });
@@ -814,13 +734,11 @@ impl<'tcx> ScopeResolutionVisitor<'tcx> {
         // visited the body.
         let outer_ec = mem::replace(&mut self.expr_and_pat_count, 0);
         let outer_cx = self.cx;
-        let outer_ts = mem::take(&mut self.terminating_scopes);
         // The 'pessimistic yield' flag is set to true when we are
         // processing a `+=` statement and have to make pessimistic
         // control flow assumptions. This doesn't apply to nested
         // bodies within the `+=` statements. See #69307.
         let outer_pessimistic_yield = mem::replace(&mut self.pessimistic_yield, false);
-        self.terminating_scopes.insert(hir_id.local_id);
 
         self.enter_scope(Scope { local_id: hir_id.local_id, data: ScopeData::CallSite });
         self.enter_scope(Scope { local_id: hir_id.local_id, data: ScopeData::Arguments });
@@ -830,14 +748,13 @@ impl<'tcx> ScopeResolutionVisitor<'tcx> {
         // Restore context we had at the start.
         self.expr_and_pat_count = outer_ec;
         self.cx = outer_cx;
-        self.terminating_scopes = outer_ts;
         self.pessimistic_yield = outer_pessimistic_yield;
     }
 }
 
 impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
     fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
-        resolve_block(self, b);
+        resolve_block(self, b, false);
     }
 
     fn visit_body(&mut self, body: &hir::Body<'tcx>) {
@@ -855,13 +772,13 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
         self.enter_body(body.value.hir_id, |this| {
             if this.tcx.hir_body_owner_kind(owner_id).is_fn_or_closure() {
                 // The arguments and `self` are parented to the fn.
-                this.cx.set_var_parent();
+                this.cx.var_parent = this.cx.parent;
                 for param in body.params {
                     this.visit_pat(param.pat);
                 }
 
                 // The body of the every fn is a root scope.
-                this.visit_expr(body.value)
+                resolve_expr(this, body.value, true);
             } else {
                 // Only functions have an outer terminating (drop) scope, while
                 // temporaries in constant initializers may be 'static, but only
@@ -882,6 +799,10 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
                 // (i.e., `'static`), which means that after `g` returns, it drops,
                 // and all the associated destruction scope rules apply.
                 this.cx.var_parent = None;
+                this.enter_scope(Scope {
+                    local_id: body.value.hir_id.local_id,
+                    data: ScopeData::Destruction,
+                });
                 resolve_local(this, None, Some(body.value));
             }
         })
@@ -897,7 +818,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
         resolve_stmt(self, s);
     }
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
-        resolve_expr(self, ex);
+        resolve_expr(self, ex, false);
     }
     fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) {
         resolve_local(self, Some(l.pat), l.init)
@@ -927,7 +848,6 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
             scope_tree: ScopeTree::default(),
             expr_and_pat_count: 0,
             cx: Context { parent: None, var_parent: None },
-            terminating_scopes: Default::default(),
             pessimistic_yield: false,
             fixup_scopes: vec![],
         };
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 952af592311..83d095ab72e 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -188,10 +188,10 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
 /// definition itself. For example, this definition would be illegal:
 ///
 /// ```rust
-/// struct Ref<'a, T> { x: &'a T }
+/// struct StaticRef<T> { x: &'static T }
 /// ```
 ///
-/// because the type did not declare that `T:'a`.
+/// because the type did not declare that `T: 'static`.
 ///
 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 15e0a72fdcb..16bac430491 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -153,9 +153,12 @@ pub(crate) fn provide(providers: &mut Providers) {
 }
 
 fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> {
+    let impls = tcx.local_trait_impls(def_id);
     // If there are no impls for the trait, then "all impls" are trivially coherent and we won't check anything
     // anyway. Thus we bail out even before the specialization graph, avoiding the dep_graph edge.
-    let Some(impls) = tcx.all_local_trait_impls(()).get(&def_id) else { return Ok(()) };
+    if impls.is_empty() {
+        return Ok(());
+    }
     // Trigger building the specialization graph for the trait. This will detect and report any
     // overlap errors.
     let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 075abc32594..625f51dd29e 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -61,6 +61,7 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers {
         type_of: type_of::type_of,
         type_of_opaque: type_of::type_of_opaque,
+        type_of_opaque_hir_typeck: type_of::type_of_opaque_hir_typeck,
         type_alias_is_lazy: type_of::type_alias_is_lazy,
         item_bounds: item_bounds::item_bounds,
         explicit_item_bounds: item_bounds::explicit_item_bounds,
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index a153ce8ea90..2bed28d7b71 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -116,8 +116,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 {
                     // enum variant discriminants are not allowed to use any kind of generics
                     None
-                } else if let Some(param_id) =
-                    tcx.hir().opt_const_param_default_param_def_id(hir_id)
+                } else if let Some(param_id) = tcx.hir_opt_const_param_default_param_def_id(hir_id)
                 {
                     // If the def_id we are calling generics_of on is an anon ct default i.e:
                     //
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 6e07f0ff53c..279b1e82a71 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -38,13 +38,13 @@ fn associated_type_bounds<'tcx>(
         let icx = ItemCtxt::new(tcx, assoc_item_def_id);
         let mut bounds = Vec::new();
         icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
-        // Associated types are implicitly sized unless a `?Sized` bound is found
+        // Implicit bounds are added to associated types unless a `?Trait` bound is found
         match filter {
             PredicateFilter::All
             | PredicateFilter::SelfOnly
             | PredicateFilter::SelfTraitThatDefines(_)
             | PredicateFilter::SelfAndAssociatedTypeBounds => {
-                icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
+                icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
             }
             // `ConstIfConst` is only interested in `~const` bounds.
             PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
@@ -327,14 +327,13 @@ fn opaque_type_bounds<'tcx>(
         let icx = ItemCtxt::new(tcx, opaque_def_id);
         let mut bounds = Vec::new();
         icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
-        // Opaque types are implicitly sized unless a `?Sized` bound is found
+        // Implicit bounds are added to opaque types unless a `?Trait` bound is found
         match filter {
             PredicateFilter::All
             | PredicateFilter::SelfOnly
             | PredicateFilter::SelfTraitThatDefines(_)
             | PredicateFilter::SelfAndAssociatedTypeBounds => {
-                // Associated types are implicitly sized unless a `?Sized` bound is found
-                icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
+                icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
             }
             //`ConstIfConst` is only interested in `~const` bounds.
             PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 4bd89861a9e..776b23bea8e 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -165,12 +165,42 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
 
             ItemKind::Trait(_, _, _, _, self_bounds, ..)
             | ItemKind::TraitAlias(_, _, self_bounds) => {
-                is_trait = Some(self_bounds);
+                is_trait = Some((self_bounds, item.span));
             }
             _ => {}
         }
     };
 
+    if let Node::TraitItem(item) = node {
+        let parent = tcx.local_parent(item.hir_id().owner.def_id);
+        let Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
+            unreachable!();
+        };
+
+        let (trait_generics, trait_bounds) = match parent_trait.kind {
+            hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
+            hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
+            _ => unreachable!(),
+        };
+
+        // Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
+        // they are not added as super trait bounds to the trait itself. See comment on
+        // `requires_default_supertraits` for more details.
+        if !icx.lowerer().requires_default_supertraits(trait_bounds, trait_generics) {
+            let mut bounds = Vec::new();
+            let self_ty_where_predicates = (parent, item.generics.predicates);
+            icx.lowerer().add_default_traits_with_filter(
+                &mut bounds,
+                tcx.types.self_param,
+                &[],
+                Some(self_ty_where_predicates),
+                item.span,
+                |tr| tr != hir::LangItem::Sized,
+            );
+            predicates.extend(bounds);
+        }
+    }
+
     let generics = tcx.generics_of(def_id);
 
     // Below we'll consider the bounds on the type parameters (including `Self`)
@@ -181,11 +211,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
         let mut bounds = Vec::new();
         icx.lowerer().lower_bounds(
             tcx.types.self_param,
-            self_bounds,
+            self_bounds.0,
             &mut bounds,
             ty::List::empty(),
             PredicateFilter::All,
         );
+        icx.lowerer().add_default_super_traits(
+            def_id,
+            &mut bounds,
+            self_bounds.0,
+            hir_generics,
+            self_bounds.1,
+        );
         predicates.extend(bounds);
     }
 
@@ -210,8 +247,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
             GenericParamKind::Type { .. } => {
                 let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
                 let mut bounds = Vec::new();
-                // Params are implicitly sized unless a `?Sized` bound is found
-                icx.lowerer().add_sized_bound(
+                // Implicit bounds are added to type params unless a `?Trait` bound is found
+                icx.lowerer().add_default_traits(
                     &mut bounds,
                     param_ty,
                     &[],
@@ -508,7 +545,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
         if matches!(def_kind, DefKind::AnonConst)
             && tcx.features().generic_const_exprs()
             && let Some(defaulted_param_def_id) =
-                tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
+                tcx.hir_opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
         {
             // In `generics_of` we set the generics' parent to be our parent's parent which means that
             // we lose out on the predicates of our actual parent if we dont return those predicates here.
@@ -625,6 +662,22 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
     let self_param_ty = tcx.types.self_param;
     let mut bounds = Vec::new();
     icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
+    match filter {
+        PredicateFilter::All
+        | PredicateFilter::SelfOnly
+        | PredicateFilter::SelfTraitThatDefines(_)
+        | PredicateFilter::SelfAndAssociatedTypeBounds => {
+            icx.lowerer().add_default_super_traits(
+                trait_def_id,
+                &mut bounds,
+                superbounds,
+                generics,
+                item.span,
+            );
+        }
+        //`ConstIfConst` is only interested in `~const` bounds.
+        PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
+    }
 
     let where_bounds_that_match =
         icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);
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 9b0d57bd75b..404753875ee 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1529,7 +1529,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             if let ResolvedArg::LateBound(..) = def
                 && let Some(what) = crossed_late_boundary
             {
-                let use_span = self.tcx.hir().span(hir_id);
+                let use_span = self.tcx.hir_span(hir_id);
                 let def_span = self.tcx.def_span(param_def_id);
                 let guar = match self.tcx.def_kind(param_def_id) {
                     DefKind::ConstParam => {
@@ -1576,11 +1576,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 } => {
                     let guar = self.tcx.dcx().emit_err(match self.tcx.def_kind(param_def_id) {
                         DefKind::TyParam => errors::LateBoundInApit::Type {
-                            span: self.tcx.hir().span(hir_id),
+                            span: self.tcx.hir_span(hir_id),
                             param_span: self.tcx.def_span(param_def_id),
                         },
                         DefKind::ConstParam => errors::LateBoundInApit::Const {
-                            span: self.tcx.hir().span(hir_id),
+                            span: self.tcx.hir_span(hir_id),
                             param_span: self.tcx.def_span(param_def_id),
                         },
                         kind => {
@@ -1605,7 +1605,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
 
         self.tcx
             .dcx()
-            .span_bug(self.tcx.hir().span(hir_id), format!("could not resolve {param_def_id:?}"));
+            .span_bug(self.tcx.hir_span(hir_id), format!("could not resolve {param_def_id:?}"));
     }
 
     #[instrument(level = "debug", skip(self))]
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index afda2c142e2..694c1228859 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -7,7 +7,9 @@ use rustc_hir::{self as hir, AmbigArg, HirId};
 use rustc_middle::query::plumbing::CyclePlaceholder;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, fold_regions};
+use rustc_middle::ty::{
+    self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, fold_regions,
+};
 use rustc_middle::{bug, span_bug};
 use rustc_span::{DUMMY_SP, Ident, Span};
 
@@ -324,10 +326,18 @@ pub(super) fn type_of_opaque(
     if let Some(def_id) = def_id.as_local() {
         Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
             hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
-                opaque::find_opaque_ty_constraints_for_tait(tcx, def_id)
+                opaque::find_opaque_ty_constraints_for_tait(
+                    tcx,
+                    def_id,
+                    DefiningScopeKind::MirBorrowck,
+                )
             }
             hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => {
-                opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id)
+                opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
+                    tcx,
+                    def_id,
+                    DefiningScopeKind::MirBorrowck,
+                )
             }
             // Opaque types desugared from `impl Trait`.
             hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
@@ -340,7 +350,12 @@ pub(super) fn type_of_opaque(
                         "tried to get type of this RPITIT with no definition"
                     );
                 }
-                opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
+                opaque::find_opaque_ty_constraints_for_rpit(
+                    tcx,
+                    def_id,
+                    owner,
+                    DefiningScopeKind::MirBorrowck,
+                )
             }
         }))
     } else {
@@ -350,6 +365,42 @@ pub(super) fn type_of_opaque(
     }
 }
 
+pub(super) fn type_of_opaque_hir_typeck(
+    tcx: TyCtxt<'_>,
+    def_id: LocalDefId,
+) -> ty::EarlyBinder<'_, Ty<'_>> {
+    ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
+        hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
+            opaque::find_opaque_ty_constraints_for_tait(tcx, def_id, DefiningScopeKind::HirTypeck)
+        }
+        hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => {
+            opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
+                tcx,
+                def_id,
+                DefiningScopeKind::HirTypeck,
+            )
+        }
+        // Opaque types desugared from `impl Trait`.
+        hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
+        | hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl } => {
+            if in_trait_or_impl == Some(hir::RpitContext::Trait)
+                && !tcx.defaultness(owner).has_value()
+            {
+                span_bug!(
+                    tcx.def_span(def_id),
+                    "tried to get type of this RPITIT with no definition"
+                );
+            }
+            opaque::find_opaque_ty_constraints_for_rpit(
+                tcx,
+                def_id,
+                owner,
+                DefiningScopeKind::HirTypeck,
+            )
+        }
+    })
+}
+
 fn infer_placeholder_type<'tcx>(
     cx: &dyn HirTyLowerer<'tcx>,
     def_id: LocalDefId,
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 3dec1e286b4..3fe3d71b32d 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -3,8 +3,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit};
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
-use rustc_span::DUMMY_SP;
+use rustc_middle::ty::{self, DefiningScopeKind, Ty, TyCtxt, TypeVisitableExt};
 use tracing::{debug, instrument, trace};
 
 use crate::errors::{TaitForwardCompat2, UnconstrainedOpaqueType};
@@ -15,6 +14,7 @@ use crate::errors::{TaitForwardCompat2, UnconstrainedOpaqueType};
 pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
     tcx: TyCtxt<'_>,
     def_id: LocalDefId,
+    opaque_types_from: DefiningScopeKind,
 ) -> Ty<'_> {
     let mut parent_def_id = def_id;
     while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy {
@@ -27,7 +27,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
         other => bug!("invalid impl trait in assoc type parent: {other:?}"),
     }
 
-    let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] };
+    let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from };
 
     for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
         let assoc = tcx.associated_item(assoc_id);
@@ -39,25 +39,14 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
     }
 
     if let Some(hidden) = locator.found {
-        // Only check against typeck if we didn't already error
-        if !hidden.ty.references_error() {
-            for concrete_type in locator.typeck_types {
-                if concrete_type.ty != tcx.erase_regions(hidden.ty) {
-                    if let Ok(d) = hidden.build_mismatch_error(&concrete_type, tcx) {
-                        d.emit();
-                    }
-                }
-            }
-        }
-
         hidden.ty
     } else {
-        let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType {
+        let guar = tcx.dcx().emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_ident(parent_def_id.to_def_id()),
             what: "impl",
         });
-        Ty::new_error(tcx, reported)
+        Ty::new_error(tcx, guar)
     }
 }
 
@@ -80,23 +69,16 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
 /// fn b<T>() -> Foo<T, u32> { .. }
 /// ```
 #[instrument(skip(tcx), level = "debug")]
-pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
-    let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] };
+pub(super) fn find_opaque_ty_constraints_for_tait(
+    tcx: TyCtxt<'_>,
+    def_id: LocalDefId,
+    opaque_types_from: DefiningScopeKind,
+) -> Ty<'_> {
+    let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from };
 
     tcx.hir_walk_toplevel_module(&mut locator);
 
     if let Some(hidden) = locator.found {
-        // Only check against typeck if we didn't already error
-        if !hidden.ty.references_error() {
-            for concrete_type in locator.typeck_types {
-                if concrete_type.ty != tcx.erase_regions(hidden.ty) {
-                    if let Ok(d) = hidden.build_mismatch_error(&concrete_type, tcx) {
-                        d.emit();
-                    }
-                }
-            }
-        }
-
         hidden.ty
     } else {
         let mut parent_def_id = def_id;
@@ -104,12 +86,12 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
             // Account for `type Alias = impl Trait<Foo = impl Trait>;` (#116031)
             parent_def_id = tcx.local_parent(parent_def_id);
         }
-        let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType {
+        let guar = tcx.dcx().emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_ident(parent_def_id.to_def_id()),
             what: "crate",
         });
-        Ty::new_error(tcx, reported)
+        Ty::new_error(tcx, guar)
     }
 }
 
@@ -126,22 +108,44 @@ struct TaitConstraintLocator<'tcx> {
     /// type).
     found: Option<ty::OpaqueHiddenType<'tcx>>,
 
-    /// In the presence of dead code, typeck may figure out a hidden type
-    /// while borrowck will not. We collect these cases here and check at
-    /// the end that we actually found a type that matches (modulo regions).
-    typeck_types: Vec<ty::OpaqueHiddenType<'tcx>>,
+    opaque_types_from: DefiningScopeKind,
 }
 
-impl TaitConstraintLocator<'_> {
+impl<'tcx> TaitConstraintLocator<'tcx> {
+    fn insert_found(&mut self, hidden_ty: ty::OpaqueHiddenType<'tcx>) {
+        if let Some(prev) = &mut self.found {
+            if hidden_ty.ty != prev.ty {
+                let (Ok(guar) | Err(guar)) =
+                    prev.build_mismatch_error(&hidden_ty, self.tcx).map(|d| d.emit());
+                prev.ty = Ty::new_error(self.tcx, guar);
+            }
+        } else {
+            self.found = Some(hidden_ty);
+        }
+    }
+
+    fn non_defining_use_in_defining_scope(&mut self, item_def_id: LocalDefId) {
+        let guar = self.tcx.dcx().emit_err(TaitForwardCompat2 {
+            span: self
+                .tcx
+                .def_ident_span(item_def_id)
+                .unwrap_or_else(|| self.tcx.def_span(item_def_id)),
+            opaque_type_span: self.tcx.def_span(self.def_id),
+            opaque_type: self.tcx.def_path_str(self.def_id),
+        });
+        self.insert_found(ty::OpaqueHiddenType::new_error(self.tcx, guar));
+    }
+
     #[instrument(skip(self), level = "debug")]
     fn check(&mut self, item_def_id: LocalDefId) {
         // Don't try to check items that cannot possibly constrain the type.
-        if !self.tcx.has_typeck_results(item_def_id) {
+        let tcx = self.tcx;
+        if !tcx.has_typeck_results(item_def_id) {
             debug!("no constraint: no typeck results");
             return;
         }
 
-        let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
+        let opaque_types_defined_by = tcx.opaque_types_defined_by(item_def_id);
         // Don't try to check items that cannot possibly constrain the type.
         if !opaque_types_defined_by.contains(&self.def_id) {
             debug!("no constraint: no opaque types defined");
@@ -152,7 +156,7 @@ impl TaitConstraintLocator<'_> {
         // "non-defining use" errors for them.
         // Note that we use `Node::fn_sig` instead of `Node::fn_decl` here, because the former
         // excludes closures, which are allowed to have `_` in their return type.
-        let hir_node = self.tcx.hir_node_by_def_id(item_def_id);
+        let hir_node = tcx.hir_node_by_def_id(item_def_id);
         debug_assert!(
             !matches!(hir_node, Node::ForeignItem(..)),
             "foreign items cannot constrain opaque types",
@@ -164,88 +168,39 @@ impl TaitConstraintLocator<'_> {
                 hir_sig.decl.output.span(),
                 "inferring return types and opaque types do not mix well",
             );
-            self.found =
-                Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) });
+            self.found = Some(ty::OpaqueHiddenType::new_error(tcx, guar));
             return;
         }
 
-        // Calling `mir_borrowck` can lead to cycle errors through
-        // const-checking, avoid calling it if we don't have to.
-        // ```rust
-        // type Foo = impl Fn() -> usize; // when computing type for this
-        // const fn bar() -> Foo {
-        //     || 0usize
-        // }
-        // const BAZR: Foo = bar(); // we would mir-borrowck this, causing cycles
-        // // because we again need to reveal `Foo` so we can check whether the
-        // // constant does not contain interior mutability.
-        // ```
-        let tables = self.tcx.typeck(item_def_id);
-        if let Some(guar) = tables.tainted_by_errors {
-            self.found =
-                Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) });
-            return;
-        }
-
-        let mut constrained = false;
-        for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
-            if opaque_type_key.def_id != self.def_id {
-                continue;
-            }
-            constrained = true;
-
-            let concrete_type =
-                self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params(
-                    opaque_type_key,
-                    self.tcx,
-                    true,
-                ));
-            if self.typeck_types.iter().all(|prev| prev.ty != concrete_type.ty) {
-                self.typeck_types.push(concrete_type);
-            }
-        }
-
-        if !constrained {
-            debug!("no constraints in typeck results");
-            if opaque_types_defined_by.contains(&self.def_id) {
-                let guar = self.tcx.dcx().emit_err(TaitForwardCompat2 {
-                    span: self
-                        .tcx
-                        .def_ident_span(item_def_id)
-                        .unwrap_or_else(|| self.tcx.def_span(item_def_id)),
-                    opaque_type_span: self.tcx.def_span(self.def_id),
-                    opaque_type: self.tcx.def_path_str(self.def_id),
-                });
-                // Avoid "opaque type not constrained" errors on the opaque itself.
-                self.found = Some(ty::OpaqueHiddenType {
-                    span: DUMMY_SP,
-                    ty: Ty::new_error(self.tcx, guar),
-                });
+        match self.opaque_types_from {
+            DefiningScopeKind::HirTypeck => {
+                let tables = tcx.typeck(item_def_id);
+                if let Some(guar) = tables.tainted_by_errors {
+                    self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
+                } else if let Some(&hidden_type) = tables.concrete_opaque_types.get(&self.def_id) {
+                    self.insert_found(hidden_type);
+                } else {
+                    self.non_defining_use_in_defining_scope(item_def_id);
+                }
             }
-            return;
-        };
-
-        // Use borrowck to get the type with unerased regions.
-        let borrowck_results = &self.tcx.mir_borrowck(item_def_id);
-
-        // If the body was tainted, then assume the opaque may have been constrained and just set it to error.
-        if let Some(guar) = borrowck_results.tainted_by_errors {
-            self.found =
-                Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) });
-            return;
-        }
-
-        debug!(?borrowck_results.concrete_opaque_types);
-        if let Some(&concrete_type) = borrowck_results.concrete_opaque_types.get(&self.def_id) {
-            debug!(?concrete_type, "found constraint");
-            if let Some(prev) = &mut self.found {
-                if concrete_type.ty != prev.ty {
-                    let (Ok(guar) | Err(guar)) =
-                        prev.build_mismatch_error(&concrete_type, self.tcx).map(|d| d.emit());
-                    prev.ty = Ty::new_error(self.tcx, guar);
+            DefiningScopeKind::MirBorrowck => {
+                let borrowck_result = tcx.mir_borrowck(item_def_id);
+                if let Some(guar) = borrowck_result.tainted_by_errors {
+                    self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
+                } else if let Some(&hidden_type) =
+                    borrowck_result.concrete_opaque_types.get(&self.def_id)
+                {
+                    debug!(?hidden_type, "found constraint");
+                    self.insert_found(hidden_type);
+                } else if let Err(guar) = tcx
+                    .type_of_opaque_hir_typeck(self.def_id)
+                    .instantiate_identity()
+                    .error_reported()
+                {
+                    self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
+                } else {
+                    self.non_defining_use_in_defining_scope(item_def_id);
                 }
-            } else {
-                self.found = Some(concrete_type);
             }
         }
     }
@@ -287,126 +242,42 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
     owner_def_id: LocalDefId,
+    opaque_types_from: DefiningScopeKind,
 ) -> Ty<'tcx> {
-    let tables = tcx.typeck(owner_def_id);
-
-    // Check that all of the opaques we inferred during HIR are compatible.
-    // FIXME: We explicitly don't check that the types inferred during HIR
-    // typeck are compatible with the one that we infer during borrowck,
-    // because that one actually sometimes has consts evaluated eagerly so
-    // using strict type equality will fail.
-    let mut hir_opaque_ty: Option<ty::OpaqueHiddenType<'tcx>> = None;
-    if tables.tainted_by_errors.is_none() {
-        for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
-            if opaque_type_key.def_id != def_id {
-                continue;
-            }
-            let concrete_type = tcx.erase_regions(
-                hidden_type.remap_generic_params_to_declaration_params(opaque_type_key, tcx, true),
-            );
-            if let Some(prev) = &mut hir_opaque_ty {
-                if concrete_type.ty != prev.ty {
-                    if let Ok(d) = prev.build_mismatch_error(&concrete_type, tcx) {
-                        d.emit();
-                    }
-                }
+    match opaque_types_from {
+        DefiningScopeKind::HirTypeck => {
+            let tables = tcx.typeck(owner_def_id);
+            if let Some(guar) = tables.tainted_by_errors {
+                Ty::new_error(tcx, guar)
+            } else if let Some(hidden_ty) = tables.concrete_opaque_types.get(&def_id) {
+                hidden_ty.ty
             } else {
-                hir_opaque_ty = Some(concrete_type);
+                // FIXME(-Znext-solver): This should not be necessary and we should
+                // instead rely on inference variable fallback inside of typeck itself.
+
+                // We failed to resolve the opaque type or it
+                // resolves to itself. We interpret this as the
+                // no values of the hidden type ever being constructed,
+                // so we can just make the hidden type be `!`.
+                // For backwards compatibility reasons, we fall back to
+                // `()` until we the diverging default is changed.
+                Ty::new_diverging_default(tcx)
             }
         }
-    }
-
-    let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
-    if let Some(mir_opaque_ty) = mir_opaque_ty {
-        if mir_opaque_ty.references_error() {
-            return mir_opaque_ty.ty;
-        }
-
-        debug!(?owner_def_id);
-        let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
-
-        match tcx.hir_node_by_def_id(owner_def_id) {
-            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),
-            other => bug!("{:?} is not a valid scope for an opaque type item", other),
-        }
-
-        mir_opaque_ty.ty
-    } else if let Some(guar) = tables.tainted_by_errors {
-        // Some error in the owner fn prevented us from populating
-        // the `concrete_opaque_types` table.
-        Ty::new_error(tcx, guar)
-    } else {
-        // Fall back to the RPIT we inferred during HIR typeck
-        if let Some(hir_opaque_ty) = hir_opaque_ty {
-            hir_opaque_ty.ty
-        } else {
-            // We failed to resolve the opaque type or it
-            // resolves to itself. We interpret this as the
-            // no values of the hidden type ever being constructed,
-            // so we can just make the hidden type be `!`.
-            // For backwards compatibility reasons, we fall back to
-            // `()` until we the diverging default is changed.
-            Ty::new_diverging_default(tcx)
-        }
-    }
-}
-
-struct RpitConstraintChecker<'tcx> {
-    tcx: TyCtxt<'tcx>,
-
-    /// def_id of the opaque type whose defining uses are being checked
-    def_id: LocalDefId,
-
-    found: ty::OpaqueHiddenType<'tcx>,
-}
-
-impl RpitConstraintChecker<'_> {
-    #[instrument(skip(self), level = "debug")]
-    fn check(&self, def_id: LocalDefId) {
-        // Use borrowck to get the type with unerased regions.
-        let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types;
-        debug!(?concrete_opaque_types);
-        if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) {
-            debug!(?concrete_type, "found constraint");
-            if concrete_type.ty != self.found.ty {
-                if let Ok(d) = self.found.build_mismatch_error(&concrete_type, self.tcx) {
-                    d.emit();
+        DefiningScopeKind::MirBorrowck => {
+            let borrowck_result = tcx.mir_borrowck(owner_def_id);
+            if let Some(guar) = borrowck_result.tainted_by_errors {
+                Ty::new_error(tcx, guar)
+            } else if let Some(hidden_ty) = borrowck_result.concrete_opaque_types.get(&def_id) {
+                hidden_ty.ty
+            } else {
+                let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
+                if let Err(guar) = hir_ty.error_reported() {
+                    Ty::new_error(tcx, guar)
+                } else {
+                    hir_ty
                 }
             }
         }
     }
 }
-
-impl<'tcx> intravisit::Visitor<'tcx> for RpitConstraintChecker<'tcx> {
-    type NestedFilter = nested_filter::OnlyBodies;
-
-    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
-        self.tcx
-    }
-    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
-        intravisit::walk_expr(self, ex);
-    }
-    fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
-        trace!(?it.owner_id);
-        // The opaque type itself or its children are not within its reveal scope.
-        if it.owner_id.def_id != self.def_id {
-            self.check(it.owner_id.def_id);
-            intravisit::walk_item(self, it);
-        }
-    }
-    fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
-        trace!(?it.owner_id);
-        // The opaque type itself or its children are not within its reveal scope.
-        if it.owner_id.def_id != self.def_id {
-            self.check(it.owner_id.def_id);
-            intravisit::walk_impl_item(self, it);
-        }
-    }
-    fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
-        trace!(?it.owner_id);
-        self.check(it.owner_id.def_id);
-        intravisit::walk_trait_item(self, it);
-    }
-}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index f0dffd780bc..c3bb860538e 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -4,9 +4,9 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::codes::*;
 use rustc_errors::struct_span_code_err;
 use rustc_hir as hir;
-use rustc_hir::HirId;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::{AmbigArg, HirId};
 use rustc_middle::bug;
 use rustc_middle::ty::{
     self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -24,25 +24,190 @@ use crate::hir_ty_lowering::{
 };
 
 impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
-    /// Add a `Sized` bound to the `bounds` if appropriate.
-    ///
-    /// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`.
-    pub(crate) fn add_sized_bound(
+    pub(crate) fn add_default_traits(
         &self,
         bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
         self_ty: Ty<'tcx>,
+        hir_bounds: &[hir::GenericBound<'tcx>],
+        self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
+        span: Span,
+    ) {
+        self.add_default_traits_with_filter(
+            bounds,
+            self_ty,
+            hir_bounds,
+            self_ty_where_predicates,
+            span,
+            |_| true,
+        );
+    }
+
+    /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
+    /// or associative items.
+    ///
+    /// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
+    /// should be added everywhere, including super bounds. However this causes a huge performance
+    /// costs. For optimization purposes instead of adding default supertraits, bounds
+    /// are added to the associative items:
+    ///
+    /// ```ignore(illustrative)
+    /// // Default bounds are generated in the following way:
+    /// trait Trait {
+    ///     fn foo(&self) where Self: Leak {}
+    /// }
+    ///
+    /// // instead of this:
+    /// trait Trait: Leak {
+    ///     fn foo(&self) {}
+    /// }
+    /// ```
+    /// It is not always possible to do this because of backward compatibility:
+    ///
+    /// ```ignore(illustrative)
+    /// pub trait Trait<Rhs = Self> {}
+    /// pub trait Trait1 : Trait {}
+    /// //~^ ERROR: `Rhs` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait`
+    /// ```
+    ///
+    /// or:
+    ///
+    /// ```ignore(illustrative)
+    /// trait Trait {
+    ///     type Type where Self: Sized;
+    /// }
+    /// trait Trait2<T> : Trait<Type = T> {}
+    /// //~^ ERROR: `DefaultAutoTrait` required for `Trait2`, by implicit  `Self: DefaultAutoTrait` in `Trait::Type`
+    /// ```
+    ///
+    /// Therefore, `experimental_default_bounds` are still being added to supertraits if
+    /// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
+    pub(crate) fn requires_default_supertraits(
+        &self,
         hir_bounds: &'tcx [hir::GenericBound<'tcx>],
+        hir_generics: &'tcx hir::Generics<'tcx>,
+    ) -> bool {
+        struct TraitInfoCollector;
+
+        impl<'tcx> hir::intravisit::Visitor<'tcx> for TraitInfoCollector {
+            type Result = ControlFlow<()>;
+
+            fn visit_assoc_item_constraint(
+                &mut self,
+                _constraint: &'tcx hir::AssocItemConstraint<'tcx>,
+            ) -> Self::Result {
+                ControlFlow::Break(())
+            }
+
+            fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
+                if matches!(
+                    &t.kind,
+                    hir::TyKind::Path(hir::QPath::Resolved(
+                        _,
+                        hir::Path { res: hir::def::Res::SelfTyParam { .. }, .. },
+                    ))
+                ) {
+                    return ControlFlow::Break(());
+                }
+                hir::intravisit::walk_ty(self, t)
+            }
+        }
+
+        let mut found = false;
+        for bound in hir_bounds {
+            found |= hir::intravisit::walk_param_bound(&mut TraitInfoCollector, bound).is_break();
+        }
+        found |= hir::intravisit::walk_generics(&mut TraitInfoCollector, hir_generics).is_break();
+        found
+    }
+
+    /// Lazily sets `experimental_default_bounds` to true on trait super bounds.
+    /// See `requires_default_supertraits` for more information.
+    pub(crate) fn add_default_super_traits(
+        &self,
+        trait_def_id: LocalDefId,
+        bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
+        hir_bounds: &'tcx [hir::GenericBound<'tcx>],
+        hir_generics: &'tcx hir::Generics<'tcx>,
+        span: Span,
+    ) {
+        assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
+        if self.requires_default_supertraits(hir_bounds, hir_generics) {
+            let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
+            self.add_default_traits_with_filter(
+                bounds,
+                self.tcx().types.self_param,
+                hir_bounds,
+                Some(self_ty_where_predicates),
+                span,
+                |default_trait| default_trait != hir::LangItem::Sized,
+            );
+        }
+    }
+
+    pub(crate) fn add_default_traits_with_filter(
+        &self,
+        bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
+        self_ty: Ty<'tcx>,
+        hir_bounds: &[hir::GenericBound<'tcx>],
+        self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
+        span: Span,
+        f: impl Fn(hir::LangItem) -> bool,
+    ) {
+        self.tcx().default_traits().iter().filter(|&&default_trait| f(default_trait)).for_each(
+            |default_trait| {
+                self.add_default_trait(
+                    *default_trait,
+                    bounds,
+                    self_ty,
+                    hir_bounds,
+                    self_ty_where_predicates,
+                    span,
+                );
+            },
+        );
+    }
+
+    /// Add a `Sized` or `experimental_default_bounds` bounds to the `bounds` if appropriate.
+    ///
+    /// Doesn't add the bound if the HIR bounds contain any of `Trait`, `?Trait` or `!Trait`.
+    pub(crate) fn add_default_trait(
+        &self,
+        trait_: hir::LangItem,
+        bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
+        self_ty: Ty<'tcx>,
+        hir_bounds: &[hir::GenericBound<'tcx>],
         self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
         span: Span,
     ) {
+        let trait_id = self.tcx().lang_items().get(trait_);
+        if let Some(trait_id) = trait_id
+            && self.do_not_provide_default_trait_bound(
+                trait_id,
+                hir_bounds,
+                self_ty_where_predicates,
+            )
+        {
+            // There was no `?Trait` or `!Trait` bound;
+            // add `Trait` if it's available.
+            let trait_ref = ty::TraitRef::new(self.tcx(), trait_id, [self_ty]);
+            // Preferable to put this obligation first, since we report better errors for sized ambiguity.
+            bounds.insert(0, (trait_ref.upcast(self.tcx()), span));
+        }
+    }
+
+    fn do_not_provide_default_trait_bound<'a>(
+        &self,
+        trait_def_id: DefId,
+        hir_bounds: &'a [hir::GenericBound<'tcx>],
+        self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
+    ) -> bool {
         let tcx = self.tcx();
-        let sized_def_id = tcx.lang_items().sized_trait();
-        let mut seen_negative_sized_bound = false;
-        let mut seen_positive_sized_bound = false;
+        let mut seen_negative_bound = false;
+        let mut seen_positive_bound = false;
 
         // Try to find an unbound in bounds.
         let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
-        let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
+        let mut search_bounds = |hir_bounds: &'a [hir::GenericBound<'tcx>]| {
             for hir_bound in hir_bounds {
                 let hir::GenericBound::Trait(ptr) = hir_bound else {
                     continue;
@@ -50,17 +215,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 match ptr.modifiers.polarity {
                     hir::BoundPolarity::Maybe(_) => unbounds.push(ptr),
                     hir::BoundPolarity::Negative(_) => {
-                        if let Some(sized_def_id) = sized_def_id
-                            && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
-                        {
-                            seen_negative_sized_bound = true;
+                        if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) {
+                            seen_negative_bound = true;
                         }
                     }
                     hir::BoundPolarity::Positive => {
-                        if let Some(sized_def_id) = sized_def_id
-                            && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
-                        {
-                            seen_positive_sized_bound = true;
+                        if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) {
+                            seen_positive_bound = true;
                         }
                     }
                 }
@@ -95,32 +256,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             };
         }
 
-        let mut seen_sized_unbound = false;
+        let mut seen_unbound = false;
         for unbound in unbounds {
-            if let Some(sized_def_id) = sized_def_id
-                && unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
-            {
-                seen_sized_unbound = true;
-                continue;
+            let unbound_def_id = unbound.trait_ref.trait_def_id();
+            if unbound_def_id == Some(trait_def_id) {
+                seen_unbound = true;
+            }
+            let emit_relax_err = || {
+                let unbound_traits =
+                    match self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
+                        true => "`?Sized` and `experimental_default_bounds`",
+                        false => "`?Sized`",
+                    };
+                // There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`.
+                tcx.dcx().span_err(
+                    unbound.span,
+                    format!(
+                        "relaxing a default bound only does something for {}; \
+                    all other traits are not bound by default",
+                        unbound_traits
+                    ),
+                );
+            };
+            match unbound_def_id {
+                Some(def_id) if !tcx.is_default_trait(def_id) => emit_relax_err(),
+                None => emit_relax_err(),
+                _ => {}
             }
-            // There was a `?Trait` bound, but it was not `?Sized`
-            self.dcx().span_err(
-                unbound.span,
-                "relaxing a default bound only does something for `?Sized`; \
-                all other traits are not bound by default",
-            );
         }
 
-        if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound {
-            // There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound;
-            // we don't need to do anything.
-        } else if let Some(sized_def_id) = sized_def_id {
-            // There was no `?Sized`, `!Sized` or explicit `Sized` bound;
-            // add `Sized` if it's available.
-            let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [self_ty]);
-            // Preferable to put this obligation first, since we report better errors for sized ambiguity.
-            bounds.insert(0, (trait_ref.upcast(tcx), span));
-        }
+        !(seen_unbound || seen_negative_bound || seen_positive_bound)
     }
 
     /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
@@ -684,7 +849,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
                 span: path_span,
                 ty: tcx.liberate_late_bound_regions(item_def_id, output),
-                fn_span: tcx.hir().span_if_local(item_def_id),
+                fn_span: tcx.hir_span_if_local(item_def_id),
                 note: (),
             }));
         };
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index 170500c7a16..ecb453bced0 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -32,7 +32,7 @@ pub(crate) fn validate_cmse_abi<'tcx>(
                         span,
                         ..
                     }) => *span,
-                    _ => tcx.hir().span(hir_id),
+                    _ => tcx.hir_span(hir_id),
                 };
                 struct_span_code_err!(
                     tcx.dcx(),
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 27643e715e6..aeebe45f881 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -57,6 +57,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
+        let ast_bounds: Vec<_> =
+            hir_bounds.iter().map(|&trait_ref| hir::GenericBound::Trait(trait_ref)).collect();
+
+        self.add_default_traits_with_filter(
+            &mut user_written_bounds,
+            dummy_self,
+            &ast_bounds,
+            None,
+            span,
+            |tr| tr != hir::LangItem::Sized,
+        );
+
         let (elaborated_trait_bounds, elaborated_projection_bounds) =
             traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied());
         let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = elaborated_trait_bounds
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 3b007c77198..6e9c178d33a 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -882,7 +882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             let rename_message = if is_shadowed { ", consider renaming it" } else { "" };
 
-            if let Some(sp) = tcx.hir().span_if_local(item.def_id) {
+            if let Some(sp) = tcx.hir_span_if_local(item.def_id) {
                 err.span_label(
                     sp,
                     format!("`{}{}` defined here{}", prefix, item.name, rename_message),
@@ -1381,7 +1381,7 @@ pub(crate) fn fn_trait_to_string(
         .find_map(|c| {
             if c.ident.name == sym::Output
                 && let Some(ty) = c.ty()
-                && ty.span != tcx.hir().span(trait_segment.hir_id)
+                && ty.span != tcx.hir_span(trait_segment.hir_id)
             {
                 tcx.sess.source_map().span_to_snippet(ty.span).ok()
             } else {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index 60a60f6415a..21f0f9648ea 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -92,7 +92,7 @@ fn generic_arg_mismatch_err(
             GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
             GenericParamDefKind::Const { .. },
         ) if tcx.type_of(param.def_id).skip_binder() == tcx.types.usize => {
-            let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id));
+            let snippet = sess.source_map().span_to_snippet(tcx.hir_span(len.hir_id));
             if let Ok(snippet) = snippet {
                 err.span_suggestion(
                     arg.span(),
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 55886312284..8e62dce2191 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -86,6 +86,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 "expected a type, found a trait"
             );
             if self_ty.span.can_be_used_for_suggestions()
+                && poly_trait_ref.trait_ref.trait_def_id().is_some()
                 && !self.maybe_suggest_impl_trait(self_ty, &mut diag)
                 && !self.maybe_suggest_dyn_trait(self_ty, sugg, &mut diag)
             {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 76a880da418..b4a71edc118 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -838,7 +838,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 | PredicateFilter::SelfOnly
                 | PredicateFilter::SelfAndAssociatedTypeBounds => {
                     match constness {
-                        hir::BoundConstness::Always(span) => {
+                        hir::BoundConstness::Always(_) => {
                             if polarity == ty::PredicatePolarity::Positive {
                                 bounds.push((
                                     poly_trait_ref
@@ -864,7 +864,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 // in `lower_assoc_item_constraint`.
                 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
                     match constness {
-                        hir::BoundConstness::Maybe(span) => {
+                        hir::BoundConstness::Maybe(_) => {
                             if polarity == ty::PredicatePolarity::Positive {
                                 bounds.push((
                                     poly_trait_ref
@@ -1066,7 +1066,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let bound_span = tcx
                     .associated_items(bound_id)
                     .find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
-                    .and_then(|item| tcx.hir().span_if_local(item.def_id));
+                    .and_then(|item| tcx.hir_span_if_local(item.def_id));
 
                 if let Some(bound_span) = bound_span {
                     err.span_label(
@@ -1400,7 +1400,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         );
                     }
 
-                    if let Some(sp) = tcx.hir().span_if_local(adt_def.did()) {
+                    if let Some(sp) = tcx.hir_span_if_local(adt_def.did()) {
                         err.span_label(sp, format!("variant `{assoc_ident}` not found here"));
                     }
 
@@ -1730,25 +1730,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         .is_accessible_from(self.item_def_id(), tcx)
                     && tcx.all_impls(*trait_def_id)
                         .any(|impl_def_id| {
-                            let impl_header = tcx.impl_trait_header(impl_def_id);
-                            impl_header.is_some_and(|header| {
-                                let trait_ref = header.trait_ref.instantiate(
-                                    tcx,
-                                    infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
-                                );
-
-                                let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
-                                // FIXME: Don't bother dealing with non-lifetime binders here...
-                                if value.has_escaping_bound_vars() {
-                                    return false;
-                                }
-                                infcx
-                                    .can_eq(
-                                        ty::ParamEnv::empty(),
-                                        trait_ref.self_ty(),
-                                        value,
-                                    ) && header.polarity != ty::ImplPolarity::Negative
-                            })
+                            let header = tcx.impl_trait_header(impl_def_id).unwrap();
+                            let trait_ref = header.trait_ref.instantiate(
+                                tcx,
+                                infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
+                            );
+
+                            let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
+                            // FIXME: Don't bother dealing with non-lifetime binders here...
+                            if value.has_escaping_bound_vars() {
+                                return false;
+                            }
+                            infcx
+                                .can_eq(
+                                    ty::ParamEnv::empty(),
+                                    trait_ref.self_ty(),
+                                    value,
+                                ) && header.polarity != ty::ImplPolarity::Negative
                         })
             })
             .map(|trait_def_id| tcx.def_path_str(trait_def_id))
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index e27a81d4976..c01b81563dc 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -170,7 +170,7 @@ fn diagnostic_hir_wf_check<'tcx>(
                 ..
             }) => vec![*ty],
             hir::Node::AnonConst(_) => {
-                if let Some(const_param_id) = tcx.hir().opt_const_param_default_param_def_id(hir_id)
+                if let Some(const_param_id) = tcx.hir_opt_const_param_default_param_def_id(hir_id)
                     && let hir::Node::GenericParam(hir::GenericParam {
                         kind: hir::GenericParamKind::Const { ty, .. },
                         ..
diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs
index 32b05dcc569..daa908c8c78 100644
--- a/compiler/rustc_hir_analysis/src/outlives/mod.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs
@@ -25,7 +25,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
         }
         DefKind::AnonConst if tcx.features().generic_const_exprs() => {
             let id = tcx.local_def_id_to_hir_id(item_def_id);
-            if tcx.hir().opt_const_param_default_param_def_id(id).is_some() {
+            if tcx.hir_opt_const_param_default_param_def_id(id).is_some() {
                 // In `generics_of` we set the generics' parent to be our parent's parent which means that
                 // we lose out on the predicates of our actual parent if we dont return those predicates here.
                 // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index ddaca89ccf8..8c0c17f7a7d 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1193,7 +1193,8 @@ impl<'a> State<'a> {
         wth: hir::StructTailExpr<'_>,
     ) {
         self.print_qpath(qpath, true);
-        self.word("{");
+        self.nbsp();
+        self.word_space("{");
         self.commasep_cmnt(Consistent, fields, |s, field| s.print_expr_field(field), |f| f.span);
         match wth {
             hir::StructTailExpr::Base(expr) => {
@@ -1215,20 +1216,13 @@ impl<'a> State<'a> {
                 self.word("..");
                 self.end();
             }
-            hir::StructTailExpr::None => {
-                if !fields.is_empty() {
-                    self.word(",");
-                }
-            }
+            hir::StructTailExpr::None => {}
         }
-
+        self.space();
         self.word("}");
     }
 
     fn print_expr_field(&mut self, field: &hir::ExprField<'_>) {
-        if self.attrs(field.hir_id).is_empty() {
-            self.space();
-        }
         self.cbox(INDENT_UNIT);
         self.print_attrs_as_outer(self.attrs(field.hir_id));
         if !field.is_shorthand {
@@ -1277,18 +1271,18 @@ impl<'a> State<'a> {
         self.print_call_post(base_args)
     }
 
-    fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) {
-        let binop_prec = op.node.precedence();
+    fn print_expr_binary(&mut self, op: hir::BinOpKind, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) {
+        let binop_prec = op.precedence();
         let left_prec = lhs.precedence();
         let right_prec = rhs.precedence();
 
-        let (mut left_needs_paren, right_needs_paren) = match op.node.fixity() {
+        let (mut left_needs_paren, right_needs_paren) = match op.fixity() {
             Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec),
             Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec),
             Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec),
         };
 
-        match (&lhs.kind, op.node) {
+        match (&lhs.kind, op) {
             // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
             // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
             // of `(x as i32) < ...`. We need to convince it _not_ to do that.
@@ -1303,7 +1297,7 @@ impl<'a> State<'a> {
 
         self.print_expr_cond_paren(lhs, left_needs_paren);
         self.space();
-        self.word_space(op.node.as_str());
+        self.word_space(op.as_str());
         self.print_expr_cond_paren(rhs, right_needs_paren);
     }
 
@@ -1457,7 +1451,7 @@ impl<'a> State<'a> {
                 self.word(".use");
             }
             hir::ExprKind::Binary(op, lhs, rhs) => {
-                self.print_expr_binary(op, lhs, rhs);
+                self.print_expr_binary(op.node, lhs, rhs);
             }
             hir::ExprKind::Unary(op, expr) => {
                 self.print_expr_unary(op, expr);
@@ -1578,8 +1572,7 @@ impl<'a> State<'a> {
             hir::ExprKind::AssignOp(op, lhs, rhs) => {
                 self.print_expr_cond_paren(lhs, lhs.precedence() <= ExprPrecedence::Assign);
                 self.space();
-                self.word(op.node.as_str());
-                self.word_space("=");
+                self.word_space(op.node.as_str());
                 self.print_expr_cond_paren(rhs, rhs.precedence() < ExprPrecedence::Assign);
             }
             hir::ExprKind::Field(expr, ident) => {
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 5e2daa69628..02fd7367e2f 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -771,7 +771,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     format!("this {descr} returns an unsized value `{output_ty}`, so it cannot be called")
                 );
                 if let DefIdOrName::DefId(def_id) = maybe_def
-                    && let Some(def_span) = self.tcx.hir().span_if_local(def_id)
+                    && let Some(def_span) = self.tcx.hir_span_if_local(def_id)
                 {
                     err.span_label(def_span, "the callable type is defined here");
                 }
@@ -780,7 +780,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        if let Some(span) = self.tcx.hir().res_span(def) {
+        if let Some(span) = self.tcx.hir_res_span(def) {
             let callee_ty = callee_ty.to_string();
             let label = match (unit_variant, inner_callee_path) {
                 (Some((_, kind, path)), _) => {
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index a4776338f6c..467ca26e7ea 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -970,7 +970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);
 
         // Normalize only after registering in `user_provided_sigs`.
-        self.normalize(self.tcx.hir().span(hir_id), result)
+        self.normalize(self.tcx.hir_span(hir_id), result)
     }
 
     /// Invoked when we are translating the coroutine that results
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 4cbc42b99ea..f42ca3af2b3 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -41,8 +41,8 @@ use rustc_abi::ExternAbi;
 use rustc_attr_parsing::InlineAttr;
 use rustc_errors::codes::*;
 use rustc_errors::{Applicability, Diag, struct_span_code_err};
+use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{self as hir, LangItem};
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_infer::infer::relate::RelateResult;
 use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
@@ -55,7 +55,7 @@ use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
 };
 use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::{self, AliasTy, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span};
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -592,63 +592,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         // Create an obligation for `Source: CoerceUnsized<Target>`.
         let cause = self.cause(self.cause.span, ObligationCauseCode::Coercion { source, target });
-        let root_obligation = Obligation::new(
-            self.tcx,
-            cause.clone(),
-            self.fcx.param_env,
-            ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]),
-        );
-
-        // If the root `Source: CoerceUnsized<Target>` obligation can't possibly hold,
-        // we don't have to assume that this is unsizing coercion (it will always lead to an error)
-        //
-        // However, we don't want to bail early all the time, since the unholdable obligations
-        // may be interesting for diagnostics (such as trying to coerce `&T` to `&dyn Id<This = U>`),
-        // so we only bail if there (likely) is another way to convert the types.
-        if !self.infcx.predicate_may_hold(&root_obligation) {
-            if let Some(dyn_metadata_adt_def_id) = self.tcx.lang_items().get(LangItem::DynMetadata)
-                && let Some(metadata_type_def_id) = self.tcx.lang_items().get(LangItem::Metadata)
-            {
-                self.probe(|_| {
-                    let ocx = ObligationCtxt::new(&self.infcx);
-
-                    // returns `true` if `<ty as Pointee>::Metadata` is `DynMetadata<_>`
-                    let has_dyn_trait_metadata = |ty| {
-                        let metadata_ty: Result<_, _> = ocx.structurally_normalize_ty(
-                            &ObligationCause::dummy(),
-                            self.fcx.param_env,
-                            Ty::new_alias(
-                                self.tcx,
-                                ty::AliasTyKind::Projection,
-                                AliasTy::new(self.tcx, metadata_type_def_id, [ty]),
-                            ),
-                        );
-
-                        metadata_ty.is_ok_and(|metadata_ty| {
-                            metadata_ty
-                                .ty_adt_def()
-                                .is_some_and(|d| d.did() == dyn_metadata_adt_def_id)
-                        })
-                    };
-
-                    // If both types are raw pointers to a (wrapper over a) trait object,
-                    // this might be a cast like `*const W<dyn Trait> -> *const dyn Trait`.
-                    // So it's better to bail and try that. (even if the cast is not possible, for
-                    // example due to vtables not matching, cast diagnostic will likely still be better)
-                    //
-                    // N.B. use `target`, not `coerce_target` (the latter is a var)
-                    if let &ty::RawPtr(source_pointee, _) = coerce_source.kind()
-                        && let &ty::RawPtr(target_pointee, _) = target.kind()
-                        && has_dyn_trait_metadata(source_pointee)
-                        && has_dyn_trait_metadata(target_pointee)
-                    {
-                        return Err(TypeError::Mismatch);
-                    }
-
-                    Ok(())
-                })?;
-            }
-        }
 
         // Use a FIFO queue for this custom fulfillment procedure.
         //
@@ -657,7 +600,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         // and almost never more than 3. By using a SmallVec we avoid an
         // allocation, at the (very small) cost of (occasionally) having to
         // shift subsequent elements down when removing the front element.
-        let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![root_obligation];
+        let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![Obligation::new(
+            self.tcx,
+            cause,
+            self.fcx.param_env,
+            ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target])
+        )];
 
         // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
         // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 41bdd0ca43e..b845e2190ef 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -999,10 +999,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let container = with_no_trimmed_paths!(self.tcx.def_path_str(container_id));
         for def_id in pick.import_ids {
             let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
-            path_span.push_span_label(
-                self.tcx.hir().span(hir_id),
-                format!("`{container}` imported here"),
-            );
+            path_span
+                .push_span_label(self.tcx.hir_span(hir_id), format!("`{container}` imported here"));
         }
         let tail = with_no_trimmed_paths!(match &other_methods_in_scope[..] {
             [] => return,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index a75f6f4caac..45ab8e03db5 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -512,7 +512,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_expr_assign(expr, expected, lhs, rhs, span)
             }
             ExprKind::AssignOp(op, lhs, rhs) => {
-                self.check_expr_binop_assign(expr, op, lhs, rhs, expected)
+                self.check_expr_assign_op(expr, op, lhs, rhs, expected)
             }
             ExprKind::Unary(unop, oprnd) => self.check_expr_unop(unop, oprnd, expected, expr),
             ExprKind::AddrOf(kind, mutbl, oprnd) => {
@@ -3239,7 +3239,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Some(x) => self.tcx.local_def_id_to_hir_id(x),
             None => return,
         };
-        let param_span = self.tcx.hir().span(param_hir_id);
+        let param_span = self.tcx.hir_span(param_hir_id);
         let param_name = self.tcx.hir_ty_param_name(param_def_id.expect_local());
 
         err.span_label(param_span, format!("type parameter '{param_name}' declared here"));
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index c71a5ea8b97..64176dacb73 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -1,6 +1,9 @@
 //! A different sort of visitor for walking fn bodies. Unlike the
 //! normal visitor, which just walks the entire body in one shot, the
 //! `ExprUseVisitor` determines how expressions are being used.
+//!
+//! In the compiler, this is only used for upvar inference, but there
+//! are many uses within clippy.
 
 use std::cell::{Ref, RefCell};
 use std::ops::Deref;
@@ -25,7 +28,7 @@ use rustc_middle::ty::{
 use rustc_middle::{bug, span_bug};
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::infer::InferCtxtExt;
-use tracing::{debug, trace};
+use tracing::{debug, instrument, trace};
 
 use crate::fn_ctxt::FnCtxt;
 
@@ -35,11 +38,8 @@ pub trait Delegate<'tcx> {
     /// The value found at `place` is moved, depending
     /// on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`.
     ///
-    /// Use of a `Copy` type in a ByValue context is considered a use
-    /// by `ImmBorrow` and `borrow` is called instead. This is because
-    /// a shared borrow is the "minimum access" that would be needed
-    /// to perform a copy.
-    ///
+    /// If the value is `Copy`, [`copy`][Self::copy] is called instead, which
+    /// by default falls back to [`borrow`][Self::borrow].
     ///
     /// The parameter `diag_expr_id` indicates the HIR id that ought to be used for
     /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic
@@ -73,6 +73,10 @@ pub trait Delegate<'tcx> {
 
     /// The value found at `place` is being copied.
     /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
+    ///
+    /// If an implementation is not provided, use of a `Copy` type in a ByValue context is instead
+    /// considered a use by `ImmBorrow` and `borrow` is called instead. This is because a shared
+    /// borrow is the "minimum access" that would be needed to perform a copy.
     fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
         // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default
         // we treat a copy of `x` as a borrow of `x`.
@@ -141,6 +145,8 @@ impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D {
     }
 }
 
+/// This trait makes `ExprUseVisitor` usable with both [`FnCtxt`]
+/// and [`LateContext`], depending on where in the compiler it is used.
 pub trait TypeInformationCtxt<'tcx> {
     type TypeckResults<'a>: Deref<Target = ty::TypeckResults<'tcx>>
     where
@@ -154,7 +160,7 @@ pub trait TypeInformationCtxt<'tcx> {
 
     fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
 
-    fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error;
+    fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error;
 
     fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error>;
 
@@ -189,7 +195,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
         (**self).try_structurally_resolve_type(sp, ty)
     }
 
-    fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error {
+    fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error {
         self.dcx().span_delayed_bug(span, msg.to_string())
     }
 
@@ -239,7 +245,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
         t
     }
 
-    fn report_error(&self, span: Span, msg: impl ToString) -> ! {
+    fn report_bug(&self, span: Span, msg: impl ToString) -> ! {
         span_bug!(span, "{}", msg.to_string())
     }
 
@@ -268,9 +274,9 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
     }
 }
 
-/// The ExprUseVisitor type
+/// A visitor that reports how each expression is being used.
 ///
-/// This is the code that actually walks the tree.
+/// See [module-level docs][self] and [`Delegate`] for details.
 pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> {
     cx: Cx,
     /// We use a `RefCell` here so that delegates can mutate themselves, but we can
@@ -314,9 +320,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         Ok(())
     }
 
+    #[instrument(skip(self), level = "debug")]
     fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
-        debug!("delegate_consume(place_with_id={:?})", place_with_id);
-
         if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
             self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
         } else {
@@ -324,9 +329,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         }
     }
 
+    #[instrument(skip(self), level = "debug")]
     pub fn consume_clone_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
-        debug!("delegate_consume_or_clone(place_with_id={:?})", place_with_id);
-
         // `x.use` will do one of the following
         // * if it implements `Copy`, it will be a copy
         // * if it implements `UseCloned`, it will be a call to `clone`
@@ -351,18 +355,16 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     }
 
     // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`.
+    #[instrument(skip(self), level = "debug")]
     pub fn consume_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
-        debug!("consume_expr(expr={:?})", expr);
-
         let place_with_id = self.cat_expr(expr)?;
         self.consume_or_copy(&place_with_id, place_with_id.hir_id);
         self.walk_expr(expr)?;
         Ok(())
     }
 
+    #[instrument(skip(self), level = "debug")]
     pub fn consume_or_clone_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
-        debug!("consume_or_clone_expr(expr={:?})", expr);
-
         let place_with_id = self.cat_expr(expr)?;
         self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
         self.walk_expr(expr)?;
@@ -376,17 +378,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         Ok(())
     }
 
+    #[instrument(skip(self), level = "debug")]
     fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) -> Result<(), Cx::Error> {
-        debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk);
-
         let place_with_id = self.cat_expr(expr)?;
         self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
         self.walk_expr(expr)
     }
 
+    #[instrument(skip(self), level = "debug")]
     pub fn walk_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
-        debug!("walk_expr(expr={:?})", expr);
-
         self.walk_adjustment(expr)?;
 
         match expr.kind {
@@ -733,9 +733,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
 
     /// Indicates that the value of `blk` will be consumed, meaning either copied or moved
     /// depending on its type.
+    #[instrument(skip(self), level = "debug")]
     fn walk_block(&self, blk: &hir::Block<'_>) -> Result<(), Cx::Error> {
-        debug!("walk_block(blk.hir_id={})", blk.hir_id);
-
         for stmt in blk.stmts {
             self.walk_stmt(stmt)?;
         }
@@ -861,7 +860,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     }
 
     /// Walks the autoref `autoref` applied to the autoderef'd
-    /// `expr`. `base_place` is the mem-categorized form of `expr`
+    /// `expr`. `base_place` is `expr` represented as a place,
     /// after all relevant autoderefs have occurred.
     fn walk_autoref(
         &self,
@@ -942,14 +941,13 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     }
 
     /// The core driver for walking a pattern
+    #[instrument(skip(self), level = "debug")]
     fn walk_pat(
         &self,
         discr_place: &PlaceWithHirId<'tcx>,
         pat: &hir::Pat<'_>,
         has_guard: bool,
     ) -> Result<(), Cx::Error> {
-        debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard);
-
         let tcx = self.cx.tcx();
         self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| {
             match pat.kind {
@@ -1042,6 +1040,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     ///
     /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing
     /// closure as the DefId.
+    #[instrument(skip(self), level = "debug")]
     fn walk_captures(&self, closure_expr: &hir::Closure<'_>) -> Result<(), Cx::Error> {
         fn upvar_is_local_variable(
             upvars: Option<&FxIndexMap<HirId, hir::Upvar>>,
@@ -1051,8 +1050,6 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             upvars.map(|upvars| !upvars.contains_key(&upvar_id)).unwrap_or(body_owner_is_closure)
         }
 
-        debug!("walk_captures({:?})", closure_expr);
-
         let tcx = self.cx.tcx();
         let closure_def_id = closure_expr.def_id;
         // For purposes of this function, coroutine and closures are equivalent.
@@ -1164,55 +1161,17 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     }
 }
 
-/// The job of the categorization methods is to analyze an expression to
-/// determine what kind of memory is used in evaluating it (for example,
-/// where dereferences occur and what kind of pointer is dereferenced;
-/// whether the memory is mutable, etc.).
-///
-/// Categorization effectively transforms all of our expressions into
-/// expressions of the following forms (the actual enum has many more
-/// possibilities, naturally, but they are all variants of these base
-/// forms):
-/// ```ignore (not-rust)
-/// E = rvalue    // some computed rvalue
-///   | x         // address of a local variable or argument
-///   | *E        // deref of a ptr
-///   | E.comp    // access to an interior component
-/// ```
-/// Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
-/// address where the result is to be found. If Expr is a place, then this
-/// is the address of the place. If `Expr` is an rvalue, this is the address of
-/// some temporary spot in memory where the result is stored.
-///
-/// Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)`
-/// as follows:
-///
-/// - `cat`: what kind of expression was this? This is a subset of the
-///   full expression forms which only includes those that we care about
-///   for the purpose of the analysis.
-/// - `mutbl`: mutability of the address `A`.
-/// - `ty`: the type of data found at the address `A`.
-///
-/// The resulting categorization tree differs somewhat from the expressions
-/// themselves. For example, auto-derefs are explicit. Also, an index `a[b]` is
-/// decomposed into two operations: a dereference to reach the array data and
-/// then an index to jump forward to the relevant item.
+/// The job of the methods whose name starts with `cat_` is to analyze
+/// expressions and construct the corresponding [`Place`]s. The `cat`
+/// stands for "categorize", this is a leftover from long ago when
+/// places were called "categorizations".
 ///
-/// ## By-reference upvars
-///
-/// One part of the codegen which may be non-obvious is that we translate
-/// closure upvars into the dereference of a borrowed pointer; this more closely
-/// resembles the runtime codegen. So, for example, if we had:
-///
-///     let mut x = 3;
-///     let y = 5;
-///     let inc = || x += y;
-///
-/// Then when we categorize `x` (*within* the closure) we would yield a
-/// result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
-/// tied to `x`. The type of `x'` will be a borrowed pointer.
+/// Note that a [`Place`] differs somewhat from the expression itself. For
+/// example, auto-derefs are explicit. Also, an index `a[b]` is decomposed into
+/// two operations: a dereference to reach the array data and then an index to
+/// jump forward to the relevant item.
 impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
-    fn resolve_type_vars_or_error(
+    fn resolve_type_vars_or_bug(
         &self,
         id: HirId,
         ty: Option<Ty<'tcx>>,
@@ -1222,10 +1181,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 let ty = self.cx.resolve_vars_if_possible(ty);
                 self.cx.error_reported_in_ty(ty)?;
                 if ty.is_ty_var() {
-                    debug!("resolve_type_vars_or_error: infer var from {:?}", ty);
-                    Err(self
-                        .cx
-                        .report_error(self.cx.tcx().hir().span(id), "encountered type variable"))
+                    debug!("resolve_type_vars_or_bug: infer var from {:?}", ty);
+                    Err(self.cx.report_bug(self.cx.tcx().hir_span(id), "encountered type variable"))
                 } else {
                     Ok(ty)
                 }
@@ -1233,24 +1190,21 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             None => {
                 // FIXME: We shouldn't be relying on the infcx being tainted.
                 self.cx.tainted_by_errors()?;
-                bug!(
-                    "no type for node {} in mem_categorization",
-                    self.cx.tcx().hir_id_to_string(id)
-                );
+                bug!("no type for node {} in ExprUseVisitor", self.cx.tcx().hir_id_to_string(id));
             }
         }
     }
 
     fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error> {
-        self.resolve_type_vars_or_error(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
+        self.resolve_type_vars_or_bug(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
     }
 
     fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
-        self.resolve_type_vars_or_error(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
+        self.resolve_type_vars_or_bug(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
     }
 
     fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
-        self.resolve_type_vars_or_error(
+        self.resolve_type_vars_or_bug(
             expr.hir_id,
             self.cx.typeck_results().expr_ty_adjusted_opt(expr),
         )
@@ -1285,7 +1239,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         self.pat_ty_unadjusted(pat)
     }
 
-    /// Like `TypeckResults::pat_ty`, but ignores implicit `&` patterns.
+    /// Like [`Self::pat_ty_adjusted`], but ignores implicit `&` patterns.
     fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
         let base_ty = self.node_ty(pat.hir_id)?;
         trace!(?base_ty);
@@ -1315,7 +1269,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                             debug!("By-ref binding of non-derefable type");
                             Err(self
                                 .cx
-                                .report_error(pat.span, "by-ref binding of non-derefable type"))
+                                .report_bug(pat.span, "by-ref binding of non-derefable type"))
                         }
                     }
                 } else {
@@ -1511,7 +1465,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 }
             }
 
-            def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def),
+            def => span_bug!(span, "unexpected definition in ExprUseVisitor: {:?}", def),
         }
     }
 
@@ -1553,10 +1507,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         if node_ty != place_ty
             && self
                 .cx
-                .try_structurally_resolve_type(
-                    self.cx.tcx().hir().span(base_place.hir_id),
-                    place_ty,
-                )
+                .try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
                 .is_impl_trait()
         {
             projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
@@ -1595,17 +1546,14 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         let base_curr_ty = base_place.place.ty();
         let deref_ty = match self
             .cx
-            .try_structurally_resolve_type(
-                self.cx.tcx().hir().span(base_place.hir_id),
-                base_curr_ty,
-            )
+            .try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
             .builtin_deref(true)
         {
             Some(ty) => ty,
             None => {
                 debug!("explicit deref of non-derefable type: {:?}", base_curr_ty);
-                return Err(self.cx.report_error(
-                    self.cx.tcx().hir().span(node),
+                return Err(self.cx.report_bug(
+                    self.cx.tcx().hir_span(node),
                     "explicit deref of non-derefable type",
                 ));
             }
@@ -1629,7 +1577,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else {
             return Err(self
                 .cx
-                .report_error(span, "struct or tuple struct pattern not applied to an ADT"));
+                .report_bug(span, "struct or tuple struct pattern not applied to an ADT"));
         };
 
         match res {
@@ -1675,7 +1623,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         let ty = self.cx.typeck_results().node_type(pat_hir_id);
         match self.cx.try_structurally_resolve_type(span, ty).kind() {
             ty::Tuple(args) => Ok(args.len()),
-            _ => Err(self.cx.report_error(span, "tuple pattern not applied to a tuple")),
+            _ => Err(self.cx.report_bug(span, "tuple pattern not applied to a tuple")),
         }
     }
 
@@ -1854,7 +1802,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                     debug!("explicit index of non-indexable type {:?}", place_with_id);
                     return Err(self
                         .cx
-                        .report_error(pat.span, "explicit index of non-indexable type"));
+                        .report_bug(pat.span, "explicit index of non-indexable type"));
                 };
                 let elt_place = self.cat_projection(
                     pat.hir_id,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index d75c2853ba0..91190a32ff5 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -157,7 +157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Lots of that diagnostics code relies on subtle effects of re-lowering, so we'll
                 // let it keep doing that and just ensure that compilation won't succeed.
                 self.dcx().span_delayed_bug(
-                    self.tcx.hir().span(id),
+                    self.tcx.hir_span(id),
                     format!("`{prev}` overridden by `{ty}` for {id:?} in {:?}", self.body_id),
                 );
             }
@@ -532,7 +532,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ct = self.lowerer().lower_const_arg(const_arg, feed);
         self.register_wf_obligation(
             ct.into(),
-            self.tcx.hir().span(const_arg.hir_id),
+            self.tcx.hir_span(const_arg.hir_id),
             ObligationCauseCode::WellFormed(None),
         );
         ct
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 264719ca569..912098c4e2d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -351,7 +351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if self.suggest_fn_call(err, expr, found, |output| self.may_coerce(output, expected))
             && let ty::FnDef(def_id, ..) = *found.kind()
-            && let Some(sp) = self.tcx.hir().span_if_local(def_id)
+            && let Some(sp) = self.tcx.hir_span_if_local(def_id)
         {
             let name = self.tcx.item_name(def_id);
             let kind = self.tcx.def_kind(def_id);
@@ -407,7 +407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         vec![(expr.span.shrink_to_hi(), format!(".{}()", conversion_method.name))]
                     };
                     let struct_pat_shorthand_field =
-                        self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr);
+                        self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr);
                     if let Some(name) = struct_pat_shorthand_field {
                         sugg.insert(0, (expr.span.shrink_to_lo(), format!("{name}: ")));
                     }
@@ -449,7 +449,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             });
 
             let prefix_wrap = |sugg: &str| {
-                if let Some(name) = self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+                if let Some(name) = self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
                     format!(": {}{}", name, sugg)
                 } else {
                     sugg.to_string()
@@ -671,7 +671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                         _ => {
                             let prefix = if let Some(name) =
-                                self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr)
+                                self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr)
                             {
                                 format!("{}: ", name)
                             } else {
@@ -1153,7 +1153,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         if can_return
             && let Some(span) = expr.span.find_ancestor_inside(
-                self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
+                self.tcx.hir_span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
             )
         {
             // When the expr is in a match arm's body, we shouldn't add semicolon ';' at the end.
@@ -1275,7 +1275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 )
                 .must_apply_modulo_regions()
         {
-            let suggestion = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+            let suggestion = match self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
                 Some(ident) => format!(": {ident}.clone()"),
                 None => ".clone()".to_string(),
             };
@@ -1381,7 +1381,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     (span.shrink_to_hi(), ").into()".to_owned()),
                 ]
             };
-            if let Some(name) = self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+            if let Some(name) = self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
                 sugg.insert(0, (expr.span.shrink_to_lo(), format!("{}: ", name)));
             }
             diag.multipart_suggestion(
@@ -1436,7 +1436,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return false;
         }
 
-        let suggestion = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+        let suggestion = match self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
             Some(ident) => format!(": {ident}.is_some()"),
             None => ".is_some()".to_string(),
         };
@@ -2032,7 +2032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             )
         };
 
-        let sugg = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+        let sugg = match self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
             Some(ident) => format!(": {ident}{sugg}"),
             None => sugg.to_string(),
         };
@@ -2289,7 +2289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Unroll desugaring, to make sure this works for `for` loops etc.
                 loop {
                     parent = self.tcx.parent_hir_id(id);
-                    let parent_span = self.tcx.hir().span(parent);
+                    let parent_span = self.tcx.hir_span(parent);
                     if parent_span.find_ancestor_inside(expr.span).is_some() {
                         // The parent node is part of the same span, so is the result of the
                         // same expansion/desugaring and not the 'real' parent node.
@@ -2378,7 +2378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .collect();
 
             let suggestions_for = |variant: &_, ctor_kind, field_name| {
-                let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+                let prefix = match self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
                     Some(ident) => format!("{ident}: "),
                     None => String::new(),
                 };
@@ -2700,8 +2700,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ));
                     }
 
-                    let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr)
-                    {
+                    let prefix = match self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
                         Some(ident) => format!("{ident}: "),
                         None => String::new(),
                     };
@@ -2911,7 +2910,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         };
 
                         let prefix =
-                            match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+                            match self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr) {
                                 Some(ident) => format!("{ident}: "),
                                 None => String::new(),
                             };
@@ -3478,30 +3477,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         lhs_ty: Ty<'tcx>,
         rhs_expr: &'tcx hir::Expr<'tcx>,
         lhs_expr: &'tcx hir::Expr<'tcx>,
-        op: hir::BinOp,
     ) {
-        match op.node {
-            hir::BinOpKind::Eq => {
-                if let Some(partial_eq_def_id) = self.infcx.tcx.lang_items().eq_trait()
-                    && self
-                        .infcx
-                        .type_implements_trait(partial_eq_def_id, [rhs_ty, lhs_ty], self.param_env)
-                        .must_apply_modulo_regions()
-                {
-                    let sm = self.tcx.sess.source_map();
-                    if let Ok(rhs_snippet) = sm.span_to_snippet(rhs_expr.span)
-                        && let Ok(lhs_snippet) = sm.span_to_snippet(lhs_expr.span)
-                    {
-                        err.note(format!("`{rhs_ty}` implements `PartialEq<{lhs_ty}>`"));
-                        err.multipart_suggestion(
-                            "consider swapping the equality",
-                            vec![(lhs_expr.span, rhs_snippet), (rhs_expr.span, lhs_snippet)],
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                }
+        if let Some(partial_eq_def_id) = self.infcx.tcx.lang_items().eq_trait()
+            && self
+                .infcx
+                .type_implements_trait(partial_eq_def_id, [rhs_ty, lhs_ty], self.param_env)
+                .must_apply_modulo_regions()
+        {
+            let sm = self.tcx.sess.source_map();
+            if let Ok(rhs_snippet) = sm.span_to_snippet(rhs_expr.span)
+                && let Ok(lhs_snippet) = sm.span_to_snippet(lhs_expr.span)
+            {
+                err.note(format!("`{rhs_ty}` implements `PartialEq<{lhs_ty}>`"));
+                err.multipart_suggestion(
+                    "consider swapping the equality",
+                    vec![(lhs_expr.span, rhs_snippet), (rhs_expr.span, lhs_snippet)],
+                    Applicability::MaybeIncorrect,
+                );
             }
-            _ => {}
         }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 54e9e699353..194e420b606 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -45,7 +45,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(crate) fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) {
         let tcx = self.tcx;
         let dl = &tcx.data_layout;
-        let span = tcx.hir().span(hir_id);
+        let span = tcx.hir_span(hir_id);
         let normalize = |ty| {
             let ty = self.resolve_vars_if_possible(ty);
             if let Ok(ty) =
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 4968998fd51..46389668de7 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -117,7 +117,7 @@ fn typeck_with_inspect<'tcx>(
 
     let id = tcx.local_def_id_to_hir_id(def_id);
     let node = tcx.hir_node(id);
-    let span = tcx.hir().span(id);
+    let span = tcx.hir_span(id);
 
     // Figure out what primary body this item has.
     let body_id = node.body_id().unwrap_or_else(|| {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 908c3ee2eb8..246b23f11b6 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -254,11 +254,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     item_name
                 );
                 err.span_label(item_name.span, format!("private {kind}"));
-                let sp = self
-                    .tcx
-                    .hir()
-                    .span_if_local(def_id)
-                    .unwrap_or_else(|| self.tcx.def_span(def_id));
+                let sp =
+                    self.tcx.hir_span_if_local(def_id).unwrap_or_else(|| self.tcx.def_span(def_id));
                 err.span_label(sp, format!("private {kind} defined here"));
                 if let Some(within_macro_span) = within_macro_span {
                     err.span_label(within_macro_span, "due to this macro variable");
@@ -566,7 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     span.push_span_label(sugg_let.span,
                             format!("`{rcvr_name}` of type `{self_ty}` that has method `{method_name}` defined earlier here"));
                     span.push_span_label(
-                        self.tcx.hir().span(recv_id),
+                        self.tcx.hir_span(recv_id),
                         format!(
                             "earlier `{rcvr_name}` shadowed here with type `{ty_str_reported}`"
                         ),
@@ -2561,7 +2558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ExprKind::Path(QPath::Resolved(_, path)) => {
                     // local binding
                     if let hir::def::Res::Local(hir_id) = path.res {
-                        let span = tcx.hir().span(hir_id);
+                        let span = tcx.hir_span(hir_id);
                         let filename = tcx.sess.source_map().span_to_filename(span);
 
                         let parent_node = self.tcx.parent_hir_node(hir_id);
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index a473e14b244..93f77b8409f 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -4,15 +4,15 @@ use rustc_data_structures::packed::Pu128;
 use rustc_errors::codes::*;
 use rustc_errors::{Applicability, Diag, struct_span_code_err};
 use rustc_infer::traits::ObligationCauseCode;
+use rustc_middle::bug;
 use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
-use rustc_middle::{bug, span_bug};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
-use rustc_span::{Ident, Span, sym};
+use rustc_span::{Ident, Span, Symbol, sym};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::{FulfillmentError, Obligation, ObligationCtxt};
 use tracing::debug;
@@ -24,24 +24,27 @@ use crate::Expectation;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Checks a `a <op>= b`
-    pub(crate) fn check_expr_binop_assign(
+    pub(crate) fn check_expr_assign_op(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
-        op: hir::BinOp,
+        op: hir::AssignOp,
         lhs: &'tcx hir::Expr<'tcx>,
         rhs: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
         let (lhs_ty, rhs_ty, return_ty) =
-            self.check_overloaded_binop(expr, lhs, rhs, op, IsAssign::Yes, expected);
-
-        let ty =
-            if !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() && is_builtin_binop(lhs_ty, rhs_ty, op) {
-                self.enforce_builtin_binop_types(lhs.span, lhs_ty, rhs.span, rhs_ty, op);
-                self.tcx.types.unit
-            } else {
-                return_ty
-            };
+            self.check_overloaded_binop(expr, lhs, rhs, Op::AssignOp(op), expected);
+
+        let category = BinOpCategory::from(op.node);
+        let ty = if !lhs_ty.is_ty_var()
+            && !rhs_ty.is_ty_var()
+            && is_builtin_binop(lhs_ty, rhs_ty, category)
+        {
+            self.enforce_builtin_binop_types(lhs.span, lhs_ty, rhs.span, rhs_ty, category);
+            self.tcx.types.unit
+        } else {
+            return_ty
+        };
 
         self.check_lhs_assignable(lhs, E0067, op.span, |err| {
             if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
@@ -49,7 +52,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .lookup_op_method(
                         (lhs, lhs_deref_ty),
                         Some((rhs, rhs_ty)),
-                        Op::Binary(op, IsAssign::Yes),
+                        lang_item_for_binop(self.tcx, Op::AssignOp(op)),
+                        op.span,
                         expected,
                     )
                     .is_ok()
@@ -60,7 +64,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .lookup_op_method(
                             (lhs, lhs_ty),
                             Some((rhs, rhs_ty)),
-                            Op::Binary(op, IsAssign::Yes),
+                            lang_item_for_binop(self.tcx, Op::AssignOp(op)),
+                            op.span,
                             expected,
                         )
                         .is_err()
@@ -98,7 +103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             expr.hir_id, expr, op, lhs_expr, rhs_expr
         );
 
-        match BinOpCategory::from(op) {
+        match BinOpCategory::from(op.node) {
             BinOpCategory::Shortcircuit => {
                 // && and || are a simple case.
                 self.check_expr_coercible_to_type(lhs_expr, tcx.types.bool, None);
@@ -114,14 +119,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Otherwise, we always treat operators as if they are
                 // overloaded. This is the way to be most flexible w/r/t
                 // types that get inferred.
-                let (lhs_ty, rhs_ty, return_ty) = self.check_overloaded_binop(
-                    expr,
-                    lhs_expr,
-                    rhs_expr,
-                    op,
-                    IsAssign::No,
-                    expected,
-                );
+                let (lhs_ty, rhs_ty, return_ty) =
+                    self.check_overloaded_binop(expr, lhs_expr, rhs_expr, Op::BinOp(op), expected);
 
                 // Supply type inference hints if relevant. Probably these
                 // hints should be enforced during select as part of the
@@ -135,16 +134,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // deduce that the result type should be `u32`, even
                 // though we don't know yet what type 2 has and hence
                 // can't pin this down to a specific impl.
+                let category = BinOpCategory::from(op.node);
                 if !lhs_ty.is_ty_var()
                     && !rhs_ty.is_ty_var()
-                    && is_builtin_binop(lhs_ty, rhs_ty, op)
+                    && is_builtin_binop(lhs_ty, rhs_ty, category)
                 {
                     let builtin_return_ty = self.enforce_builtin_binop_types(
                         lhs_expr.span,
                         lhs_ty,
                         rhs_expr.span,
                         rhs_ty,
-                        op,
+                        category,
                     );
                     self.demand_eqtype(expr.span, builtin_return_ty, return_ty);
                     builtin_return_ty
@@ -161,16 +161,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         lhs_ty: Ty<'tcx>,
         rhs_span: Span,
         rhs_ty: Ty<'tcx>,
-        op: hir::BinOp,
+        category: BinOpCategory,
     ) -> Ty<'tcx> {
-        debug_assert!(is_builtin_binop(lhs_ty, rhs_ty, op));
+        debug_assert!(is_builtin_binop(lhs_ty, rhs_ty, category));
 
         // Special-case a single layer of referencing, so that things like `5.0 + &6.0f32` work.
         // (See https://github.com/rust-lang/rust/issues/57447.)
         let (lhs_ty, rhs_ty) = (deref_ty_if_possible(lhs_ty), deref_ty_if_possible(rhs_ty));
 
         let tcx = self.tcx;
-        match BinOpCategory::from(op) {
+        match category {
             BinOpCategory::Shortcircuit => {
                 self.demand_suptype(lhs_span, tcx.types.bool, lhs_ty);
                 self.demand_suptype(rhs_span, tcx.types.bool, rhs_ty);
@@ -201,17 +201,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &'tcx hir::Expr<'tcx>,
         lhs_expr: &'tcx hir::Expr<'tcx>,
         rhs_expr: &'tcx hir::Expr<'tcx>,
-        op: hir::BinOp,
-        is_assign: IsAssign,
+        op: Op,
         expected: Expectation<'tcx>,
     ) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) {
-        debug!(
-            "check_overloaded_binop(expr.hir_id={}, op={:?}, is_assign={:?})",
-            expr.hir_id, op, is_assign
-        );
+        debug!("check_overloaded_binop(expr.hir_id={}, op={:?})", expr.hir_id, op);
 
-        let lhs_ty = match is_assign {
-            IsAssign::No => {
+        let lhs_ty = match op {
+            Op::BinOp(_) => {
                 // Find a suitable supertype of the LHS expression's type, by coercing to
                 // a type variable, to pass as the `Self` to the trait, avoiding invariant
                 // trait matching creating lifetime constraints that are too strict.
@@ -221,7 +217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let fresh_var = self.next_ty_var(lhs_expr.span);
                 self.demand_coerce(lhs_expr, lhs_ty, fresh_var, Some(rhs_expr), AllowTwoPhase::No)
             }
-            IsAssign::Yes => {
+            Op::AssignOp(_) => {
                 // rust-lang/rust#52126: We have to use strict
                 // equivalence on the LHS of an assign-op like `+=`;
                 // overwritten or mutably-borrowed places cannot be
@@ -242,7 +238,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let result = self.lookup_op_method(
             (lhs_expr, lhs_ty),
             Some((rhs_expr, rhs_ty_var)),
-            Op::Binary(op, is_assign),
+            lang_item_for_binop(self.tcx, op),
+            op.span(),
             expected,
         );
 
@@ -252,15 +249,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             rhs_ty_var,
             Some(lhs_expr),
             |err, ty| {
-                self.suggest_swapping_lhs_and_rhs(err, ty, lhs_ty, rhs_expr, lhs_expr, op);
+                if let Op::BinOp(binop) = op
+                    && binop.node == hir::BinOpKind::Eq
+                {
+                    self.suggest_swapping_lhs_and_rhs(err, ty, lhs_ty, rhs_expr, lhs_expr);
+                }
             },
         );
         let rhs_ty = self.resolve_vars_with_obligations(rhs_ty);
 
         let return_ty = match result {
             Ok(method) => {
-                let by_ref_binop = !op.node.is_by_value();
-                if is_assign == IsAssign::Yes || by_ref_binop {
+                let by_ref_binop = !op.is_by_value();
+                if matches!(op, Op::AssignOp(_)) || by_ref_binop {
                     if let ty::Ref(_, _, mutbl) = method.sig.inputs()[0].kind() {
                         let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes);
                         let autoref = Adjustment {
@@ -301,32 +302,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Ty::new_misc_error(self.tcx)
             }
             Err(errors) => {
-                let (_, trait_def_id) =
-                    lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
+                let (_, trait_def_id) = lang_item_for_binop(self.tcx, op);
                 let missing_trait = trait_def_id
                     .map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id)));
                 let mut path = None;
                 let lhs_ty_str = self.tcx.short_string(lhs_ty, &mut path);
                 let rhs_ty_str = self.tcx.short_string(rhs_ty, &mut path);
-                let (mut err, output_def_id) = match is_assign {
-                    IsAssign::Yes => {
+                let (mut err, output_def_id) = match op {
+                    Op::AssignOp(assign_op) => {
+                        let s = assign_op.node.as_str();
                         let mut err = struct_span_code_err!(
                             self.dcx(),
                             expr.span,
                             E0368,
-                            "binary assignment operation `{}=` cannot be applied to type `{}`",
-                            op.node.as_str(),
+                            "binary assignment operation `{}` cannot be applied to type `{}`",
+                            s,
                             lhs_ty_str,
                         );
                         err.span_label(
                             lhs_expr.span,
-                            format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty_str),
+                            format!("cannot use `{}` on type `{}`", s, lhs_ty_str),
                         );
                         self.note_unmet_impls_on_type(&mut err, errors, false);
                         (err, None)
                     }
-                    IsAssign::No => {
-                        let message = match op.node {
+                    Op::BinOp(bin_op) => {
+                        let message = match bin_op.node {
                             hir::BinOpKind::Add => {
                                 format!("cannot add `{rhs_ty_str}` to `{lhs_ty_str}`")
                             }
@@ -362,8 +363,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                             _ => format!(
                                 "binary operation `{}` cannot be applied to type `{}`",
-                                op.node.as_str(),
-                                lhs_ty_str,
+                                bin_op.node.as_str(),
+                                lhs_ty_str
                             ),
                         };
                         let output_def_id = trait_def_id.and_then(|def_id| {
@@ -376,7 +377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 .cloned()
                         });
                         let mut err =
-                            struct_span_code_err!(self.dcx(), op.span, E0369, "{message}");
+                            struct_span_code_err!(self.dcx(), bin_op.span, E0369, "{message}");
                         if !lhs_expr.span.eq(&rhs_expr.span) {
                             err.span_label(lhs_expr.span, lhs_ty_str.clone());
                             err.span_label(rhs_expr.span, rhs_ty_str);
@@ -409,18 +410,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .lookup_op_method(
                             (lhs_expr, lhs_deref_ty),
                             Some((rhs_expr, rhs_ty)),
-                            Op::Binary(op, is_assign),
+                            lang_item_for_binop(self.tcx, op),
+                            op.span(),
                             expected,
                         )
                         .is_ok()
                     {
                         let msg = format!(
-                            "`{}{}` can be used on `{}` if you dereference the left-hand side",
-                            op.node.as_str(),
-                            match is_assign {
-                                IsAssign::Yes => "=",
-                                IsAssign::No => "",
-                            },
+                            "`{}` can be used on `{}` if you dereference the left-hand side",
+                            op.as_str(),
                             self.tcx.short_string(lhs_deref_ty, err.long_ty_path()),
                         );
                         err.span_suggestion_verbose(
@@ -442,14 +440,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             .lookup_op_method(
                                 (lhs_expr, lhs_adjusted_ty),
                                 Some((rhs_expr, rhs_adjusted_ty)),
-                                Op::Binary(op, is_assign),
+                                lang_item_for_binop(self.tcx, op),
+                                op.span(),
                                 expected,
                             )
                             .is_ok()
                         {
                             let lhs = self.tcx.short_string(lhs_adjusted_ty, err.long_ty_path());
                             let rhs = self.tcx.short_string(rhs_adjusted_ty, err.long_ty_path());
-                            let op = op.node.as_str();
+                            let op = op.as_str();
                             err.note(format!("an implementation for `{lhs} {op} {rhs}` exists"));
 
                             if let Some(lhs_new_mutbl) = lhs_new_mutbl
@@ -499,7 +498,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.lookup_op_method(
                         (lhs_expr, lhs_ty),
                         Some((rhs_expr, rhs_ty)),
-                        Op::Binary(op, is_assign),
+                        lang_item_for_binop(self.tcx, op),
+                        op.span(),
                         expected,
                     )
                     .is_ok()
@@ -511,13 +511,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 // We should suggest `a + b` => `*a + b` if `a` is copy, and suggest
                 // `a += b` => `*a += b` if a is a mut ref.
-                if !op.span.can_be_used_for_suggestions() {
+                if !op.span().can_be_used_for_suggestions() {
                     // Suppress suggestions when lhs and rhs are not in the same span as the error
-                } else if is_assign == IsAssign::Yes
+                } else if let Op::AssignOp(_) = op
                     && let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty)
                 {
                     suggest_deref_binop(&mut err, lhs_deref_ty);
-                } else if is_assign == IsAssign::No
+                } else if let Op::BinOp(_) = op
                     && let ty::Ref(region, lhs_deref_ty, mutbl) = lhs_ty.kind()
                 {
                     if self.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty) {
@@ -572,10 +572,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
 
                 if let Some(missing_trait) = missing_trait {
-                    if op.node == hir::BinOpKind::Add
-                        && self.check_str_addition(
-                            lhs_expr, rhs_expr, lhs_ty, rhs_ty, &mut err, is_assign, op,
-                        )
+                    if matches!(
+                        op,
+                        Op::BinOp(Spanned { node: hir::BinOpKind::Add, .. })
+                            | Op::AssignOp(Spanned { node: hir::AssignOpKind::AddAssign, .. })
+                    ) && self
+                        .check_str_addition(lhs_expr, rhs_expr, lhs_ty, rhs_ty, &mut err, op)
                     {
                         // This has nothing here because it means we did string
                         // concatenation (e.g., "Hello " + "World!"). This means
@@ -592,7 +594,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             .lookup_op_method(
                                 (lhs_expr, lhs_ty),
                                 Some((rhs_expr, rhs_ty)),
-                                Op::Binary(op, is_assign),
+                                lang_item_for_binop(self.tcx, op),
+                                op.span(),
                                 expected,
                             )
                             .unwrap_err();
@@ -642,9 +645,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 // Suggest using `add`, `offset` or `offset_from` for pointer - {integer},
                 // pointer + {integer} or pointer - pointer.
-                if op.span.can_be_used_for_suggestions() {
-                    match op.node {
-                        hir::BinOpKind::Add if lhs_ty.is_raw_ptr() && rhs_ty.is_integral() => {
+                if op.span().can_be_used_for_suggestions() {
+                    match op {
+                        Op::BinOp(Spanned { node: hir::BinOpKind::Add, .. })
+                            if lhs_ty.is_raw_ptr() && rhs_ty.is_integral() =>
+                        {
                             err.multipart_suggestion(
                                 "consider using `wrapping_add` or `add` for pointer + {integer}",
                                 vec![
@@ -657,7 +662,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 Applicability::MaybeIncorrect,
                             );
                         }
-                        hir::BinOpKind::Sub => {
+                        Op::BinOp(Spanned { node: hir::BinOpKind::Sub, .. }) => {
                             if lhs_ty.is_raw_ptr() && rhs_ty.is_integral() {
                                 err.multipart_suggestion(
                                     "consider using `wrapping_sub` or `sub` for \
@@ -713,8 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         lhs_ty: Ty<'tcx>,
         rhs_ty: Ty<'tcx>,
         err: &mut Diag<'_>,
-        is_assign: IsAssign,
-        op: hir::BinOp,
+        op: Op,
     ) -> bool {
         let str_concat_note = "string concatenation requires an owned `String` on the left";
         let rm_borrow_msg = "remove the borrow to obtain an owned `String`";
@@ -733,8 +737,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             r_ty.kind(), ty::Ref(_, inner_ty, _) if *inner_ty.kind() == ty::Str
                         )) =>
             {
-                if let IsAssign::No = is_assign { // Do not supply this message if `&str += &str`
-                    err.span_label(op.span, "`+` cannot be used to concatenate two `&str` strings");
+                if let Op::BinOp(_) = op { // Do not supply this message if `&str += &str`
+                    err.span_label(
+                        op.span(),
+                        "`+` cannot be used to concatenate two `&str` strings"
+                    );
                     err.note(str_concat_note);
                     if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind {
                         err.span_suggestion_verbose(
@@ -758,11 +765,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if (*l_ty.kind() == ty::Str || is_std_string(l_ty)) && is_std_string(rhs_ty) =>
             {
                 err.span_label(
-                    op.span,
+                    op.span(),
                     "`+` cannot be used to concatenate a `&str` with a `String`",
                 );
-                match is_assign {
-                    IsAssign::No => {
+                match op {
+                    Op::BinOp(_) => {
                         let sugg_msg;
                         let lhs_sugg = if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind {
                             sugg_msg = "remove the borrow on the left and add one on the right";
@@ -781,7 +788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             Applicability::MachineApplicable,
                         );
                     }
-                    IsAssign::Yes => {
+                    Op::AssignOp(_) => {
                         err.note(str_concat_note);
                     }
                 }
@@ -799,7 +806,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
         assert!(op.is_by_value());
-        match self.lookup_op_method((ex, operand_ty), None, Op::Unary(op, ex.span), expected) {
+        match self.lookup_op_method(
+            (ex, operand_ty),
+            None,
+            lang_item_for_unop(self.tcx, op),
+            ex.span,
+            expected,
+        ) {
             Ok(method) => {
                 self.write_method_call_and_enforce_effects(ex.hir_id, ex.span, method);
                 method.sig.output()
@@ -898,21 +911,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         (lhs_expr, lhs_ty): (&'tcx hir::Expr<'tcx>, Ty<'tcx>),
         opt_rhs: Option<(&'tcx hir::Expr<'tcx>, Ty<'tcx>)>,
-        op: Op,
+        (opname, trait_did): (Symbol, Option<hir::def_id::DefId>),
+        span: Span,
         expected: Expectation<'tcx>,
     ) -> Result<MethodCallee<'tcx>, Vec<FulfillmentError<'tcx>>> {
-        let span = match op {
-            Op::Binary(op, _) => op.span,
-            Op::Unary(_, span) => span,
-        };
-        let (opname, Some(trait_did)) = lang_item_for_op(self.tcx, op, span) else {
+        let Some(trait_did) = trait_did else {
             // Bail if the operator trait is not defined.
             return Err(vec![]);
         };
 
         debug!(
-            "lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})",
-            lhs_ty, op, opname, trait_did
+            "lookup_op_method(lhs_ty={:?}, opname={:?}, trait_did={:?})",
+            lhs_ty, opname, trait_did
         );
 
         let opname = Ident::with_dummy_span(opname);
@@ -980,37 +990,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 }
 
-fn lang_item_for_op(
-    tcx: TyCtxt<'_>,
-    op: Op,
-    span: Span,
-) -> (rustc_span::Symbol, Option<hir::def_id::DefId>) {
+fn lang_item_for_binop(tcx: TyCtxt<'_>, op: Op) -> (Symbol, Option<hir::def_id::DefId>) {
     let lang = tcx.lang_items();
-    if let Op::Binary(op, IsAssign::Yes) = op {
-        match op.node {
-            hir::BinOpKind::Add => (sym::add_assign, lang.add_assign_trait()),
-            hir::BinOpKind::Sub => (sym::sub_assign, lang.sub_assign_trait()),
-            hir::BinOpKind::Mul => (sym::mul_assign, lang.mul_assign_trait()),
-            hir::BinOpKind::Div => (sym::div_assign, lang.div_assign_trait()),
-            hir::BinOpKind::Rem => (sym::rem_assign, lang.rem_assign_trait()),
-            hir::BinOpKind::BitXor => (sym::bitxor_assign, lang.bitxor_assign_trait()),
-            hir::BinOpKind::BitAnd => (sym::bitand_assign, lang.bitand_assign_trait()),
-            hir::BinOpKind::BitOr => (sym::bitor_assign, lang.bitor_assign_trait()),
-            hir::BinOpKind::Shl => (sym::shl_assign, lang.shl_assign_trait()),
-            hir::BinOpKind::Shr => (sym::shr_assign, lang.shr_assign_trait()),
-            hir::BinOpKind::Lt
-            | hir::BinOpKind::Le
-            | hir::BinOpKind::Ge
-            | hir::BinOpKind::Gt
-            | hir::BinOpKind::Eq
-            | hir::BinOpKind::Ne
-            | hir::BinOpKind::And
-            | hir::BinOpKind::Or => {
-                span_bug!(span, "impossible assignment operation: {}=", op.node.as_str())
-            }
-        }
-    } else if let Op::Binary(op, IsAssign::No) = op {
-        match op.node {
+    match op {
+        Op::AssignOp(op) => match op.node {
+            hir::AssignOpKind::AddAssign => (sym::add_assign, lang.add_assign_trait()),
+            hir::AssignOpKind::SubAssign => (sym::sub_assign, lang.sub_assign_trait()),
+            hir::AssignOpKind::MulAssign => (sym::mul_assign, lang.mul_assign_trait()),
+            hir::AssignOpKind::DivAssign => (sym::div_assign, lang.div_assign_trait()),
+            hir::AssignOpKind::RemAssign => (sym::rem_assign, lang.rem_assign_trait()),
+            hir::AssignOpKind::BitXorAssign => (sym::bitxor_assign, lang.bitxor_assign_trait()),
+            hir::AssignOpKind::BitAndAssign => (sym::bitand_assign, lang.bitand_assign_trait()),
+            hir::AssignOpKind::BitOrAssign => (sym::bitor_assign, lang.bitor_assign_trait()),
+            hir::AssignOpKind::ShlAssign => (sym::shl_assign, lang.shl_assign_trait()),
+            hir::AssignOpKind::ShrAssign => (sym::shr_assign, lang.shr_assign_trait()),
+        },
+        Op::BinOp(op) => match op.node {
             hir::BinOpKind::Add => (sym::add, lang.add_trait()),
             hir::BinOpKind::Sub => (sym::sub, lang.sub_trait()),
             hir::BinOpKind::Mul => (sym::mul, lang.mul_trait()),
@@ -1028,20 +1023,24 @@ fn lang_item_for_op(
             hir::BinOpKind::Eq => (sym::eq, lang.eq_trait()),
             hir::BinOpKind::Ne => (sym::ne, lang.eq_trait()),
             hir::BinOpKind::And | hir::BinOpKind::Or => {
-                span_bug!(span, "&& and || are not overloadable")
+                bug!("&& and || are not overloadable")
             }
-        }
-    } else if let Op::Unary(hir::UnOp::Not, _) = op {
-        (sym::not, lang.not_trait())
-    } else if let Op::Unary(hir::UnOp::Neg, _) = op {
-        (sym::neg, lang.neg_trait())
-    } else {
-        bug!("lookup_op_method: op not supported: {:?}", op)
+        },
+    }
+}
+
+fn lang_item_for_unop(tcx: TyCtxt<'_>, op: hir::UnOp) -> (Symbol, Option<hir::def_id::DefId>) {
+    let lang = tcx.lang_items();
+    match op {
+        hir::UnOp::Not => (sym::not, lang.not_trait()),
+        hir::UnOp::Neg => (sym::neg, lang.neg_trait()),
+        hir::UnOp::Deref => bug!("Deref is not overloadable"),
     }
 }
 
 // Binary operator categories. These categories summarize the behavior
 // with respect to the builtin operations supported.
+#[derive(Clone, Copy)]
 enum BinOpCategory {
     /// &&, || -- cannot be overridden
     Shortcircuit,
@@ -1063,44 +1062,58 @@ enum BinOpCategory {
     Comparison,
 }
 
-impl BinOpCategory {
-    fn from(op: hir::BinOp) -> BinOpCategory {
-        match op.node {
-            hir::BinOpKind::Shl | hir::BinOpKind::Shr => BinOpCategory::Shift,
-
-            hir::BinOpKind::Add
-            | hir::BinOpKind::Sub
-            | hir::BinOpKind::Mul
-            | hir::BinOpKind::Div
-            | hir::BinOpKind::Rem => BinOpCategory::Math,
-
-            hir::BinOpKind::BitXor | hir::BinOpKind::BitAnd | hir::BinOpKind::BitOr => {
-                BinOpCategory::Bitwise
-            }
-
-            hir::BinOpKind::Eq
-            | hir::BinOpKind::Ne
-            | hir::BinOpKind::Lt
-            | hir::BinOpKind::Le
-            | hir::BinOpKind::Ge
-            | hir::BinOpKind::Gt => BinOpCategory::Comparison,
+impl From<hir::BinOpKind> for BinOpCategory {
+    fn from(op: hir::BinOpKind) -> BinOpCategory {
+        use hir::BinOpKind::*;
+        match op {
+            Shl | Shr => BinOpCategory::Shift,
+            Add | Sub | Mul | Div | Rem => BinOpCategory::Math,
+            BitXor | BitAnd | BitOr => BinOpCategory::Bitwise,
+            Eq | Ne | Lt | Le | Ge | Gt => BinOpCategory::Comparison,
+            And | Or => BinOpCategory::Shortcircuit,
+        }
+    }
+}
 
-            hir::BinOpKind::And | hir::BinOpKind::Or => BinOpCategory::Shortcircuit,
+impl From<hir::AssignOpKind> for BinOpCategory {
+    fn from(op: hir::AssignOpKind) -> BinOpCategory {
+        use hir::AssignOpKind::*;
+        match op {
+            ShlAssign | ShrAssign => BinOpCategory::Shift,
+            AddAssign | SubAssign | MulAssign | DivAssign | RemAssign => BinOpCategory::Math,
+            BitXorAssign | BitAndAssign | BitOrAssign => BinOpCategory::Bitwise,
         }
     }
 }
 
-/// Whether the binary operation is an assignment (`a += b`), or not (`a + b`)
+/// An assignment op (e.g. `a += b`), or a binary op (e.g. `a + b`).
 #[derive(Clone, Copy, Debug, PartialEq)]
-enum IsAssign {
-    No,
-    Yes,
+enum Op {
+    BinOp(hir::BinOp),
+    AssignOp(hir::AssignOp),
 }
 
-#[derive(Clone, Copy, Debug)]
-enum Op {
-    Binary(hir::BinOp, IsAssign),
-    Unary(hir::UnOp, Span),
+impl Op {
+    fn span(&self) -> Span {
+        match self {
+            Op::BinOp(op) => op.span,
+            Op::AssignOp(op) => op.span,
+        }
+    }
+
+    fn as_str(&self) -> &'static str {
+        match self {
+            Op::BinOp(op) => op.node.as_str(),
+            Op::AssignOp(op) => op.node.as_str(),
+        }
+    }
+
+    fn is_by_value(&self) -> bool {
+        match self {
+            Op::BinOp(op) => op.node.is_by_value(),
+            Op::AssignOp(op) => op.node.is_by_value(),
+        }
+    }
 }
 
 /// Dereferences a single level of immutable referencing.
@@ -1127,27 +1140,24 @@ fn deref_ty_if_possible(ty: Ty<'_>) -> Ty<'_> {
 /// Reason #2 is the killer. I tried for a while to always use
 /// overloaded logic and just check the types in constants/codegen after
 /// the fact, and it worked fine, except for SIMD types. -nmatsakis
-fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool {
+fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, category: BinOpCategory) -> bool {
     // Special-case a single layer of referencing, so that things like `5.0 + &6.0f32` work.
     // (See https://github.com/rust-lang/rust/issues/57447.)
     let (lhs, rhs) = (deref_ty_if_possible(lhs), deref_ty_if_possible(rhs));
 
-    match BinOpCategory::from(op) {
+    match category.into() {
         BinOpCategory::Shortcircuit => true,
-
         BinOpCategory::Shift => {
             lhs.references_error()
                 || rhs.references_error()
                 || lhs.is_integral() && rhs.is_integral()
         }
-
         BinOpCategory::Math => {
             lhs.references_error()
                 || rhs.references_error()
                 || lhs.is_integral() && rhs.is_integral()
                 || lhs.is_floating_point() && rhs.is_floating_point()
         }
-
         BinOpCategory::Bitwise => {
             lhs.references_error()
                 || rhs.references_error()
@@ -1155,7 +1165,6 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool
                 || lhs.is_floating_point() && rhs.is_floating_point()
                 || lhs.is_bool() && rhs.is_bool()
         }
-
         BinOpCategory::Comparison => {
             lhs.references_error() || rhs.references_error() || lhs.is_scalar() && rhs.is_scalar()
         }
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index f1f956779c9..9766ceda569 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -632,10 +632,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             {
                 let tcx = self.tcx;
                 trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
-                self.typeck_results
-                    .borrow_mut()
-                    .treat_byte_string_as_slice
-                    .insert(lt.hir_id.local_id);
                 pat_ty =
                     Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, Ty::new_slice(tcx, tcx.types.u8));
             }
@@ -944,10 +940,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let var_ty = self.local_ty(span, var_id);
         if let Err(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
-            let hir = self.tcx.hir();
             let var_ty = self.resolve_vars_if_possible(var_ty);
             let msg = format!("first introduced with type `{var_ty}` here");
-            err.span_label(hir.span(var_id), msg);
+            err.span_label(self.tcx.hir_span(var_id), msg);
             let in_match = self.tcx.hir_parent_iter(var_id).any(|(_, n)| {
                 matches!(
                     n,
@@ -1255,7 +1250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 })) => 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);
+                            let span = self.tcx.hir_span(body_id.hir_id);
                             if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) {
                                 e.span_suggestion_verbose(
                                     ident.span,
@@ -1286,7 +1281,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat_ty: Ty<'tcx>,
         segments: &'tcx [hir::PathSegment<'tcx>],
     ) {
-        if let Some(span) = self.tcx.hir().res_span(pat_res) {
+        if let Some(span) = self.tcx.hir_res_span(pat_res) {
             e.span_label(span, format!("{} defined here", res.descr()));
             if let [hir::PathSegment { ident, .. }] = &*segments {
                 e.span_label(
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index fc98a603dd8..8ab71e5220b 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -18,12 +18,12 @@
 //! from there).
 //!
 //! The fact that we are inferring borrow kinds as we go results in a
-//! semi-hacky interaction with mem-categorization. In particular,
-//! mem-categorization will query the current borrow kind as it
-//! categorizes, and we'll return the *current* value, but this may get
+//! semi-hacky interaction with the way `ExprUseVisitor` is computing
+//! `Place`s. In particular, it will query the current borrow kind as it
+//! goes, and we'll return the *current* value, but this may get
 //! adjusted later. Therefore, in this module, we generally ignore the
-//! borrow kind (and derived mutabilities) that are returned from
-//! mem-categorization, since they may be inaccurate. (Another option
+//! borrow kind (and derived mutabilities) that `ExprUseVisitor` returns
+//! within `Place`s, since they may be inaccurate. (Another option
 //! would be to use a unification scheme, where instead of returning a
 //! concrete borrow kind like `ty::ImmBorrow`, we return a
 //! `ty::InferBorrow(upvar_id)` or something like that, but this would
@@ -85,7 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 /// Intermediate format to store the hir_id pointing to the use that resulted in the
 /// corresponding place being captured and a String which contains the captured value's
 /// name (i.e: a.b.c)
-#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 enum UpvarMigrationInfo {
     /// We previously captured all of `x`, but now we capture some sub-path.
     CapturingPrecise { source_expr: Option<HirId>, var_name: String },
@@ -635,7 +635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let (place, capture_kind) = truncate_capture_for_optimization(place, capture_kind);
 
                 let usage_span = if let Some(usage_expr) = capture_info.path_expr_id {
-                    self.tcx.hir().span(usage_expr)
+                    self.tcx.hir_span(usage_expr)
                 } else {
                     unreachable!()
                 };
@@ -986,7 +986,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         for lint_note in diagnostics_info.iter() {
                             match &lint_note.captures_info {
                                 UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => {
-                                    let cause_span = self.tcx.hir().span(*capture_expr_id);
+                                    let cause_span = self.tcx.hir_span(*capture_expr_id);
                                     lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`",
                                         self.tcx.hir_name(*var_hir_id),
                                         captured_name,
@@ -1047,13 +1047,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         "add a dummy let to cause {migrated_variables_concat} to be fully captured"
                     );
 
-                    let closure_span = self.tcx.hir().span_with_body(closure_hir_id);
+                    let closure_span = self.tcx.hir_span_with_body(closure_hir_id);
                     let mut closure_body_span = {
                         // If the body was entirely expanded from a macro
                         // invocation, i.e. the body is not contained inside the
                         // closure span, then we walk up the expansion until we
                         // find the span before the expansion.
-                        let s = self.tcx.hir().span_with_body(body_id.hir_id);
+                        let s = self.tcx.hir_span_with_body(body_id.hir_id);
                         s.find_ancestor_inside(closure_span).unwrap_or(s)
                     };
 
@@ -1396,14 +1396,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 FxIndexSet::default()
             };
 
-            // Combine all the captures responsible for needing migrations into one HashSet
+            // Combine all the captures responsible for needing migrations into one IndexSet
             let mut capture_diagnostic = drop_reorder_diagnostic.clone();
             for key in auto_trait_diagnostic.keys() {
                 capture_diagnostic.insert(key.clone());
             }
 
             let mut capture_diagnostic = capture_diagnostic.into_iter().collect::<Vec<_>>();
-            capture_diagnostic.sort();
+            capture_diagnostic.sort_by_cached_key(|info| match info {
+                UpvarMigrationInfo::CapturingPrecise { source_expr: _, var_name } => {
+                    (0, Some(var_name.clone()))
+                }
+                UpvarMigrationInfo::CapturingNothing { use_span: _ } => (1, None),
+            });
             for captures_info in capture_diagnostic {
                 // Get the auto trait reasons of why migration is needed because of that capture, if there are any
                 let capture_trait_reasons =
@@ -1752,8 +1757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let capture_str = construct_capture_info_string(self.tcx, place, capture_info);
                 let output_str = format!("Capturing {capture_str}");
 
-                let span =
-                    capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e));
+                let span = capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir_span(e));
                 diag.span_note(span, output_str);
             }
             diag.emit();
@@ -1780,10 +1784,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if capture.info.path_expr_id != capture.info.capture_kind_expr_id {
                             let path_span = capture_info
                                 .path_expr_id
-                                .map_or(closure_span, |e| self.tcx.hir().span(e));
+                                .map_or(closure_span, |e| self.tcx.hir_span(e));
                             let capture_kind_span = capture_info
                                 .capture_kind_expr_id
-                                .map_or(closure_span, |e| self.tcx.hir().span(e));
+                                .map_or(closure_span, |e| self.tcx.hir_span(e));
 
                             let mut multi_span: MultiSpan =
                                 MultiSpan::from_spans(vec![path_span, capture_kind_span]);
@@ -1799,7 +1803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         } else {
                             let span = capture_info
                                 .path_expr_id
-                                .map_or(closure_span, |e| self.tcx.hir().span(e));
+                                .map_or(closure_span, |e| self.tcx.hir_span(e));
 
                             diag.span_note(span, output_str);
                         };
@@ -1828,8 +1832,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut is_mutbl = bm.1;
 
         for pointer_ty in place.deref_tys() {
-            match self.structurally_resolve_type(self.tcx.hir().span(var_hir_id), pointer_ty).kind()
-            {
+            match self.structurally_resolve_type(self.tcx.hir_span(var_hir_id), pointer_ty).kind() {
                 // We don't capture derefs of raw ptrs
                 ty::RawPtr(_, _) => unreachable!(),
 
@@ -1844,7 +1847,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ty::Adt(def, ..) if def.is_box() => {}
 
                 unexpected_ty => span_bug!(
-                    self.tcx.hir().span(var_hir_id),
+                    self.tcx.hir_span(var_hir_id),
                     "deref of unexpected pointer type {:?}",
                     unexpected_ty
                 ),
@@ -1975,14 +1978,14 @@ fn drop_location_span(tcx: TyCtxt<'_>, hir_id: HirId) -> Span {
     let owner_node = tcx.hir_node(owner_id);
     let owner_span = match owner_node {
         hir::Node::Item(item) => match item.kind {
-            hir::ItemKind::Fn { body: owner_id, .. } => tcx.hir().span(owner_id.hir_id),
+            hir::ItemKind::Fn { body: owner_id, .. } => tcx.hir_span(owner_id.hir_id),
             _ => {
                 bug!("Drop location span error: need to handle more ItemKind '{:?}'", item.kind);
             }
         },
-        hir::Node::Block(block) => tcx.hir().span(block.hir_id),
-        hir::Node::TraitItem(item) => tcx.hir().span(item.hir_id()),
-        hir::Node::ImplItem(item) => tcx.hir().span(item.hir_id()),
+        hir::Node::Block(block) => tcx.hir_span(block.hir_id),
+        hir::Node::TraitItem(item) => tcx.hir_span(item.hir_id()),
+        hir::Node::ImplItem(item) => tcx.hir_span(item.hir_id()),
         _ => {
             bug!("Drop location span error: need to handle more Node '{:?}'", owner_node);
         }
@@ -2325,8 +2328,9 @@ fn should_do_rust_2021_incompatible_closure_captures_analysis(
         return false;
     }
 
-    let (level, _) =
-        tcx.lint_level_at_node(lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_id);
+    let level = tcx
+        .lint_level_at_node(lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_id)
+        .level;
 
     !matches!(level, lint::Level::Allow)
 }
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index b63c0b6ab7e..6ba7435cb79 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -12,10 +12,12 @@ use rustc_middle::span_bug;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, fold_regions,
+    self, DefiningScopeKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeVisitableExt, fold_regions,
 };
 use rustc_span::{Span, sym};
 use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
+use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid;
 use rustc_trait_selection::solve;
 use tracing::{debug, instrument};
 
@@ -81,9 +83,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
         wbcx.typeck_results.used_trait_imports = used_trait_imports;
 
-        wbcx.typeck_results.treat_byte_string_as_slice =
-            mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice);
-
         debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results);
 
         self.tcx.arena.alloc(wbcx.typeck_results)
@@ -160,7 +159,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                     self.typeck_results.node_args_mut().remove(e.hir_id);
                 }
             }
-            hir::ExprKind::Binary(ref op, lhs, rhs) | hir::ExprKind::AssignOp(ref op, lhs, rhs) => {
+            hir::ExprKind::Binary(ref op, lhs, rhs) => {
                 let lhs_ty = self.typeck_results.node_type(lhs.hir_id);
                 let rhs_ty = self.typeck_results.node_type(rhs.hir_id);
 
@@ -168,25 +167,27 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                     self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
                     self.typeck_results.node_args_mut().remove(e.hir_id);
 
-                    match e.kind {
-                        hir::ExprKind::Binary(..) => {
-                            if !op.node.is_by_value() {
-                                let mut adjustments = self.typeck_results.adjustments_mut();
-                                if let Some(a) = adjustments.get_mut(lhs.hir_id) {
-                                    a.pop();
-                                }
-                                if let Some(a) = adjustments.get_mut(rhs.hir_id) {
-                                    a.pop();
-                                }
-                            }
+                    if !op.node.is_by_value() {
+                        let mut adjustments = self.typeck_results.adjustments_mut();
+                        if let Some(a) = adjustments.get_mut(lhs.hir_id) {
+                            a.pop();
                         }
-                        hir::ExprKind::AssignOp(..)
-                            if let Some(a) =
-                                self.typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
-                        {
+                        if let Some(a) = adjustments.get_mut(rhs.hir_id) {
                             a.pop();
                         }
-                        _ => {}
+                    }
+                }
+            }
+            hir::ExprKind::AssignOp(_, lhs, rhs) => {
+                let lhs_ty = self.typeck_results.node_type(lhs.hir_id);
+                let rhs_ty = self.typeck_results.node_type(rhs.hir_id);
+
+                if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
+                    self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
+                    self.typeck_results.node_args_mut().remove(e.hir_id);
+
+                    if let Some(a) = self.typeck_results.adjustments_mut().get_mut(lhs.hir_id) {
+                        a.pop();
                     }
                 }
             }
@@ -491,7 +492,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
                 if let ty::UserTypeKind::TypeOf(_, user_args) = c_ty.value.kind {
                     // This is a unit-testing mechanism.
-                    let span = self.tcx().hir().span(hir_id);
+                    let span = self.tcx().hir_span(hir_id);
                     // We need to buffer the errors in order to guarantee a consistent
                     // order when emitting them.
                     let err =
@@ -556,6 +557,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     fn visit_opaque_types(&mut self) {
+        let tcx = self.tcx();
         // We clone the opaques instead of stealing them here as they are still used for
         // normalization in the next generation trait solver.
         //
@@ -578,16 +580,46 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 }
             }
 
-            // Here we only detect impl trait definition conflicts when they
-            // are equal modulo regions.
-            if let Some(last_opaque_ty) =
-                self.typeck_results.concrete_opaque_types.insert(opaque_type_key, hidden_type)
-                && last_opaque_ty.ty != hidden_type.ty
+            if let Err(guar) = check_opaque_type_parameter_valid(
+                &self.fcx,
+                opaque_type_key,
+                hidden_type.span,
+                DefiningScopeKind::HirTypeck,
+            ) {
+                self.typeck_results
+                    .concrete_opaque_types
+                    .insert(opaque_type_key.def_id, ty::OpaqueHiddenType::new_error(tcx, guar));
+            }
+
+            let hidden_type = hidden_type.remap_generic_params_to_declaration_params(
+                opaque_type_key,
+                tcx,
+                DefiningScopeKind::HirTypeck,
+            );
+
+            if let Some(prev) = self
+                .typeck_results
+                .concrete_opaque_types
+                .insert(opaque_type_key.def_id, hidden_type)
             {
-                assert!(!self.fcx.next_trait_solver());
-                if let Ok(d) = hidden_type.build_mismatch_error(&last_opaque_ty, self.tcx()) {
-                    d.emit();
+                let entry = &mut self
+                    .typeck_results
+                    .concrete_opaque_types
+                    .get_mut(&opaque_type_key.def_id)
+                    .unwrap();
+                if prev.ty != hidden_type.ty {
+                    if let Some(guar) = self.typeck_results.tainted_by_errors {
+                        entry.ty = Ty::new_error(tcx, guar);
+                    } else {
+                        let (Ok(guar) | Err(guar)) =
+                            prev.build_mismatch_error(&hidden_type, tcx).map(|d| d.emit());
+                        entry.ty = Ty::new_error(tcx, guar);
+                    }
                 }
+
+                // Pick a better span if there is one.
+                // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
+                entry.span = prev.span.substitute_dummy(hidden_type.span);
             }
         }
     }
@@ -775,7 +807,7 @@ impl Locatable for Span {
 
 impl Locatable for HirId {
     fn to_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.hir().span(*self)
+        tcx.hir_span(*self)
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index fa8dea064da..529e996ad1e 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -27,6 +27,7 @@ use rustc_middle::bug;
 use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues};
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::select;
+use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{
     self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs,
@@ -268,7 +269,7 @@ pub struct InferCtxt<'tcx> {
     /// The set of predicates on which errors have been reported, to
     /// avoid reporting the same error twice.
     pub reported_trait_errors:
-        RefCell<FxIndexMap<Span, (Vec<ty::Predicate<'tcx>>, ErrorGuaranteed)>>,
+        RefCell<FxIndexMap<Span, (Vec<Goal<'tcx, ty::Predicate<'tcx>>>, ErrorGuaranteed)>>,
 
     pub reported_signature_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
 
@@ -966,7 +967,8 @@ impl<'tcx> InferCtxt<'tcx> {
     pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
         debug_assert!(!self.next_trait_solver());
         match self.typing_mode() {
-            TypingMode::Analysis { defining_opaque_types } => {
+            TypingMode::Analysis { defining_opaque_types }
+            | TypingMode::Borrowck { defining_opaque_types } => {
                 id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id))
             }
             // FIXME(#132279): This function is quite weird in post-analysis
@@ -1260,7 +1262,8 @@ impl<'tcx> InferCtxt<'tcx> {
             // to handle them without proper canonicalization. This means we may cause cycle
             // errors and fail to reveal opaques while inside of bodies. We should rename this
             // function and require explicit comments on all use-sites in the future.
-            ty::TypingMode::Analysis { defining_opaque_types: _ } => {
+            ty::TypingMode::Analysis { defining_opaque_types: _ }
+            | ty::TypingMode::Borrowck { defining_opaque_types: _ } => {
                 TypingMode::non_body_analysis()
             }
             mode @ (ty::TypingMode::Coherence
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 215b1333726..ce5d2e6e17a 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::{
 use rustc_span::Span;
 use tracing::{debug, instrument};
 
-use super::DefineOpaqueTypes;
+use super::{DefineOpaqueTypes, RegionVariableOrigin};
 use crate::errors::OpaqueHiddenTypeDiag;
 use crate::infer::{InferCtxt, InferOk};
 use crate::traits::{self, Obligation, PredicateObligations};
@@ -198,13 +198,12 @@ impl<'tcx> InferCtxt<'tcx> {
     /// it hasn't previously been defined. This does not emit any
     /// constraints and it's the responsibility of the caller to make
     /// sure that the item bounds of the opaque are checked.
-    pub fn inject_new_hidden_type_unchecked(
+    pub fn register_hidden_type_in_storage(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
         hidden_ty: OpaqueHiddenType<'tcx>,
-    ) {
-        let prev = self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty);
-        assert_eq!(prev, None);
+    ) -> Option<Ty<'tcx>> {
+        self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty)
     }
 
     /// Insert a hidden type into the opaque type storage, equating it
@@ -222,6 +221,7 @@ impl<'tcx> InferCtxt<'tcx> {
         hidden_ty: Ty<'tcx>,
         goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
     ) -> Result<(), TypeError<'tcx>> {
+        let tcx = self.tcx;
         // Ideally, we'd get the span where *this specific `ty` came
         // from*, but right now we just use the span from the overall
         // value being folded. In simple cases like `-> impl Foo`,
@@ -232,7 +232,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 // During intercrate we do not define opaque types but instead always
                 // force ambiguity unless the hidden type is known to not implement
                 // our trait.
-                goals.push(Goal::new(self.tcx, param_env, ty::PredicateKind::Ambiguous));
+                goals.push(Goal::new(tcx, param_env, ty::PredicateKind::Ambiguous));
             }
             ty::TypingMode::Analysis { .. } => {
                 let prev = self
@@ -250,6 +250,36 @@ impl<'tcx> InferCtxt<'tcx> {
                     );
                 }
             }
+            ty::TypingMode::Borrowck { .. } => {
+                let prev = self
+                    .inner
+                    .borrow_mut()
+                    .opaque_types()
+                    .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
+
+                // We either equate the new hidden type with the previous entry or with the type
+                // inferred by HIR typeck.
+                let actual = prev.unwrap_or_else(|| {
+                    let actual = tcx
+                        .type_of_opaque_hir_typeck(opaque_type_key.def_id)
+                        .instantiate(self.tcx, opaque_type_key.args);
+                    let actual = ty::fold_regions(tcx, actual, |re, _dbi| match re.kind() {
+                        ty::ReErased => {
+                            self.next_region_var(RegionVariableOrigin::MiscVariable(span))
+                        }
+                        _ => re,
+                    });
+                    actual
+                });
+
+                goals.extend(
+                    self.at(&ObligationCause::dummy_with_span(span), param_env)
+                        .eq(DefineOpaqueTypes::Yes, hidden_ty, actual)?
+                        .obligations
+                        .into_iter()
+                        .map(|obligation| obligation.as_goal()),
+                );
+            }
             mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => {
                 bug!("insert hidden type in {mode:?}")
             }
diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl
index ffbe708ba8d..4b9c71d7172 100644
--- a/compiler/rustc_interface/messages.ftl
+++ b/compiler/rustc_interface/messages.ftl
@@ -50,11 +50,5 @@ interface_out_dir_error =
 interface_proc_macro_crate_panic_abort =
     building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
 
-interface_rustc_error_fatal =
-    fatal error triggered by #[rustc_error]
-
-interface_rustc_error_unexpected_annotation =
-    unexpected annotation used with `#[rustc_error(...)]`!
-
 interface_temps_dir_error =
     failed to find or create the directory specified by `--temps-dir`
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
index ef0235b5577..6b39b4f1891 100644
--- a/compiler/rustc_interface/src/errors.rs
+++ b/compiler/rustc_interface/src/errors.rs
@@ -74,20 +74,6 @@ pub struct TempsDirError;
 pub struct OutDirError;
 
 #[derive(Diagnostic)]
-#[diag(interface_rustc_error_fatal)]
-pub struct RustcErrorFatal {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(interface_rustc_error_unexpected_annotation)]
-pub struct RustcErrorUnexpectedAnnotation {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(interface_failed_writing_file)]
 pub struct FailedWritingFile<'a> {
     pub path: &'a Path,
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 3f87b1a547b..33b4a48b28d 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -204,6 +204,14 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch
                     error!("`cfg()` names cannot be after values");
                 }
                 names.push(ident);
+            } else if let Some(boolean) = arg.boolean_literal() {
+                if values_specified {
+                    error!("`cfg()` names cannot be after values");
+                }
+                names.push(rustc_span::Ident::new(
+                    if boolean { rustc_span::kw::True } else { rustc_span::kw::False },
+                    arg.span(),
+                ));
             } else if arg.has_name(sym::any)
                 && let Some(args) = arg.meta_item_list()
             {
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 2440f0639c8..747e36b6a1a 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -976,7 +976,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
         tcx.par_hir_body_owners(|def_id| {
             if tcx.is_coroutine(def_id.to_def_id()) {
                 tcx.ensure_ok().mir_coroutine_witnesses(def_id);
-                tcx.ensure_ok().check_coroutine_obligations(
+                let _ = tcx.ensure_ok().check_coroutine_obligations(
                     tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(),
                 );
                 // Eagerly check the unsubstituted layout for cycles.
@@ -1067,48 +1067,18 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
     });
 }
 
-/// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used
-/// to write UI tests that actually test that compilation succeeds without reporting
-/// an error.
-fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
-    let Some((def_id, _)) = tcx.entry_fn(()) else { return };
-    for attr in tcx.get_attrs(def_id, sym::rustc_error) {
-        match attr.meta_item_list() {
-            // Check if there is a `#[rustc_error(delayed_bug_from_inside_query)]`.
-            Some(list)
-                if list.iter().any(|list_item| {
-                    matches!(
-                        list_item.ident().map(|i| i.name),
-                        Some(sym::delayed_bug_from_inside_query)
-                    )
-                }) =>
-            {
-                tcx.ensure_ok().trigger_delayed_bug(def_id);
-            }
-
-            // Bare `#[rustc_error]`.
-            None => {
-                tcx.dcx().emit_fatal(errors::RustcErrorFatal { span: tcx.def_span(def_id) });
-            }
-
-            // Some other attribute.
-            Some(_) => {
-                tcx.dcx().emit_warn(errors::RustcErrorUnexpectedAnnotation {
-                    span: tcx.def_span(def_id),
-                });
-            }
-        }
-    }
-}
-
 /// Runs the codegen backend, after which the AST and analysis can
 /// be discarded.
 pub(crate) fn start_codegen<'tcx>(
     codegen_backend: &dyn CodegenBackend,
     tcx: TyCtxt<'tcx>,
 ) -> Box<dyn Any> {
-    // Hook for UI tests.
-    check_for_rustc_errors_attr(tcx);
+    // Hook for tests.
+    if let Some((def_id, _)) = tcx.entry_fn(())
+        && tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query)
+    {
+        tcx.ensure_ok().trigger_delayed_bug(def_id);
+    }
 
     // Don't run this test assertions when not doing codegen. Compiletest tries to build
     // build-fail tests in check mode first and expects it to not give an error in that case.
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index b44be1710ed..a8e55663257 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -787,6 +787,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(direct_access_external_data, Some(true));
     tracked!(dual_proc_macros, true);
     tracked!(dwarf_version, Some(5));
+    tracked!(embed_metadata, false);
     tracked!(embed_source, true);
     tracked!(emit_thin_lto, false);
     tracked!(emscripten_wasm_eh, true);
@@ -852,6 +853,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(sanitizer_cfi_generalize_pointers, Some(true));
     tracked!(sanitizer_cfi_normalize_integers, Some(true));
     tracked!(sanitizer_dataflow_abilist, vec![String::from("/rustc/abc")]);
+    tracked!(sanitizer_kcfi_arity, Some(true));
     tracked!(sanitizer_memory_track_origins, 2);
     tracked!(sanitizer_recover, SanitizerSet::ADDRESS);
     tracked!(saturating_float_casts, Some(true));
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 0a3eb434d3f..782d328a951 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -456,6 +456,10 @@ lint_invalid_nan_comparisons_eq_ne = incorrect NaN comparison, NaN cannot be dir
 
 lint_invalid_nan_comparisons_lt_le_gt_ge = incorrect NaN comparison, NaN is not orderable
 
+lint_invalid_null_arguments = calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+    .origin = null pointer originates from here
+    .doc = for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
 lint_invalid_reference_casting_assign_to_ref = assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
     .label = casting happened here
 
@@ -680,15 +684,6 @@ lint_private_extern_crate_reexport = extern crate `{$ident}` is private and cann
 lint_proc_macro_derive_resolution_fallback = cannot find {$ns} `{$ident}` in this scope
     .label = names from parent modules are not accessible without an explicit import
 
-lint_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false
-    .help = wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
-    .label = expression has type `{$orig_ty}`
-
-lint_ptr_null_checks_fn_ret = returned pointer of `{$fn_name}` call is never null, so checking it for null will always return false
-
-lint_ptr_null_checks_ref = references are not nullable, so checking them for null will always return false
-    .label = expression has type `{$orig_ty}`
-
 lint_query_instability = using `{$query}` can result in unstable query results
     .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
@@ -981,6 +976,15 @@ lint_unused_result = unused result of type `{$ty}`
 
 lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result
 
+lint_useless_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false
+    .help = wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
+    .label = expression has type `{$orig_ty}`
+
+lint_useless_ptr_null_checks_fn_ret = returned pointer of `{$fn_name}` call is never null, so checking it for null will always return false
+
+lint_useless_ptr_null_checks_ref = references are not nullable, so checking them for null will always return false
+    .label = expression has type `{$orig_ty}`
+
 lint_uses_power_alignment = repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
 
 lint_variant_size_differences =
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 9dccd4a0552..dae0efcbbc4 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -29,6 +29,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
 use rustc_hir::intravisit::FnKind as HirFnKind;
 use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
 use rustc_middle::bug;
+use rustc_middle::lint::LevelAndSource;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
@@ -330,7 +331,6 @@ impl EarlyLintPass for UnsafeCode {
         if let FnKind::Fn(
             ctxt,
             _,
-            _,
             ast::Fn {
                 sig: ast::FnSig { header: ast::FnHeader { safety: ast::Safety::Unsafe(_), .. }, .. },
                 body,
@@ -695,7 +695,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
         }
 
         // Avoid listing trait impls if the trait is allowed.
-        let (level, _) = cx.tcx.lint_level_at_node(MISSING_DEBUG_IMPLEMENTATIONS, item.hir_id());
+        let LevelAndSource { level, .. } =
+            cx.tcx.lint_level_at_node(MISSING_DEBUG_IMPLEMENTATIONS, item.hir_id());
         if level == Level::Allow {
             return;
         }
@@ -3116,6 +3117,7 @@ impl EarlyLintPass for SpecialModuleName {
         for item in &krate.items {
             if let ast::ItemKind::Mod(
                 _,
+                ident,
                 ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _, _),
             ) = item.kind
             {
@@ -3123,7 +3125,7 @@ impl EarlyLintPass for SpecialModuleName {
                     continue;
                 }
 
-                match item.ident.name.as_str() {
+                match ident.name.as_str() {
                     "lib" => cx.emit_span_lint(
                         SPECIAL_MODULE_NAME,
                         item.span,
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 017ae943e91..885a7308bdc 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -17,13 +17,12 @@ use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_hir::{Pat, PatKind};
 use rustc_middle::bug;
+use rustc_middle::lint::LevelAndSource;
 use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
 use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
-use rustc_session::lint::{
-    FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
-};
+use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintBuffer, LintExpectationId, LintId};
 use rustc_session::{LintStoreMarker, Session};
 use rustc_span::edit_distance::find_best_match_for_names;
 use rustc_span::{Ident, Span, Symbol, sym};
@@ -573,7 +572,7 @@ pub trait LintContext {
     }
 
     /// This returns the lint level for the given lint at the current location.
-    fn get_lint_level(&self, lint: &'static Lint) -> Level;
+    fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource;
 
     /// This function can be used to manually fulfill an expectation. This can
     /// be used for lints which contain several spans, and should be suppressed,
@@ -642,8 +641,8 @@ impl<'tcx> LintContext for LateContext<'tcx> {
         }
     }
 
-    fn get_lint_level(&self, lint: &'static Lint) -> Level {
-        self.tcx.lint_level_at_node(lint, self.last_node_with_lint_attrs).0
+    fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource {
+        self.tcx.lint_level_at_node(lint, self.last_node_with_lint_attrs)
     }
 }
 
@@ -663,8 +662,8 @@ impl LintContext for EarlyContext<'_> {
         self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorate)
     }
 
-    fn get_lint_level(&self, lint: &'static Lint) -> Level {
-        self.builder.lint_level(lint).0
+    fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource {
+        self.builder.lint_level(lint)
     }
 }
 
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index c2404a7b843..26481b97076 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -392,7 +392,7 @@ where
                         }
                         _ => {
                             self.tcx.dcx().span_delayed_bug(
-                                self.tcx.hir().span(arg.hir_id()),
+                                self.tcx.hir_span(arg.hir_id()),
                                 "no valid for captured arg",
                             );
                         }
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 8718fb807ec..f1fe07cfcfa 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -84,10 +84,10 @@ impl LintLevelSets {
     ) -> LevelAndSource {
         let lint = LintId::of(lint);
         let (level, mut src) = self.raw_lint_id_level(lint, idx, aux);
-        let level = reveal_actual_level(level, &mut src, sess, lint, |id| {
+        let (level, lint_id) = reveal_actual_level(level, &mut src, sess, lint, |id| {
             self.raw_lint_id_level(id, idx, aux)
         });
-        (level, src)
+        LevelAndSource { level, lint_id, src }
     }
 
     fn raw_lint_id_level(
@@ -95,17 +95,17 @@ impl LintLevelSets {
         id: LintId,
         mut idx: LintStackIndex,
         aux: Option<&FxIndexMap<LintId, LevelAndSource>>,
-    ) -> (Option<Level>, LintLevelSource) {
+    ) -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource) {
         if let Some(specs) = aux
-            && let Some(&(level, src)) = specs.get(&id)
+            && let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id)
         {
-            return (Some(level), src);
+            return (Some((level, lint_id)), src);
         }
 
         loop {
             let LintSet { ref specs, parent } = self.list[idx];
-            if let Some(&(level, src)) = specs.get(&id) {
-                return (Some(level), src);
+            if let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id) {
+                return (Some((level, lint_id)), src);
             }
             if idx == COMMAND_LINE {
                 return (None, LintLevelSource::Default);
@@ -131,8 +131,8 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LintId> {
         })
         .filter_map(|lint| {
             let lint_level = map.lint_level_id_at_node(tcx, LintId::of(lint), CRATE_HIR_ID);
-            if matches!(lint_level, (Level::Allow, ..))
-                || (matches!(lint_level, (.., LintLevelSource::Default)))
+            if matches!(lint_level.level, Level::Allow)
+                || (matches!(lint_level.src, LintLevelSource::Default))
                     && lint.default_level(tcx.sess.edition()) == Level::Allow
             {
                 Some(LintId::of(lint))
@@ -379,13 +379,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> {
     fn visit_attribute(&mut self, attribute: &'tcx hir::Attribute) {
         if matches!(
             Level::from_attr(attribute),
-            Some(
-                Level::Warn
-                    | Level::Deny
-                    | Level::Forbid
-                    | Level::Expect(..)
-                    | Level::ForceWarn(..),
-            )
+            Some((Level::Warn | Level::Deny | Level::Forbid | Level::Expect | Level::ForceWarn, _))
         ) {
             let store = unerased_lint_store(self.tcx.sess);
             // Lint attributes are always a metalist inside a
@@ -450,6 +444,19 @@ impl<'s> LintLevelsBuilder<'s, TopDown> {
         builder
     }
 
+    pub fn crate_root(
+        sess: &'s Session,
+        features: &'s Features,
+        lint_added_lints: bool,
+        store: &'s LintStore,
+        registered_tools: &'s RegisteredTools,
+        crate_attrs: &[ast::Attribute],
+    ) -> Self {
+        let mut builder = Self::new(sess, features, lint_added_lints, store, registered_tools);
+        builder.add(crate_attrs, true, None);
+        builder
+    }
+
     fn process_command_line(&mut self) {
         self.provider.cur = self
             .provider
@@ -528,9 +535,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         for &(ref lint_name, level) in &self.sess.opts.lint_opts {
             // Checks the validity of lint names derived from the command line.
             let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name);
-            if lint_name_only == crate::WARNINGS.name_lower()
-                && matches!(level, Level::ForceWarn(_))
-            {
+            if lint_name_only == crate::WARNINGS.name_lower() && matches!(level, Level::ForceWarn) {
                 self.sess
                     .dcx()
                     .emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() });
@@ -573,7 +578,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                 _ => {}
             };
 
-            let orig_level = level;
             let lint_flag_val = Symbol::intern(lint_name);
 
             let Ok(ids) = self.store.find_lints(lint_name) else {
@@ -582,15 +586,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
             };
             for id in ids {
                 // ForceWarn and Forbid cannot be overridden
-                if let Some((Level::ForceWarn(_) | Level::Forbid, _)) =
+                if let Some(LevelAndSource { level: Level::ForceWarn | Level::Forbid, .. }) =
                     self.current_specs().get(&id)
                 {
                     continue;
                 }
 
                 if self.check_gated_lint(id, DUMMY_SP, true) {
-                    let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
-                    self.insert(id, (level, src));
+                    let src = LintLevelSource::CommandLine(lint_flag_val, level);
+                    self.insert(id, LevelAndSource { level, lint_id: None, src });
                 }
             }
         }
@@ -599,8 +603,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful
     /// (e.g. if a forbid was already inserted on the same scope), then emits a
     /// diagnostic with no change to `specs`.
-    fn insert_spec(&mut self, id: LintId, (level, src): LevelAndSource) {
-        let (old_level, old_src) = self.provider.get_lint_level(id.lint, self.sess);
+    fn insert_spec(&mut self, id: LintId, LevelAndSource { level, lint_id, src }: LevelAndSource) {
+        let LevelAndSource { level: old_level, src: old_src, .. } =
+            self.provider.get_lint_level(id.lint, self.sess);
 
         // Setting to a non-forbid level is an error if the lint previously had
         // a forbid level. Note that this is not necessarily true even with a
@@ -672,7 +677,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         // The lint `unfulfilled_lint_expectations` can't be expected, as it would suppress itself.
         // Handling expectations of this lint would add additional complexity with little to no
         // benefit. The expect level for this lint will therefore be ignored.
-        if let Level::Expect(_) = level
+        if let Level::Expect = level
             && id == LintId::of(UNFULFILLED_LINT_EXPECTATIONS)
         {
             return;
@@ -680,13 +685,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
 
         match (old_level, level) {
             // If the new level is an expectation store it in `ForceWarn`
-            (Level::ForceWarn(_), Level::Expect(expectation_id)) => {
-                self.insert(id, (Level::ForceWarn(Some(expectation_id)), old_src))
+            (Level::ForceWarn, Level::Expect) => {
+                self.insert(id, LevelAndSource { level: Level::ForceWarn, lint_id, src: old_src })
             }
             // Keep `ForceWarn` level but drop the expectation
-            (Level::ForceWarn(_), _) => self.insert(id, (Level::ForceWarn(None), old_src)),
+            (Level::ForceWarn, _) => self.insert(
+                id,
+                LevelAndSource { level: Level::ForceWarn, lint_id: None, src: old_src },
+            ),
             // Set the lint level as normal
-            _ => self.insert(id, (level, src)),
+            _ => self.insert(id, LevelAndSource { level, lint_id, src }),
         };
     }
 
@@ -701,7 +709,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
             if attr.has_name(sym::automatically_derived) {
                 self.insert(
                     LintId::of(SINGLE_USE_LIFETIMES),
-                    (Level::Allow, LintLevelSource::Default),
+                    LevelAndSource {
+                        level: Level::Allow,
+                        lint_id: None,
+                        src: LintLevelSource::Default,
+                    },
                 );
                 continue;
             }
@@ -712,15 +724,22 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                     .meta_item_list()
                     .is_some_and(|l| ast::attr::list_contains_name(&l, sym::hidden))
             {
-                self.insert(LintId::of(MISSING_DOCS), (Level::Allow, LintLevelSource::Default));
+                self.insert(
+                    LintId::of(MISSING_DOCS),
+                    LevelAndSource {
+                        level: Level::Allow,
+                        lint_id: None,
+                        src: LintLevelSource::Default,
+                    },
+                );
                 continue;
             }
 
-            let level = match Level::from_attr(attr) {
+            let (level, lint_id) = match Level::from_attr(attr) {
                 None => continue,
                 // This is the only lint level with a `LintExpectationId` that can be created from
                 // an attribute.
-                Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => {
+                Some((Level::Expect, Some(unstable_id))) if let Some(hir_id) = source_hir_id => {
                     let LintExpectationId::Unstable { lint_index: None, attr_id: _ } = unstable_id
                     else {
                         bug!("stable id Level::from_attr")
@@ -732,9 +751,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                         lint_index: None,
                     };
 
-                    Level::Expect(stable_id)
+                    (Level::Expect, Some(stable_id))
                 }
-                Some(lvl) => lvl,
+                Some((lvl, id)) => (lvl, id),
             };
 
             let Some(mut metas) = attr.meta_item_list() else { continue };
@@ -782,13 +801,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
             }
 
             for (lint_index, li) in metas.iter_mut().enumerate() {
-                let level = match level {
-                    Level::Expect(mut id) => {
-                        id.set_lint_index(Some(lint_index as u16));
-                        Level::Expect(id)
-                    }
-                    level => level,
-                };
+                let mut lint_id = lint_id;
+                if let Some(id) = &mut lint_id {
+                    id.set_lint_index(Some(lint_index as u16));
+                }
 
                 let sp = li.span();
                 let meta_item = match li {
@@ -920,7 +936,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                 let src = LintLevelSource::Node { name, span: sp, reason };
                 for &id in ids {
                     if self.check_gated_lint(id, sp, false) {
-                        self.insert_spec(id, (level, src));
+                        self.insert_spec(id, LevelAndSource { level, lint_id, src });
                     }
                 }
 
@@ -929,7 +945,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                 // overriding the lint level but instead add an expectation that can't be
                 // fulfilled. The lint message will include an explanation, that the
                 // `unfulfilled_lint_expectations` lint can't be expected.
-                if let Level::Expect(expect_id) = level {
+                if let (Level::Expect, Some(expect_id)) = (level, lint_id) {
                     // The `unfulfilled_lint_expectations` lint is not part of any lint
                     // groups. Therefore. we only need to check the slice if it contains a
                     // single lint.
@@ -951,7 +967,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         }
 
         if self.lint_added_lints && !is_crate_node {
-            for (id, &(level, ref src)) in self.current_specs().iter() {
+            for (id, &LevelAndSource { level, ref src, .. }) in self.current_specs().iter() {
                 if !id.lint.crate_level_only {
                     continue;
                 }
@@ -989,10 +1005,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
 
         if self.lint_added_lints {
             let lint = builtin::UNKNOWN_LINTS;
-            let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
+            let level = self.lint_level(builtin::UNKNOWN_LINTS);
             // FIXME: make this translatable
             #[allow(rustc::diagnostic_outside_of_impl)]
-            lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
+            lint_level(self.sess, lint, level, Some(span.into()), |lint| {
                 lint.primary_message(fluent::lint_unknown_gated_lint);
                 lint.arg("name", lint_id.lint.name_lower());
                 lint.note(fluent::lint_note);
@@ -1027,8 +1043,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         span: Option<MultiSpan>,
         decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
     ) {
-        let (level, src) = self.lint_level(lint);
-        lint_level(self.sess, lint, level, src, span, decorate)
+        let level = self.lint_level(lint);
+        lint_level(self.sess, lint, level, span, decorate)
     }
 
     #[track_caller]
@@ -1038,16 +1054,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         span: MultiSpan,
         decorate: impl for<'a> LintDiagnostic<'a, ()>,
     ) {
-        let (level, src) = self.lint_level(lint);
-        lint_level(self.sess, lint, level, src, Some(span), |lint| {
+        let level = self.lint_level(lint);
+        lint_level(self.sess, lint, level, Some(span), |lint| {
             decorate.decorate_lint(lint);
         });
     }
 
     #[track_caller]
     pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) {
-        let (level, src) = self.lint_level(lint);
-        lint_level(self.sess, lint, level, src, None, |lint| {
+        let level = self.lint_level(lint);
+        lint_level(self.sess, lint, level, None, |lint| {
             decorate.decorate_lint(lint);
         });
     }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index cd474f1b7db..9b5c564d332 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -80,6 +80,7 @@ mod types;
 mod unit_bindings;
 mod unqualified_local_imports;
 mod unused;
+mod utils;
 
 use async_closures::AsyncClosureUsage;
 use async_fn_in_trait::AsyncFnInTrait;
@@ -129,6 +130,7 @@ pub use context::{
 };
 pub use early::{EarlyCheckNode, check_ast_node};
 pub use late::{check_crate, late_lint_mod, unerased_lint_store};
+pub use levels::LintLevelsBuilder;
 pub use passes::{EarlyLintPass, LateLintPass};
 pub use rustc_session::lint::Level::{self, *};
 pub use rustc_session::lint::{
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 036d68d13fa..55d010e6d34 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -591,24 +591,40 @@ pub(crate) struct ExpectationNote {
 
 // ptr_nulls.rs
 #[derive(LintDiagnostic)]
-pub(crate) enum PtrNullChecksDiag<'a> {
-    #[diag(lint_ptr_null_checks_fn_ptr)]
-    #[help(lint_help)]
+pub(crate) enum UselessPtrNullChecksDiag<'a> {
+    #[diag(lint_useless_ptr_null_checks_fn_ptr)]
+    #[help]
     FnPtr {
         orig_ty: Ty<'a>,
         #[label]
         label: Span,
     },
-    #[diag(lint_ptr_null_checks_ref)]
+    #[diag(lint_useless_ptr_null_checks_ref)]
     Ref {
         orig_ty: Ty<'a>,
         #[label]
         label: Span,
     },
-    #[diag(lint_ptr_null_checks_fn_ret)]
+    #[diag(lint_useless_ptr_null_checks_fn_ret)]
     FnRet { fn_name: Ident },
 }
 
+#[derive(LintDiagnostic)]
+pub(crate) enum InvalidNullArgumentsDiag {
+    #[diag(lint_invalid_null_arguments)]
+    #[help(lint_doc)]
+    NullPtrInline {
+        #[label(lint_origin)]
+        null_span: Span,
+    },
+    #[diag(lint_invalid_null_arguments)]
+    #[help(lint_doc)]
+    NullPtrThroughBinding {
+        #[note(lint_origin)]
+        null_span: Span,
+    },
+}
+
 // for_loops_over_fallibles.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_for_loops_over_fallibles)]
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index 66e207a451e..9c11fb41aa6 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -159,12 +159,13 @@ impl EarlyLintPass for NonAsciiIdents {
         use rustc_span::Span;
         use unicode_security::GeneralSecurityProfile;
 
-        let check_non_ascii_idents = cx.builder.lint_level(NON_ASCII_IDENTS).0 != Level::Allow;
+        let check_non_ascii_idents = cx.builder.lint_level(NON_ASCII_IDENTS).level != Level::Allow;
         let check_uncommon_codepoints =
-            cx.builder.lint_level(UNCOMMON_CODEPOINTS).0 != Level::Allow;
-        let check_confusable_idents = cx.builder.lint_level(CONFUSABLE_IDENTS).0 != Level::Allow;
+            cx.builder.lint_level(UNCOMMON_CODEPOINTS).level != Level::Allow;
+        let check_confusable_idents =
+            cx.builder.lint_level(CONFUSABLE_IDENTS).level != Level::Allow;
         let check_mixed_script_confusables =
-            cx.builder.lint_level(MIXED_SCRIPT_CONFUSABLES).0 != Level::Allow;
+            cx.builder.lint_level(MIXED_SCRIPT_CONFUSABLES).level != Level::Allow;
 
         if !check_non_ascii_idents
             && !check_uncommon_codepoints
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 752636ccaf0..df567e80e55 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -172,20 +172,22 @@ impl EarlyLintPass for NonCamelCaseTypes {
         }
 
         match &it.kind {
-            ast::ItemKind::TyAlias(..)
-            | ast::ItemKind::Enum(..)
-            | ast::ItemKind::Struct(..)
-            | ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident),
-            ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident),
-            ast::ItemKind::TraitAlias(..) => self.check_case(cx, "trait alias", &it.ident),
+            ast::ItemKind::TyAlias(box ast::TyAlias { ident, .. })
+            | ast::ItemKind::Enum(ident, ..)
+            | ast::ItemKind::Struct(ident, ..)
+            | ast::ItemKind::Union(ident, ..) => self.check_case(cx, "type", ident),
+            ast::ItemKind::Trait(box ast::Trait { ident, .. }) => {
+                self.check_case(cx, "trait", ident)
+            }
+            ast::ItemKind::TraitAlias(ident, _, _) => self.check_case(cx, "trait alias", ident),
 
             // N.B. This check is only for inherent associated types, so that we don't lint against
             // trait impls where we should have warned for the trait definition already.
             ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => {
                 for it in items {
                     // FIXME: this doesn't respect `#[allow(..)]` on the item itself.
-                    if let ast::AssocItemKind::Type(..) = it.kind {
-                        self.check_case(cx, "associated type", &it.ident);
+                    if let ast::AssocItemKind::Type(alias) = &it.kind {
+                        self.check_case(cx, "associated type", &alias.ident);
                     }
                 }
             }
@@ -194,8 +196,8 @@ impl EarlyLintPass for NonCamelCaseTypes {
     }
 
     fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
-        if let ast::AssocItemKind::Type(..) = it.kind {
-            self.check_case(cx, "associated type", &it.ident);
+        if let ast::AssocItemKind::Type(alias) = &it.kind {
+            self.check_case(cx, "associated type", &alias.ident);
         }
     }
 
diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs
index 1489f9de819..826bce2c315 100644
--- a/compiler/rustc_lint/src/ptr_nulls.rs
+++ b/compiler/rustc_lint/src/ptr_nulls.rs
@@ -1,9 +1,11 @@
 use rustc_ast::LitKind;
 use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind};
+use rustc_middle::ty::RawPtr;
 use rustc_session::{declare_lint, declare_lint_pass};
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 
-use crate::lints::PtrNullChecksDiag;
+use crate::lints::{InvalidNullArgumentsDiag, UselessPtrNullChecksDiag};
+use crate::utils::peel_casts;
 use crate::{LateContext, LateLintPass, LintContext};
 
 declare_lint! {
@@ -31,17 +33,40 @@ declare_lint! {
     "useless checking of non-null-typed pointer"
 }
 
-declare_lint_pass!(PtrNullChecks => [USELESS_PTR_NULL_CHECKS]);
+declare_lint! {
+    /// The `invalid_null_arguments` lint checks for invalid usage of null pointers in arguments.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// # use std::{slice, ptr};
+    /// // Undefined behavior
+    /// # let _slice: &[u8] =
+    /// unsafe { slice::from_raw_parts(ptr::null(), 0) };
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Calling methods whos safety invariants requires non-null ptr with a null pointer
+    /// is [Undefined Behavior](https://doc.rust-lang.org/reference/behavior-considered-undefined.html)!
+    INVALID_NULL_ARGUMENTS,
+    Deny,
+    "invalid null pointer in arguments"
+}
+
+declare_lint_pass!(PtrNullChecks => [USELESS_PTR_NULL_CHECKS, INVALID_NULL_ARGUMENTS]);
 
 /// This function checks if the expression is from a series of consecutive casts,
 /// ie. `(my_fn as *const _ as *mut _).cast_mut()` and whether the original expression is either
 /// a fn ptr, a reference, or a function call whose definition is
 /// annotated with `#![rustc_never_returns_null_ptr]`.
 /// If this situation is present, the function returns the appropriate diagnostic.
-fn incorrect_check<'a, 'tcx: 'a>(
+fn useless_check<'a, 'tcx: 'a>(
     cx: &'a LateContext<'tcx>,
     mut e: &'a Expr<'a>,
-) -> Option<PtrNullChecksDiag<'tcx>> {
+) -> Option<UselessPtrNullChecksDiag<'tcx>> {
     let mut had_at_least_one_cast = false;
     loop {
         e = e.peel_blocks();
@@ -50,14 +75,14 @@ fn incorrect_check<'a, 'tcx: 'a>(
             && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr)
             && let Some(fn_name) = cx.tcx.opt_item_ident(def_id)
         {
-            return Some(PtrNullChecksDiag::FnRet { fn_name });
+            return Some(UselessPtrNullChecksDiag::FnRet { fn_name });
         } else if let ExprKind::Call(path, _args) = e.kind
             && let ExprKind::Path(ref qpath) = path.kind
             && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
             && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr)
             && let Some(fn_name) = cx.tcx.opt_item_ident(def_id)
         {
-            return Some(PtrNullChecksDiag::FnRet { fn_name });
+            return Some(UselessPtrNullChecksDiag::FnRet { fn_name });
         }
         e = if let ExprKind::Cast(expr, t) = e.kind
             && let TyKind::Ptr(_) = t.kind
@@ -73,9 +98,9 @@ fn incorrect_check<'a, 'tcx: 'a>(
         } else if had_at_least_one_cast {
             let orig_ty = cx.typeck_results().expr_ty(e);
             return if orig_ty.is_fn() {
-                Some(PtrNullChecksDiag::FnPtr { orig_ty, label: e.span })
+                Some(UselessPtrNullChecksDiag::FnPtr { orig_ty, label: e.span })
             } else if orig_ty.is_ref() {
-                Some(PtrNullChecksDiag::Ref { orig_ty, label: e.span })
+                Some(UselessPtrNullChecksDiag::Ref { orig_ty, label: e.span })
             } else {
                 None
             };
@@ -85,6 +110,25 @@ fn incorrect_check<'a, 'tcx: 'a>(
     }
 }
 
+/// Checks if the given expression is a null pointer (modulo casting)
+fn is_null_ptr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<Span> {
+    let (expr, _) = peel_casts(cx, expr);
+
+    if let ExprKind::Call(path, []) = expr.kind
+        && let ExprKind::Path(ref qpath) = path.kind
+        && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+        && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
+    {
+        (diag_item == sym::ptr_null || diag_item == sym::ptr_null_mut).then_some(expr.span)
+    } else if let ExprKind::Lit(spanned) = expr.kind
+        && let LitKind::Int(v, _) = spanned.node
+    {
+        (v == 0).then_some(expr.span)
+    } else {
+        None
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         match expr.kind {
@@ -97,12 +141,68 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
                         cx.tcx.get_diagnostic_name(def_id),
                         Some(sym::ptr_const_is_null | sym::ptr_is_null)
                     )
-                    && let Some(diag) = incorrect_check(cx, arg) =>
+                    && let Some(diag) = useless_check(cx, arg) =>
             {
                 cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
             }
 
             // Catching:
+            // <path>(arg...) where `arg` is null-ptr and `path` is a fn that expect non-null-ptr
+            ExprKind::Call(path, args)
+                if let ExprKind::Path(ref qpath) = path.kind
+                    && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+                    && let Some(diag_name) = cx.tcx.get_diagnostic_name(def_id) =>
+            {
+                // `arg` positions where null would cause U.B and whenever ZST are allowed.
+                //
+                // We should probably have a `rustc` attribute, but checking them is costly,
+                // maybe if we checked for null ptr first, it would be acceptable?
+                let (arg_indices, are_zsts_allowed): (&[_], _) = match diag_name {
+                    sym::ptr_read
+                    | sym::ptr_read_unaligned
+                    | sym::ptr_read_volatile
+                    | sym::ptr_replace
+                    | sym::ptr_write
+                    | sym::ptr_write_bytes
+                    | sym::ptr_write_unaligned
+                    | sym::ptr_write_volatile => (&[0], true),
+                    sym::slice_from_raw_parts | sym::slice_from_raw_parts_mut => (&[0], false),
+                    sym::ptr_copy
+                    | sym::ptr_copy_nonoverlapping
+                    | sym::ptr_swap
+                    | sym::ptr_swap_nonoverlapping => (&[0, 1], true),
+                    _ => return,
+                };
+
+                for &arg_idx in arg_indices {
+                    if let Some(arg) = args.get(arg_idx)
+                        && let Some(null_span) = is_null_ptr(cx, arg)
+                        && let Some(ty) = cx.typeck_results().expr_ty_opt(arg)
+                        && let RawPtr(ty, _mutbl) = ty.kind()
+                    {
+                        // If ZST are fine, don't lint on them
+                        let typing_env = cx.typing_env();
+                        if are_zsts_allowed
+                            && cx
+                                .tcx
+                                .layout_of(typing_env.as_query_input(*ty))
+                                .is_ok_and(|layout| layout.is_1zst())
+                        {
+                            break;
+                        }
+
+                        let diag = if arg.span.contains(null_span) {
+                            InvalidNullArgumentsDiag::NullPtrInline { null_span }
+                        } else {
+                            InvalidNullArgumentsDiag::NullPtrThroughBinding { null_span }
+                        };
+
+                        cx.emit_span_lint(INVALID_NULL_ARGUMENTS, expr.span, diag)
+                    }
+                }
+            }
+
+            // Catching:
             // (fn_ptr as *<const/mut> <ty>).is_null()
             ExprKind::MethodCall(_, receiver, _, _)
                 if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
@@ -110,18 +210,18 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
                         cx.tcx.get_diagnostic_name(def_id),
                         Some(sym::ptr_const_is_null | sym::ptr_is_null)
                     )
-                    && let Some(diag) = incorrect_check(cx, receiver) =>
+                    && let Some(diag) = useless_check(cx, receiver) =>
             {
                 cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
             }
 
             ExprKind::Binary(op, left, right) if matches!(op.node, BinOpKind::Eq) => {
                 let to_check: &Expr<'_>;
-                let diag: PtrNullChecksDiag<'_>;
-                if let Some(ddiag) = incorrect_check(cx, left) {
+                let diag: UselessPtrNullChecksDiag<'_>;
+                if let Some(ddiag) = useless_check(cx, left) {
                     to_check = right;
                     diag = ddiag;
-                } else if let Some(ddiag) = incorrect_check(cx, right) {
+                } else if let Some(ddiag) = useless_check(cx, right) {
                     to_check = left;
                     diag = ddiag;
                 } else {
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 7c6656f91c9..1d4d380cb68 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -6,6 +6,7 @@ use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::sym;
 
 use crate::lints::InvalidReferenceCastingDiag;
+use crate::utils::peel_casts;
 use crate::{LateContext, LateLintPass, LintContext};
 
 declare_lint! {
@@ -235,46 +236,3 @@ fn is_cast_to_bigger_memory_layout<'tcx>(
         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 ...
-        e = if let ExprKind::Cast(expr, _) = e.kind {
-            expr
-        // <expr>.cast(), <expr>.cast_mut() or <expr>.cast_const()
-        } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
-            && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
-            && matches!(
-                cx.tcx.get_diagnostic_name(def_id),
-                Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const)
-            )
-        {
-            expr
-        // ptr::from_ref(<expr>), UnsafeCell::raw_get(<expr>) or mem::transmute<_, _>(<expr>)
-        } else if let ExprKind::Call(path, [arg]) = e.kind
-            && let ExprKind::Path(ref qpath) = path.kind
-            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
-            && matches!(
-                cx.tcx.get_diagnostic_name(def_id),
-                Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get | sym::transmute)
-            )
-        {
-            if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
-                gone_trough_unsafe_cell_raw_get = true;
-            }
-            arg
-        } else {
-            let init = cx.expr_or_init(e);
-            if init.hir_id != e.hir_id {
-                init
-            } else {
-                break;
-            }
-        };
-    }
-
-    (e, gone_trough_unsafe_cell_raw_get)
-}
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 7109fefbe78..a6c82f574a1 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -14,7 +14,7 @@ use rustc_middle::ty::{
 };
 use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{Span, Symbol, source_map, sym};
+use rustc_span::{Span, Symbol, sym};
 use tracing::debug;
 use {rustc_ast as ast, rustc_hir as hir};
 
@@ -223,7 +223,7 @@ impl TypeLimits {
 fn lint_nan<'tcx>(
     cx: &LateContext<'tcx>,
     e: &'tcx hir::Expr<'tcx>,
-    binop: hir::BinOp,
+    binop: hir::BinOpKind,
     l: &'tcx hir::Expr<'tcx>,
     r: &'tcx hir::Expr<'tcx>,
 ) {
@@ -262,19 +262,19 @@ fn lint_nan<'tcx>(
         InvalidNanComparisons::EqNe { suggestion }
     }
 
-    let lint = match binop.node {
+    let lint = match binop {
         hir::BinOpKind::Eq | hir::BinOpKind::Ne if is_nan(cx, l) => {
             eq_ne(e, l, r, |l_span, r_span| InvalidNanComparisonsSuggestion::Spanful {
                 nan_plus_binop: l_span.until(r_span),
                 float: r_span.shrink_to_hi(),
-                neg: (binop.node == hir::BinOpKind::Ne).then(|| r_span.shrink_to_lo()),
+                neg: (binop == hir::BinOpKind::Ne).then(|| r_span.shrink_to_lo()),
             })
         }
         hir::BinOpKind::Eq | hir::BinOpKind::Ne if is_nan(cx, r) => {
             eq_ne(e, l, r, |l_span, r_span| InvalidNanComparisonsSuggestion::Spanful {
                 nan_plus_binop: l_span.shrink_to_hi().to(r_span),
                 float: l_span.shrink_to_hi(),
-                neg: (binop.node == hir::BinOpKind::Ne).then(|| l_span.shrink_to_lo()),
+                neg: (binop == hir::BinOpKind::Ne).then(|| l_span.shrink_to_lo()),
             })
         }
         hir::BinOpKind::Lt | hir::BinOpKind::Le | hir::BinOpKind::Gt | hir::BinOpKind::Ge
@@ -560,11 +560,11 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
                 }
             }
             hir::ExprKind::Binary(binop, ref l, ref r) => {
-                if is_comparison(binop) {
-                    if !check_limits(cx, binop, l, r) {
+                if is_comparison(binop.node) {
+                    if !check_limits(cx, binop.node, l, r) {
                         cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
                     } else {
-                        lint_nan(cx, e, binop, l, r);
+                        lint_nan(cx, e, binop.node, l, r);
                         let cmpop = ComparisonOp::BinOp(binop.node);
                         lint_wide_pointer(cx, e, cmpop, l, r);
                         lint_fn_pointer(cx, e, cmpop, l, r);
@@ -591,8 +591,8 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
             _ => {}
         };
 
-        fn is_valid<T: PartialOrd>(binop: hir::BinOp, v: T, min: T, max: T) -> bool {
-            match binop.node {
+        fn is_valid<T: PartialOrd>(binop: hir::BinOpKind, v: T, min: T, max: T) -> bool {
+            match binop {
                 hir::BinOpKind::Lt => v > min && v <= max,
                 hir::BinOpKind::Le => v >= min && v < max,
                 hir::BinOpKind::Gt => v >= min && v < max,
@@ -602,22 +602,19 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
             }
         }
 
-        fn rev_binop(binop: hir::BinOp) -> hir::BinOp {
-            source_map::respan(
-                binop.span,
-                match binop.node {
-                    hir::BinOpKind::Lt => hir::BinOpKind::Gt,
-                    hir::BinOpKind::Le => hir::BinOpKind::Ge,
-                    hir::BinOpKind::Gt => hir::BinOpKind::Lt,
-                    hir::BinOpKind::Ge => hir::BinOpKind::Le,
-                    _ => return binop,
-                },
-            )
+        fn rev_binop(binop: hir::BinOpKind) -> hir::BinOpKind {
+            match binop {
+                hir::BinOpKind::Lt => hir::BinOpKind::Gt,
+                hir::BinOpKind::Le => hir::BinOpKind::Ge,
+                hir::BinOpKind::Gt => hir::BinOpKind::Lt,
+                hir::BinOpKind::Ge => hir::BinOpKind::Le,
+                _ => binop,
+            }
         }
 
         fn check_limits(
             cx: &LateContext<'_>,
-            binop: hir::BinOp,
+            binop: hir::BinOpKind,
             l: &hir::Expr<'_>,
             r: &hir::Expr<'_>,
         ) -> bool {
@@ -659,9 +656,9 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
             }
         }
 
-        fn is_comparison(binop: hir::BinOp) -> bool {
+        fn is_comparison(binop: hir::BinOpKind) -> bool {
             matches!(
-                binop.node,
+                binop,
                 hir::BinOpKind::Eq
                     | hir::BinOpKind::Lt
                     | hir::BinOpKind::Le
@@ -1403,7 +1400,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             CItemKind::Definition => "fn",
         };
         let span_note = if let ty::Adt(def, _) = ty.kind()
-            && let Some(sp) = self.cx.tcx.hir().span_if_local(def.did())
+            && let Some(sp) = self.cx.tcx.hir_span_if_local(def.did())
         {
             Some(sp)
         } else {
@@ -1634,6 +1631,9 @@ impl ImproperCTypesDefinitions {
             return true;
         } else if let Adt(adt_def, _) = ty.kind()
             && adt_def.is_struct()
+            && adt_def.repr().c()
+            && !adt_def.repr().packed()
+            && adt_def.repr().align.is_none()
         {
             let struct_variant = adt_def.variant(VariantIdx::ZERO);
             // Within a nested struct, all fields are examined to correctly
@@ -1655,8 +1655,11 @@ impl ImproperCTypesDefinitions {
         item: &'tcx hir::Item<'tcx>,
     ) {
         let adt_def = cx.tcx.adt_def(item.owner_id.to_def_id());
+        // repr(C) structs also with packed or aligned representation
+        // should be ignored.
         if adt_def.repr().c()
             && !adt_def.repr().packed()
+            && adt_def.repr().align.is_none()
             && cx.tcx.sess.target.os == "aix"
             && !adt_def.all_fields().next().is_none()
         {
diff --git a/compiler/rustc_lint/src/utils.rs b/compiler/rustc_lint/src/utils.rs
new file mode 100644
index 00000000000..a7295d9c532
--- /dev/null
+++ b/compiler/rustc_lint/src/utils.rs
@@ -0,0 +1,55 @@
+use rustc_hir::{Expr, ExprKind};
+use rustc_span::sym;
+
+use crate::LateContext;
+
+/// Given an expression, peel all of casts (`<expr> as ...`, `<expr>.cast{,_mut,_const}()`,
+/// `ptr::from_ref(<expr>)`, ...) and init expressions.
+///
+/// Returns the innermost expression and a boolean representing if one of the casts was
+/// `UnsafeCell::raw_get(<expr>)`
+pub(crate) 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 ...
+        e = if let ExprKind::Cast(expr, _) = e.kind {
+            expr
+        // <expr>.cast(), <expr>.cast_mut() or <expr>.cast_const()
+        } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
+            && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
+            && matches!(
+                cx.tcx.get_diagnostic_name(def_id),
+                Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const)
+            )
+        {
+            expr
+        // ptr::from_ref(<expr>), UnsafeCell::raw_get(<expr>) or mem::transmute<_, _>(<expr>)
+        } else if let ExprKind::Call(path, [arg]) = e.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && matches!(
+                cx.tcx.get_diagnostic_name(def_id),
+                Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get | sym::transmute)
+            )
+        {
+            if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
+                gone_trough_unsafe_cell_raw_get = true;
+            }
+            arg
+        } else {
+            let init = cx.expr_or_init(e);
+            if init.hir_id != e.hir_id {
+                init
+            } else {
+                break;
+            }
+        };
+    }
+
+    (e, gone_trough_unsafe_cell_raw_get)
+}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 46b4b1d4383..7fdbae3a59d 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -8,7 +8,8 @@ use rustc_data_structures::stable_hasher::{
 };
 use rustc_error_messages::{DiagMessage, MultiSpan};
 use rustc_hir::def::Namespace;
-use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind};
+use rustc_hir::def_id::DefPathHash;
+use rustc_hir::{HashStableContext, HirId, ItemLocalId, MissingLifetimeKind};
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 pub use rustc_span::edition::Edition;
 use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym};
@@ -102,7 +103,7 @@ pub enum Applicability {
 /// The index values have a type of `u16` to reduce the size of the `LintExpectationId`.
 /// It's reasonable to assume that no user will define 2^16 attributes on one node or
 /// have that amount of lints listed. `u16` values should therefore suffice.
-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, Encodable, Decodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)]
 pub enum LintExpectationId {
     /// Used for lints emitted during the `EarlyLintPass`. This id is not
     /// hash stable and should not be cached.
@@ -156,13 +157,14 @@ impl<HCX: rustc_hir::HashStableContext> HashStable<HCX> for LintExpectationId {
 }
 
 impl<HCX: rustc_hir::HashStableContext> ToStableHashKey<HCX> for LintExpectationId {
-    type KeyType = (HirId, u16, u16);
+    type KeyType = (DefPathHash, ItemLocalId, u16, u16);
 
     #[inline]
-    fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
+    fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType {
         match self {
             LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
-                (*hir_id, *attr_index, *lint_index)
+                let (def_path_hash, lint_idx) = hir_id.to_stable_hash_key(hcx);
+                (def_path_hash, lint_idx, *attr_index, *lint_index)
             }
             _ => {
                 unreachable!("HashStable should only be called for a filled `LintExpectationId`")
@@ -199,9 +201,9 @@ pub enum Level {
     ///
     /// See RFC 2383.
     ///
-    /// The [`LintExpectationId`] is used to later link a lint emission to the actual
+    /// Requires a [`LintExpectationId`] to later link a lint emission to the actual
     /// expectation. It can be ignored in most cases.
-    Expect(LintExpectationId),
+    Expect,
     /// The `warn` level will produce a warning if the lint was violated, however the
     /// compiler will continue with its execution.
     Warn,
@@ -209,9 +211,9 @@ pub enum Level {
     /// to ensure that a lint can't be suppressed. This lint level can currently only be set
     /// via the console and is therefore session specific.
     ///
-    /// The [`LintExpectationId`] is intended to fulfill expectations marked via the
+    /// Requires a [`LintExpectationId`] to fulfill expectations marked via the
     /// `#[expect]` attribute, that will still be suppressed due to the level.
-    ForceWarn(Option<LintExpectationId>),
+    ForceWarn,
     /// The `deny` level will produce an error and stop further execution after the lint
     /// pass is complete.
     Deny,
@@ -225,9 +227,9 @@ impl Level {
     pub fn as_str(self) -> &'static str {
         match self {
             Level::Allow => "allow",
-            Level::Expect(_) => "expect",
+            Level::Expect => "expect",
             Level::Warn => "warn",
-            Level::ForceWarn(_) => "force-warn",
+            Level::ForceWarn => "force-warn",
             Level::Deny => "deny",
             Level::Forbid => "forbid",
         }
@@ -246,24 +248,30 @@ impl Level {
     }
 
     /// Converts an `Attribute` to a level.
-    pub fn from_attr(attr: &impl AttributeExt) -> Option<Self> {
+    pub fn from_attr(attr: &impl AttributeExt) -> Option<(Self, Option<LintExpectationId>)> {
         Self::from_symbol(attr.name_or_empty(), || Some(attr.id()))
     }
 
     /// Converts a `Symbol` to a level.
-    pub fn from_symbol(s: Symbol, id: impl FnOnce() -> Option<AttrId>) -> Option<Self> {
+    pub fn from_symbol(
+        s: Symbol,
+        id: impl FnOnce() -> Option<AttrId>,
+    ) -> Option<(Self, Option<LintExpectationId>)> {
         match s {
-            sym::allow => Some(Level::Allow),
+            sym::allow => Some((Level::Allow, None)),
             sym::expect => {
                 if let Some(attr_id) = id() {
-                    Some(Level::Expect(LintExpectationId::Unstable { attr_id, lint_index: None }))
+                    Some((
+                        Level::Expect,
+                        Some(LintExpectationId::Unstable { attr_id, lint_index: None }),
+                    ))
                 } else {
                     None
                 }
             }
-            sym::warn => Some(Level::Warn),
-            sym::deny => Some(Level::Deny),
-            sym::forbid => Some(Level::Forbid),
+            sym::warn => Some((Level::Warn, None)),
+            sym::deny => Some((Level::Deny, None)),
+            sym::forbid => Some((Level::Forbid, None)),
             _ => None,
         }
     }
@@ -274,8 +282,8 @@ impl Level {
             Level::Deny => "-D",
             Level::Forbid => "-F",
             Level::Allow => "-A",
-            Level::ForceWarn(_) => "--force-warn",
-            Level::Expect(_) => {
+            Level::ForceWarn => "--force-warn",
+            Level::Expect => {
                 unreachable!("the expect level does not have a commandline flag")
             }
         }
@@ -283,17 +291,10 @@ impl Level {
 
     pub fn is_error(self) -> bool {
         match self {
-            Level::Allow | Level::Expect(_) | Level::Warn | Level::ForceWarn(_) => false,
+            Level::Allow | Level::Expect | Level::Warn | Level::ForceWarn => false,
             Level::Deny | Level::Forbid => true,
         }
     }
-
-    pub fn get_expectation_id(&self) -> Option<LintExpectationId> {
-        match self {
-            Level::Expect(id) | Level::ForceWarn(Some(id)) => Some(*id),
-            _ => None,
-        }
-    }
 }
 
 /// Specification of a single lint.
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index b8884486c33..4695de8ea09 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -47,7 +47,6 @@ struct LLVMRustMCDCBranchParameters {
   int16_t ConditionIDs[2];
 };
 
-#if LLVM_VERSION_GE(19, 0)
 static coverage::mcdc::BranchParameters
 fromRust(LLVMRustMCDCBranchParameters Params) {
   return coverage::mcdc::BranchParameters(
@@ -59,7 +58,6 @@ fromRust(LLVMRustMCDCDecisionParameters Params) {
   return coverage::mcdc::DecisionParameters(Params.BitmapIdx,
                                             Params.NumConditions);
 }
-#endif
 
 // Must match the layout of
 // `rustc_codegen_llvm::coverageinfo::ffi::CoverageSpan`.
@@ -203,7 +201,6 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer(
         Region.Span.LineEnd, Region.Span.ColumnEnd));
   }
 
-#if LLVM_VERSION_GE(19, 0)
   // MC/DC branch regions:
   for (const auto &Region : ArrayRef(MCDCBranchRegions, NumMCDCBranchRegions)) {
     MappingRegions.push_back(coverage::CounterMappingRegion::makeBranchRegion(
@@ -221,7 +218,6 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer(
         Region.Span.LineStart, Region.Span.ColumnStart, Region.Span.LineEnd,
         Region.Span.ColumnEnd));
   }
-#endif
 
   // Write the converted expressions and mappings to a byte buffer.
   auto CoverageMappingWriter = coverage::CoverageMappingWriter(
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 86f1bcc46ee..e02c80c50b1 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -47,10 +47,7 @@
 #include <vector>
 
 // Conditional includes prevent clang-format from fully sorting the list,
-// so keep them separate.
-#if LLVM_VERSION_GE(19, 0)
-#include "llvm/Support/PGOOptions.h"
-#endif
+// so if any are needed, keep them separate down here.
 
 using namespace llvm;
 
@@ -432,31 +429,15 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   }
   if (!strcmp("zlib", DebugInfoCompression) &&
       llvm::compression::zlib::isAvailable()) {
-#if LLVM_VERSION_GE(19, 0)
     Options.MCOptions.CompressDebugSections = DebugCompressionType::Zlib;
-#else
-    Options.CompressDebugSections = DebugCompressionType::Zlib;
-#endif
   } else if (!strcmp("zstd", DebugInfoCompression) &&
              llvm::compression::zstd::isAvailable()) {
-#if LLVM_VERSION_GE(19, 0)
     Options.MCOptions.CompressDebugSections = DebugCompressionType::Zstd;
-#else
-    Options.CompressDebugSections = DebugCompressionType::Zstd;
-#endif
   } else if (!strcmp("none", DebugInfoCompression)) {
-#if LLVM_VERSION_GE(19, 0)
     Options.MCOptions.CompressDebugSections = DebugCompressionType::None;
-#else
-    Options.CompressDebugSections = DebugCompressionType::None;
-#endif
   }
 
-#if LLVM_VERSION_GE(19, 0)
   Options.MCOptions.X86RelaxRelocations = RelaxELFRelocations;
-#else
-  Options.RelaxELFRelocations = RelaxELFRelocations;
-#endif
   Options.UseInitArray = UseInitArray;
   Options.EmulatedTLS = UseEmulatedTls;
 
@@ -753,34 +734,23 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   auto FS = vfs::getRealFileSystem();
   if (PGOGenPath) {
     assert(!PGOUsePath && !PGOSampleUsePath);
-    PGOOpt = PGOOptions(PGOGenPath, "", "", "", FS, PGOOptions::IRInstr,
-                        PGOOptions::NoCSAction,
-#if LLVM_VERSION_GE(19, 0)
-                        PGOOptions::ColdFuncOpt::Default,
-#endif
-                        DebugInfoForProfiling);
+    PGOOpt = PGOOptions(
+        PGOGenPath, "", "", "", FS, PGOOptions::IRInstr, PGOOptions::NoCSAction,
+        PGOOptions::ColdFuncOpt::Default, DebugInfoForProfiling);
   } else if (PGOUsePath) {
     assert(!PGOSampleUsePath);
-    PGOOpt = PGOOptions(PGOUsePath, "", "", "", FS, PGOOptions::IRUse,
-                        PGOOptions::NoCSAction,
-#if LLVM_VERSION_GE(19, 0)
-                        PGOOptions::ColdFuncOpt::Default,
-#endif
-                        DebugInfoForProfiling);
+    PGOOpt = PGOOptions(
+        PGOUsePath, "", "", "", FS, PGOOptions::IRUse, PGOOptions::NoCSAction,
+        PGOOptions::ColdFuncOpt::Default, DebugInfoForProfiling);
   } else if (PGOSampleUsePath) {
-    PGOOpt = PGOOptions(PGOSampleUsePath, "", "", "", FS, PGOOptions::SampleUse,
-                        PGOOptions::NoCSAction,
-#if LLVM_VERSION_GE(19, 0)
-                        PGOOptions::ColdFuncOpt::Default,
-#endif
-                        DebugInfoForProfiling);
+    PGOOpt =
+        PGOOptions(PGOSampleUsePath, "", "", "", FS, PGOOptions::SampleUse,
+                   PGOOptions::NoCSAction, PGOOptions::ColdFuncOpt::Default,
+                   DebugInfoForProfiling);
   } else if (DebugInfoForProfiling) {
-    PGOOpt = PGOOptions("", "", "", "", FS, PGOOptions::NoAction,
-                        PGOOptions::NoCSAction,
-#if LLVM_VERSION_GE(19, 0)
-                        PGOOptions::ColdFuncOpt::Default,
-#endif
-                        DebugInfoForProfiling);
+    PGOOpt = PGOOptions(
+        "", "", "", "", FS, PGOOptions::NoAction, PGOOptions::NoCSAction,
+        PGOOptions::ColdFuncOpt::Default, DebugInfoForProfiling);
   }
 
   auto PB = PassBuilder(TM, PTO, PGOOpt, &PIC);
@@ -855,10 +825,15 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   }
 
   if (LintIR) {
-    PipelineStartEPCallbacks.push_back(
-        [](ModulePassManager &MPM, OptimizationLevel Level) {
-          MPM.addPass(createModuleToFunctionPassAdaptor(LintPass()));
-        });
+    PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM,
+                                          OptimizationLevel Level) {
+#if LLVM_VERSION_GE(21, 0)
+      MPM.addPass(
+          createModuleToFunctionPassAdaptor(LintPass(/*AbortOnError=*/true)));
+#else
+      MPM.addPass(createModuleToFunctionPassAdaptor(LintPass()));
+#endif
+    });
   }
 
   if (InstrumentCoverage) {
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 53df59930f4..5f0e4d745e8 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -384,6 +384,12 @@ static inline void AddAttributes(T *t, unsigned Index, LLVMAttributeRef *Attrs,
   t->setAttributes(PALNew);
 }
 
+extern "C" bool LLVMRustHasAttributeAtIndex(LLVMValueRef Fn, unsigned Index,
+                                            LLVMRustAttributeKind RustAttr) {
+  Function *F = unwrap<Function>(Fn);
+  return F->hasParamAttribute(Index, fromRust(RustAttr));
+}
+
 extern "C" void LLVMRustAddFunctionAttributes(LLVMValueRef Fn, unsigned Index,
                                               LLVMAttributeRef *Attrs,
                                               size_t AttrsLen) {
@@ -467,12 +473,8 @@ extern "C" LLVMAttributeRef
 LLVMRustCreateRangeAttribute(LLVMContextRef C, unsigned NumBits,
                              const uint64_t LowerWords[],
                              const uint64_t UpperWords[]) {
-#if LLVM_VERSION_GE(19, 0)
   return LLVMCreateConstantRangeAttribute(C, Attribute::Range, NumBits,
                                           LowerWords, UpperWords);
-#else
-  report_fatal_error("LLVM 19.0 is required for Range Attribute");
-#endif
 }
 
 // These values **must** match ffi::AllocKindFlags.
@@ -636,6 +638,10 @@ static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
   }
 }
 
+extern "C" uint64_t LLVMRustGetArrayNumElements(LLVMTypeRef Ty) {
+  return unwrap(Ty)->getArrayNumElements();
+}
+
 extern "C" LLVMValueRef
 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
                   char *Constraints, size_t ConstraintsLen,
@@ -1591,43 +1597,6 @@ extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B, LLVMValueRef Dst,
                                       MaybeAlign(DstAlign), IsVolatile));
 }
 
-// Polyfill for `LLVMBuildCallBr`, which was added in LLVM 19.
-// <https://github.com/llvm/llvm-project/commit/584253c4e2f788f870488fc32193b52d67ddaccc>
-// FIXME: Remove when Rust's minimum supported LLVM version reaches 19.
-#if LLVM_VERSION_LT(19, 0)
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OperandBundleDef, LLVMOperandBundleRef)
-
-extern "C" LLVMValueRef
-LLVMBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
-                LLVMBasicBlockRef DefaultDest, LLVMBasicBlockRef *IndirectDests,
-                unsigned NumIndirectDests, LLVMValueRef *Args, unsigned NumArgs,
-                LLVMOperandBundleRef *Bundles, unsigned NumBundles,
-                const char *Name) {
-  Value *Callee = unwrap(Fn);
-  FunctionType *FTy = unwrap<FunctionType>(Ty);
-
-  // FIXME: Is there a way around this?
-  std::vector<BasicBlock *> IndirectDestsUnwrapped;
-  IndirectDestsUnwrapped.reserve(NumIndirectDests);
-  for (unsigned i = 0; i < NumIndirectDests; ++i) {
-    IndirectDestsUnwrapped.push_back(unwrap(IndirectDests[i]));
-  }
-
-  // FIXME: Is there a way around this?
-  SmallVector<OperandBundleDef> OpBundles;
-  OpBundles.reserve(NumBundles);
-  for (unsigned i = 0; i < NumBundles; ++i) {
-    OpBundles.push_back(*unwrap(Bundles[i]));
-  }
-
-  return wrap(
-      unwrap(B)->CreateCallBr(FTy, Callee, unwrap(DefaultDest),
-                              ArrayRef<BasicBlock *>(IndirectDestsUnwrapped),
-                              ArrayRef<Value *>(unwrap(Args), NumArgs),
-                              ArrayRef<OperandBundleDef>(OpBundles), Name));
-}
-#endif
-
 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
                                                LLVMBasicBlockRef BB) {
   auto Point = unwrap(BB)->getFirstInsertionPt();
@@ -1771,24 +1740,6 @@ extern "C" LLVMValueRef LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS,
   return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS), unwrap(RHS)));
 }
 
-#if LLVM_VERSION_LT(19, 0)
-enum {
-  LLVMGEPFlagInBounds = (1 << 0),
-  LLVMGEPFlagNUSW = (1 << 1),
-  LLVMGEPFlagNUW = (1 << 2),
-};
-extern "C" LLVMValueRef
-LLVMBuildGEPWithNoWrapFlags(LLVMBuilderRef B, LLVMTypeRef Ty,
-                            LLVMValueRef Pointer, LLVMValueRef *Indices,
-                            unsigned NumIndices, const char *Name,
-                            unsigned NoWrapFlags) {
-  if (NoWrapFlags & LLVMGEPFlagInBounds)
-    return LLVMBuildInBoundsGEP2(B, Ty, Pointer, Indices, NumIndices, Name);
-  else
-    return LLVMBuildGEP2(B, Ty, Pointer, Indices, NumIndices, Name);
-}
-#endif
-
 // Transfers ownership of DiagnosticHandler unique_ptr to the caller.
 extern "C" DiagnosticHandler *
 LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) {
@@ -1856,11 +1807,7 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
         }
       }
       if (DiagnosticHandlerCallback) {
-#if LLVM_VERSION_GE(19, 0)
         DiagnosticHandlerCallback(&DI, DiagnosticHandlerContext);
-#else
-        DiagnosticHandlerCallback(DI, DiagnosticHandlerContext);
-#endif
         return true;
       }
       return false;
@@ -2008,21 +1955,3 @@ extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
   MD.NoHWAddress = true;
   GV.setSanitizerMetadata(MD);
 }
-
-// Operations on composite constants.
-// These are clones of LLVM api functions that will become available in future
-// releases. They can be removed once Rust's minimum supported LLVM version
-// supports them. See https://github.com/rust-lang/rust/issues/121868 See
-// https://llvm.org/doxygen/group__LLVMCCoreValueConstantComposite.html
-
-// FIXME: Remove when Rust's minimum supported LLVM version reaches 19.
-// https://github.com/llvm/llvm-project/commit/e1405e4f71c899420ebf8262d5e9745598419df8
-#if LLVM_VERSION_LT(19, 0)
-extern "C" LLVMValueRef LLVMConstStringInContext2(LLVMContextRef C,
-                                                  const char *Str,
-                                                  size_t Length,
-                                                  bool DontNullTerminate) {
-  return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length),
-                                           !DontNullTerminate));
-}
-#endif
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index 9adbcabcf45..d997ba198ac 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -97,6 +97,10 @@ metadata_found_staticlib =
     found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}
     .help = please recompile that crate using --crate-type lib
 
+metadata_full_metadata_not_found =
+    only metadata stub found for `{$flavor}` dependency `{$crate_name}`
+    please provide path to the corresponding .rmeta file with full metadata
+
 metadata_global_alloc_required =
     no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index b7f13e0afdc..1c3222bbfeb 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -340,7 +340,7 @@ impl CStore {
         }
         let level = tcx
             .lint_level_at_node(lint::builtin::UNUSED_CRATE_DEPENDENCIES, rustc_hir::CRATE_HIR_ID)
-            .0;
+            .level;
         if level != lint::Level::Allow {
             let unused_externs =
                 self.unused_externs.iter().map(|ident| ident.to_ident_string()).collect::<Vec<_>>();
@@ -1032,14 +1032,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
     }
 
     fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
-        self.cstore.has_global_allocator = match &*global_allocator_spans(krate) {
-            [span1, span2, ..] => {
-                self.dcx().emit_err(errors::NoMultipleGlobalAlloc { span2: *span2, span1: *span1 });
-                true
-            }
-            spans => !spans.is_empty(),
-        };
-        self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(krate) {
+        self.cstore.has_global_allocator =
+            match &*fn_spans(krate, Symbol::intern(&global_fn_name(sym::alloc))) {
+                [span1, span2, ..] => {
+                    self.dcx()
+                        .emit_err(errors::NoMultipleGlobalAlloc { span2: *span2, span1: *span1 });
+                    true
+                }
+                spans => !spans.is_empty(),
+            };
+        self.cstore.has_alloc_error_handler = match &*fn_spans(
+            krate,
+            Symbol::intern(alloc_error_handler_name(AllocatorKind::Global)),
+        ) {
             [span1, span2, ..] => {
                 self.dcx()
                     .emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 });
@@ -1310,17 +1315,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         definitions: &Definitions,
     ) -> Option<CrateNum> {
         match item.kind {
-            ast::ItemKind::ExternCrate(orig_name) => {
-                debug!(
-                    "resolving extern crate stmt. ident: {} orig_name: {:?}",
-                    item.ident, orig_name
-                );
+            ast::ItemKind::ExternCrate(orig_name, ident) => {
+                debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", ident, orig_name);
                 let name = match orig_name {
                     Some(orig_name) => {
                         validate_crate_name(self.sess, orig_name, Some(item.span));
                         orig_name
                     }
-                    None => item.ident.name,
+                    None => ident.name,
                 };
                 let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
                     CrateDepKind::MacrosOnly
@@ -1368,36 +1370,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
     }
 }
 
-fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
-    struct Finder {
-        name: Symbol,
-        spans: Vec<Span>,
-    }
-    impl<'ast> visit::Visitor<'ast> for Finder {
-        fn visit_item(&mut self, item: &'ast ast::Item) {
-            if item.ident.name == self.name
-                && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
-            {
-                self.spans.push(item.span);
-            }
-            visit::walk_item(self, item)
-        }
-    }
-
-    let name = Symbol::intern(&global_fn_name(sym::alloc));
-    let mut f = Finder { name, spans: Vec::new() };
-    visit::walk_crate(&mut f, krate);
-    f.spans
-}
-
-fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec<Span> {
+fn fn_spans(krate: &ast::Crate, name: Symbol) -> Vec<Span> {
     struct Finder {
         name: Symbol,
         spans: Vec<Span>,
     }
     impl<'ast> visit::Visitor<'ast> for Finder {
         fn visit_item(&mut self, item: &'ast ast::Item) {
-            if item.ident.name == self.name
+            if let Some(ident) = item.kind.ident()
+                && ident.name == self.name
                 && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
             {
                 self.spans.push(item.span);
@@ -1406,7 +1387,6 @@ fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec<Span> {
         }
     }
 
-    let name = Symbol::intern(alloc_error_handler_name(AllocatorKind::Global));
     let mut f = Finder { name, spans: Vec::new() };
     visit::walk_crate(&mut f, krate);
     f.spans
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 0c54628598c..c45daeda85d 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -526,6 +526,15 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for MultipleCandidates {
 }
 
 #[derive(Diagnostic)]
+#[diag(metadata_full_metadata_not_found)]
+pub(crate) struct FullMetadataNotFound {
+    #[primary_span]
+    pub span: Span,
+    pub flavor: CrateFlavor,
+    pub crate_name: Symbol,
+}
+
+#[derive(Diagnostic)]
 #[diag(metadata_symbol_conflicts_current, code = E0519)]
 pub struct SymbolConflictsCurrent {
     #[primary_span]
diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs
index 4450d050c8e..c4e1e0f1d1a 100644
--- a/compiler/rustc_metadata/src/fs.rs
+++ b/compiler/rustc_metadata/src/fs.rs
@@ -3,7 +3,7 @@ use std::{fs, io};
 
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_middle::ty::TyCtxt;
-use rustc_session::config::{OutFileName, OutputType};
+use rustc_session::config::{CrateType, OutFileName, OutputType};
 use rustc_session::output::filename_for_metadata;
 use rustc_session::{MetadataKind, Session};
 use tempfile::Builder as TempFileBuilder;
@@ -50,7 +50,14 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
         .tempdir_in(out_filename.parent().unwrap_or_else(|| Path::new("")))
         .unwrap_or_else(|err| tcx.dcx().emit_fatal(FailedCreateTempdir { err }));
     let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
-    let metadata_filename = metadata_tmpdir.as_ref().join(METADATA_FILENAME);
+    let metadata_filename = metadata_tmpdir.as_ref().join("full.rmeta");
+    let metadata_stub_filename = if !tcx.sess.opts.unstable_opts.embed_metadata
+        && !tcx.crate_types().contains(&CrateType::ProcMacro)
+    {
+        Some(metadata_tmpdir.as_ref().join("stub.rmeta"))
+    } else {
+        None
+    };
 
     // Always create a file at `metadata_filename`, even if we have nothing to write to it.
     // This simplifies the creation of the output `out_filename` when requested.
@@ -60,9 +67,15 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
             std::fs::File::create(&metadata_filename).unwrap_or_else(|err| {
                 tcx.dcx().emit_fatal(FailedCreateFile { filename: &metadata_filename, err });
             });
+            if let Some(metadata_stub_filename) = &metadata_stub_filename {
+                std::fs::File::create(metadata_stub_filename).unwrap_or_else(|err| {
+                    tcx.dcx()
+                        .emit_fatal(FailedCreateFile { filename: &metadata_stub_filename, err });
+                });
+            }
         }
         MetadataKind::Uncompressed | MetadataKind::Compressed => {
-            encode_metadata(tcx, &metadata_filename);
+            encode_metadata(tcx, &metadata_filename, metadata_stub_filename.as_deref())
         }
     };
 
@@ -100,9 +113,10 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
 
     // Load metadata back to memory: codegen may need to include it in object files.
     let metadata =
-        EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|err| {
-            tcx.dcx().emit_fatal(FailedCreateEncodedMetadata { err });
-        });
+        EncodedMetadata::from_path(metadata_filename, metadata_stub_filename, metadata_tmpdir)
+            .unwrap_or_else(|err| {
+                tcx.dcx().emit_fatal(FailedCreateEncodedMetadata { err });
+            });
 
     let need_metadata_module = metadata_kind == MetadataKind::Compressed;
 
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index d5dd5059aac..112954eca0d 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -654,7 +654,24 @@ impl<'a> CrateLocator<'a> {
                     continue;
                 }
             }
-            *slot = Some((hash, metadata, lib.clone()));
+
+            // We error eagerly here. If we're locating a rlib, then in theory the full metadata
+            // could still be in a (later resolved) dylib. In practice, if the rlib and dylib
+            // were produced in a way where one has full metadata and the other hasn't, it would
+            // mean that they were compiled using different compiler flags and probably also have
+            // a different SVH value.
+            if metadata.get_header().is_stub {
+                // `is_stub` should never be true for .rmeta files.
+                assert_ne!(flavor, CrateFlavor::Rmeta);
+
+                // Because rmeta files are resolved before rlib/dylib files, if this is a stub and
+                // we haven't found a slot already, it means that the full metadata is missing.
+                if slot.is_none() {
+                    return Err(CrateError::FullMetadataNotFound(self.crate_name, flavor));
+                }
+            } else {
+                *slot = Some((hash, metadata, lib.clone()));
+            }
             ret = Some((lib, kind));
         }
 
@@ -728,37 +745,25 @@ impl<'a> CrateLocator<'a> {
             let Some(file) = loc_orig.file_name().and_then(|s| s.to_str()) else {
                 return Err(CrateError::ExternLocationNotFile(self.crate_name, loc_orig.clone()));
             };
-            // FnMut cannot return reference to captured value, so references
-            // must be taken outside the closure.
-            let rlibs = &mut rlibs;
-            let rmetas = &mut rmetas;
-            let dylibs = &mut dylibs;
-            let type_via_filename = (|| {
-                if file.starts_with("lib") {
-                    if file.ends_with(".rlib") {
-                        return Some(rlibs);
-                    }
-                    if file.ends_with(".rmeta") {
-                        return Some(rmetas);
-                    }
-                }
-                let dll_prefix = self.target.dll_prefix.as_ref();
-                let dll_suffix = self.target.dll_suffix.as_ref();
-                if file.starts_with(dll_prefix) && file.ends_with(dll_suffix) {
-                    return Some(dylibs);
-                }
-                None
-            })();
-            match type_via_filename {
-                Some(type_via_filename) => {
-                    type_via_filename.insert(loc_canon.clone(), PathKind::ExternFlag);
+            if file.starts_with("lib") {
+                if file.ends_with(".rlib") {
+                    rlibs.insert(loc_canon.clone(), PathKind::ExternFlag);
+                    continue;
                 }
-                None => {
-                    self.crate_rejections
-                        .via_filename
-                        .push(CrateMismatch { path: loc_orig.clone(), got: String::new() });
+                if file.ends_with(".rmeta") {
+                    rmetas.insert(loc_canon.clone(), PathKind::ExternFlag);
+                    continue;
                 }
             }
+            let dll_prefix = self.target.dll_prefix.as_ref();
+            let dll_suffix = self.target.dll_suffix.as_ref();
+            if file.starts_with(dll_prefix) && file.ends_with(dll_suffix) {
+                dylibs.insert(loc_canon.clone(), PathKind::ExternFlag);
+                continue;
+            }
+            self.crate_rejections
+                .via_filename
+                .push(CrateMismatch { path: loc_orig.clone(), got: String::new() });
         }
 
         // Extract the dylib/rlib/rmeta triple.
@@ -928,6 +933,7 @@ pub(crate) enum CrateError {
     ExternLocationNotExist(Symbol, PathBuf),
     ExternLocationNotFile(Symbol, PathBuf),
     MultipleCandidates(Symbol, CrateFlavor, Vec<PathBuf>),
+    FullMetadataNotFound(Symbol, CrateFlavor),
     SymbolConflictsCurrent(Symbol),
     StableCrateIdCollision(Symbol, Symbol),
     DlOpen(String, String),
@@ -978,6 +984,9 @@ impl CrateError {
             CrateError::MultipleCandidates(crate_name, flavor, candidates) => {
                 dcx.emit_err(errors::MultipleCandidates { span, crate_name, flavor, candidates });
             }
+            CrateError::FullMetadataNotFound(crate_name, flavor) => {
+                dcx.emit_err(errors::FullMetadataNotFound { span, crate_name, flavor });
+            }
             CrateError::SymbolConflictsCurrent(root_name) => {
                 dcx.emit_err(errors::SymbolConflictsCurrent { span, crate_name: root_name });
             }
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index f63ae8079dc..130a425e9c7 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -73,7 +73,7 @@ pub fn walk_native_lib_search_dirs<R>(
         || sess.target.os == "linux"
         || sess.target.os == "fuchsia"
         || sess.target.is_like_aix
-        || sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
+        || sess.target.is_like_darwin && !sess.opts.unstable_opts.sanitizer.is_empty()
     {
         f(&sess.target_tlib_path.dir, false)?;
     }
@@ -257,7 +257,7 @@ impl<'tcx> Collector<'tcx> {
                             "static" => NativeLibKind::Static { bundle: None, whole_archive: None },
                             "dylib" => NativeLibKind::Dylib { as_needed: None },
                             "framework" => {
-                                if !sess.target.is_like_osx {
+                                if !sess.target.is_like_darwin {
                                     sess.dcx().emit_err(errors::LinkFrameworkApple { span });
                                 }
                                 NativeLibKind::Framework { as_needed: None }
@@ -531,7 +531,7 @@ impl<'tcx> Collector<'tcx> {
         let mut renames = FxHashSet::default();
         for lib in &self.tcx.sess.opts.libs {
             if let NativeLibKind::Framework { .. } = lib.kind
-                && !self.tcx.sess.target.is_like_osx
+                && !self.tcx.sess.target.is_like_darwin
             {
                 // Cannot check this when parsing options because the target is not yet available.
                 self.tcx.dcx().emit_err(errors::LibFrameworkApple);
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 776b081a463..3dc82ce9d18 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -330,14 +330,8 @@ provide! { tcx, def_id, other, cdata,
 
     visibility => { cdata.get_visibility(def_id.index) }
     adt_def => { cdata.get_adt_def(def_id.index, tcx) }
-    adt_destructor => {
-        let _ = cdata;
-        tcx.calculate_dtor(def_id, |_,_| Ok(()))
-    }
-    adt_async_destructor => {
-        let _ = cdata;
-        tcx.calculate_async_dtor(def_id, |_,_| Ok(()))
-    }
+    adt_destructor => { table }
+    adt_async_destructor => { table }
     associated_item_def_ids => {
         tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index))
     }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 7ab3d432bdf..167122a9793 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -701,6 +701,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     triple: tcx.sess.opts.target_triple.clone(),
                     hash: tcx.crate_hash(LOCAL_CRATE),
                     is_proc_macro_crate: proc_macro_data.is_some(),
+                    is_stub: false,
                 },
                 extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
                 stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
@@ -1633,6 +1634,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 record!(self.tables.fn_sig[variant.def_id] <- fn_sig);
             }
         }
+
+        if let Some(destructor) = tcx.adt_destructor(local_def_id) {
+            record!(self.tables.adt_destructor[def_id] <- destructor);
+        }
+
+        if let Some(destructor) = tcx.adt_async_destructor(local_def_id) {
+            record!(self.tables.adt_async_destructor[def_id] <- destructor);
+        }
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -1881,8 +1890,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         let is_proc_macro = self.tcx.crate_types().contains(&CrateType::ProcMacro);
         if is_proc_macro {
             let tcx = self.tcx;
-            let hir = tcx.hir();
-
             let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index;
             let stability = tcx.lookup_stability(CRATE_DEF_ID);
             let macros =
@@ -1915,7 +1922,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let id = proc_macro;
                 let proc_macro = tcx.local_def_id_to_hir_id(proc_macro);
                 let mut name = tcx.hir_name(proc_macro);
-                let span = hir.span(proc_macro);
+                let span = tcx.hir_span(proc_macro);
                 // Proc-macros may have attributes like `#[allow_internal_unstable]`,
                 // so downstream crates need access to them.
                 let attrs = tcx.hir_attrs(proc_macro);
@@ -2231,8 +2238,12 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
 // generated regardless of trailing bytes that end up in it.
 
 pub struct EncodedMetadata {
-    // The declaration order matters because `mmap` should be dropped before `_temp_dir`.
-    mmap: Option<Mmap>,
+    // The declaration order matters because `full_metadata` should be dropped
+    // before `_temp_dir`.
+    full_metadata: Option<Mmap>,
+    // This is an optional stub metadata containing only the crate header.
+    // The header should be very small, so we load it directly into memory.
+    stub_metadata: Option<Vec<u8>>,
     // We need to carry MaybeTempDir to avoid deleting the temporary
     // directory while accessing the Mmap.
     _temp_dir: Option<MaybeTempDir>,
@@ -2240,33 +2251,50 @@ pub struct EncodedMetadata {
 
 impl EncodedMetadata {
     #[inline]
-    pub fn from_path(path: PathBuf, temp_dir: Option<MaybeTempDir>) -> std::io::Result<Self> {
+    pub fn from_path(
+        path: PathBuf,
+        stub_path: Option<PathBuf>,
+        temp_dir: Option<MaybeTempDir>,
+    ) -> std::io::Result<Self> {
         let file = std::fs::File::open(&path)?;
         let file_metadata = file.metadata()?;
         if file_metadata.len() == 0 {
-            return Ok(Self { mmap: None, _temp_dir: None });
+            return Ok(Self { full_metadata: None, stub_metadata: None, _temp_dir: None });
         }
-        let mmap = unsafe { Some(Mmap::map(file)?) };
-        Ok(Self { mmap, _temp_dir: temp_dir })
+        let full_mmap = unsafe { Some(Mmap::map(file)?) };
+
+        let stub =
+            if let Some(stub_path) = stub_path { Some(std::fs::read(stub_path)?) } else { None };
+
+        Ok(Self { full_metadata: full_mmap, stub_metadata: stub, _temp_dir: temp_dir })
     }
 
     #[inline]
-    pub fn raw_data(&self) -> &[u8] {
-        self.mmap.as_deref().unwrap_or_default()
+    pub fn full(&self) -> &[u8] {
+        &self.full_metadata.as_deref().unwrap_or_default()
+    }
+
+    #[inline]
+    pub fn stub_or_full(&self) -> &[u8] {
+        self.stub_metadata.as_deref().unwrap_or(self.full())
     }
 }
 
 impl<S: Encoder> Encodable<S> for EncodedMetadata {
     fn encode(&self, s: &mut S) {
-        let slice = self.raw_data();
+        self.stub_metadata.encode(s);
+
+        let slice = self.full();
         slice.encode(s)
     }
 }
 
 impl<D: Decoder> Decodable<D> for EncodedMetadata {
     fn decode(d: &mut D) -> Self {
+        let stub = <Option<Vec<u8>>>::decode(d);
+
         let len = d.read_usize();
-        let mmap = if len > 0 {
+        let full_metadata = if len > 0 {
             let mut mmap = MmapMut::map_anon(len).unwrap();
             mmap.copy_from_slice(d.read_raw_bytes(len));
             Some(mmap.make_read_only().unwrap())
@@ -2274,11 +2302,11 @@ impl<D: Decoder> Decodable<D> for EncodedMetadata {
             None
         };
 
-        Self { mmap, _temp_dir: None }
+        Self { full_metadata, stub_metadata: stub, _temp_dir: None }
     }
 }
 
-pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
+pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
     let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata");
 
     // Since encoding metadata is not in a query, and nothing is cached,
@@ -2292,6 +2320,42 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
         join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE));
     }
 
+    with_encode_metadata_header(tcx, path, |ecx| {
+        // Encode all the entries and extra information in the crate,
+        // culminating in the `CrateRoot` which points to all of it.
+        let root = ecx.encode_crate_root();
+
+        // Flush buffer to ensure backing file has the correct size.
+        ecx.opaque.flush();
+        // Record metadata size for self-profiling
+        tcx.prof.artifact_size(
+            "crate_metadata",
+            "crate_metadata",
+            ecx.opaque.file().metadata().unwrap().len(),
+        );
+
+        root.position.get()
+    });
+
+    if let Some(ref_path) = ref_path {
+        with_encode_metadata_header(tcx, ref_path, |ecx| {
+            let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader {
+                name: tcx.crate_name(LOCAL_CRATE),
+                triple: tcx.sess.opts.target_triple.clone(),
+                hash: tcx.crate_hash(LOCAL_CRATE),
+                is_proc_macro_crate: false,
+                is_stub: true,
+            });
+            header.position.get()
+        });
+    }
+}
+
+fn with_encode_metadata_header(
+    tcx: TyCtxt<'_>,
+    path: &Path,
+    f: impl FnOnce(&mut EncodeContext<'_, '_>) -> usize,
+) {
     let mut encoder = opaque::FileEncoder::new(path)
         .unwrap_or_else(|err| tcx.dcx().emit_fatal(FailCreateFileEncoder { err }));
     encoder.emit_raw_bytes(METADATA_HEADER);
@@ -2326,9 +2390,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
     // Encode the rustc version string in a predictable location.
     rustc_version(tcx.sess.cfg_version).encode(&mut ecx);
 
-    // Encode all the entries and extra information in the crate,
-    // culminating in the `CrateRoot` which points to all of it.
-    let root = ecx.encode_crate_root();
+    let root_position = f(&mut ecx);
 
     // Make sure we report any errors from writing to the file.
     // If we forget this, compilation can succeed with an incomplete rmeta file,
@@ -2338,12 +2400,9 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
     }
 
     let file = ecx.opaque.file();
-    if let Err(err) = encode_root_position(file, root.position.get()) {
+    if let Err(err) = encode_root_position(file, root_position) {
         tcx.dcx().emit_fatal(FailWriteFile { path: ecx.opaque.path(), err });
     }
-
-    // Record metadata size for self-profiling
-    tcx.prof.artifact_size("crate_metadata", "crate_metadata", file.metadata().unwrap().len());
 }
 
 fn encode_root_position(mut file: &File, pos: usize) -> Result<(), std::io::Error> {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index dc453b1e747..96a1f65eeb0 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -36,7 +36,9 @@ use rustc_serialize::opaque::FileEncoder;
 use rustc_session::config::{SymbolManglingVersion, TargetModifier};
 use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
 use rustc_span::edition::Edition;
-use rustc_span::hygiene::{ExpnIndex, MacroKind, SyntaxContextData};
+use rustc_span::hygiene::{
+    ExpnIndex, MacroKind, SyntaxContextDataNonRecursive as SyntaxContextData,
+};
 use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Ident, Span, Symbol};
 use rustc_target::spec::{PanicStrategy, TargetTuple};
 use table::TableBuilder;
@@ -56,7 +58,7 @@ pub(crate) fn rustc_version(cfg_version: &'static str) -> String {
 /// Metadata encoding version.
 /// N.B., increment this if you change the format of metadata such that
 /// the rustc version can't be found to compare with `rustc_version()`.
-const METADATA_VERSION: u8 = 9;
+const METADATA_VERSION: u8 = 10;
 
 /// Metadata header which includes `METADATA_VERSION`.
 ///
@@ -221,6 +223,12 @@ pub(crate) struct CrateHeader {
     /// This is separate from [`ProcMacroData`] to avoid having to update [`METADATA_VERSION`] every
     /// time ProcMacroData changes.
     pub(crate) is_proc_macro_crate: bool,
+    /// Whether this crate metadata section is just a stub.
+    /// Stubs do not contain the full metadata (it will be typically stored
+    /// in a separate rmeta file).
+    ///
+    /// This is used inside rlibs and dylibs when using `-Zembed-metadata=no`.
+    pub(crate) is_stub: bool,
 }
 
 /// Serialized `.rmeta` data for a crate.
@@ -446,6 +454,8 @@ define_tables! {
     fn_arg_names: Table<DefIndex, LazyArray<Option<Ident>>>,
     coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
     coroutine_for_closure: Table<DefIndex, RawDefId>,
+    adt_destructor: Table<DefIndex, LazyValue<ty::Destructor>>,
+    adt_async_destructor: Table<DefIndex, LazyValue<ty::AsyncDestructor>>,
     coroutine_by_move_body_def_id: Table<DefIndex, RawDefId>,
     eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>,
     trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index be34c7ef4bd..644cdac5d55 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -89,6 +89,7 @@ rustc_query_append!(define_dep_nodes![
     /// We use this to create a forever-red node.
     [] fn Red() -> (),
     [] fn SideEffect() -> (),
+    [] fn AnonZeroDeps() -> (),
     [] fn TraitSelect() -> (),
     [] fn CompileCodegenUnit() -> (),
     [] fn CompileMonoItem() -> (),
diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index 739c0be1a91..931d67087ac 100644
--- a/compiler/rustc_middle/src/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
@@ -53,6 +53,7 @@ impl Deps for DepsType {
     const DEP_KIND_NULL: DepKind = dep_kinds::Null;
     const DEP_KIND_RED: DepKind = dep_kinds::Red;
     const DEP_KIND_SIDE_EFFECT: DepKind = dep_kinds::SideEffect;
+    const DEP_KIND_ANON_ZERO_DEPS: DepKind = dep_kinds::AnonZeroDeps;
     const DEP_KIND_MAX: u16 = dep_node::DEP_KIND_VARIANTS - 1;
 }
 
diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs
index 52f155a16b8..21ab06c98a7 100644
--- a/compiler/rustc_middle/src/hir/map.rs
+++ b/compiler/rustc_middle/src/hir/map.rs
@@ -22,6 +22,7 @@ use crate::ty::TyCtxt;
 // 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).
+#[allow(unused)] // FIXME: temporary
 #[derive(Copy, Clone)]
 pub struct Map<'hir> {
     pub(super) tcx: TyCtxt<'hir>,
@@ -273,7 +274,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self.hir_maybe_body_owned_by(id).unwrap_or_else(|| {
             let hir_id = self.local_def_id_to_hir_id(id);
             span_bug!(
-                self.hir().span(hir_id),
+                self.hir_span(hir_id),
                 "body_owned_by: {} has no associated body",
                 self.hir_id_to_string(hir_id)
             );
@@ -367,10 +368,6 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn hir_trait_impls(self, trait_did: DefId) -> &'tcx [LocalDefId] {
-        self.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..])
-    }
-
     /// Gets the attributes on the crate. This is preferable to
     /// invoking `krate.attrs` because it registers a tighter
     /// dep-graph access.
@@ -681,9 +678,8 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn hir_id_to_string(self, id: HirId) -> String {
         let path_str = |def_id: LocalDefId| self.def_path_str(def_id);
 
-        let span_str = || {
-            self.sess.source_map().span_to_snippet(Map { tcx: self }.span(id)).unwrap_or_default()
-        };
+        let span_str =
+            || self.sess.source_map().span_to_snippet(self.hir_span(id)).unwrap_or_default();
         let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
 
         match self.hir_node(id) {
@@ -879,12 +875,10 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn hir_attrs(self, id: HirId) -> &'tcx [Attribute] {
         self.hir_attr_map(id.owner).get(id.local_id)
     }
-}
 
-impl<'hir> Map<'hir> {
     /// Gets the span of the definition of the specified HIR node.
     /// This is used by `tcx.def_span`.
-    pub fn span(self, hir_id: HirId) -> Span {
+    pub fn hir_span(self, hir_id: HirId) -> Span {
         fn until_within(outer: Span, end: Span) -> Span {
             if let Some(end) = end.find_ancestor_inside(outer) {
                 outer.with_hi(end.hi())
@@ -904,7 +898,7 @@ impl<'hir> Map<'hir> {
             span
         }
 
-        let span = match self.tcx.hir_node(hir_id) {
+        let span = match self.hir_node(hir_id) {
             // Function-like.
             Node::Item(Item { kind: ItemKind::Fn { sig, .. }, span: outer_span, .. })
             | Node::TraitItem(TraitItem {
@@ -984,7 +978,7 @@ impl<'hir> Map<'hir> {
             Node::Variant(variant) => named_span(variant.span, variant.ident, None),
             Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
             Node::ForeignItem(item) => named_span(item.span, item.ident, None),
-            Node::Ctor(_) => return self.span(self.tcx.parent_hir_id(hir_id)),
+            Node::Ctor(_) => return self.hir_span(self.parent_hir_id(hir_id)),
             Node::Expr(Expr {
                 kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
                 span,
@@ -993,16 +987,16 @@ impl<'hir> Map<'hir> {
                 // Ensure that the returned span has the item's SyntaxContext.
                 fn_decl_span.find_ancestor_inside(*span).unwrap_or(*span)
             }
-            _ => self.span_with_body(hir_id),
+            _ => self.hir_span_with_body(hir_id),
         };
-        debug_assert_eq!(span.ctxt(), self.span_with_body(hir_id).ctxt());
+        debug_assert_eq!(span.ctxt(), self.hir_span_with_body(hir_id).ctxt());
         span
     }
 
-    /// Like `hir.span()`, but includes the body of items
+    /// 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.tcx.hir_node(hir_id) {
+    pub fn hir_span_with_body(self, hir_id: HirId) -> Span {
+        match self.hir_node(hir_id) {
             Node::Param(param) => param.span,
             Node::Item(item) => item.span,
             Node::ForeignItem(foreign_item) => foreign_item.span,
@@ -1011,7 +1005,7 @@ impl<'hir> Map<'hir> {
             Node::Variant(variant) => variant.span,
             Node::Field(field) => field.span,
             Node::AnonConst(constant) => constant.span,
-            Node::ConstBlock(constant) => self.tcx.hir_body(constant.body).value.span,
+            Node::ConstBlock(constant) => self.hir_body(constant.body).value.span,
             Node::ConstArg(const_arg) => const_arg.span(),
             Node::Expr(expr) => expr.span,
             Node::ExprField(field) => field.span,
@@ -1031,7 +1025,7 @@ impl<'hir> Map<'hir> {
             Node::PatExpr(lit) => lit.span,
             Node::Arm(arm) => arm.span,
             Node::Block(block) => block.span,
-            Node::Ctor(..) => self.span_with_body(self.tcx.parent_hir_id(hir_id)),
+            Node::Ctor(..) => self.hir_span_with_body(self.parent_hir_id(hir_id)),
             Node::Lifetime(lifetime) => lifetime.ident.span,
             Node::GenericParam(param) => param.span,
             Node::Infer(i) => i.span,
@@ -1044,23 +1038,23 @@ impl<'hir> Map<'hir> {
         }
     }
 
-    pub fn span_if_local(self, id: DefId) -> Option<Span> {
-        id.is_local().then(|| self.tcx.def_span(id))
+    pub fn hir_span_if_local(self, id: DefId) -> Option<Span> {
+        id.is_local().then(|| self.def_span(id))
     }
 
-    pub fn res_span(self, res: Res) -> Option<Span> {
+    pub fn hir_res_span(self, res: Res) -> Option<Span> {
         match res {
             Res::Err => None,
-            Res::Local(id) => Some(self.span(id)),
-            res => self.span_if_local(res.opt_def_id()?),
+            Res::Local(id) => Some(self.hir_span(id)),
+            res => self.hir_span_if_local(res.opt_def_id()?),
         }
     }
 
     /// Returns the HirId of `N` in `struct Foo<const N: usize = { ... }>` when
     /// called with the HirId for the `{ ... }` anon const
-    pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option<LocalDefId> {
-        let const_arg = self.tcx.parent_hir_id(anon_const);
-        match self.tcx.parent_hir_node(const_arg) {
+    pub fn hir_opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option<LocalDefId> {
+        let const_arg = self.parent_hir_id(anon_const);
+        match self.parent_hir_node(const_arg) {
             Node::GenericParam(GenericParam {
                 def_id: param_id,
                 kind: GenericParamKind::Const { .. },
@@ -1070,7 +1064,7 @@ impl<'hir> Map<'hir> {
         }
     }
 
-    pub fn maybe_get_struct_pattern_shorthand_field(&self, expr: &Expr<'_>) -> Option<Symbol> {
+    pub fn hir_maybe_get_struct_pattern_shorthand_field(self, expr: &Expr<'_>) -> Option<Symbol> {
         let local = match expr {
             Expr {
                 kind:
@@ -1085,7 +1079,7 @@ impl<'hir> Map<'hir> {
             _ => None,
         }?;
 
-        match self.tcx.parent_hir_node(expr.hir_id) {
+        match self.parent_hir_node(expr.hir_id) {
             Node::ExprField(field) => {
                 if field.ident.name == local.name && field.is_shorthand {
                     return Some(local.name);
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 347bc5ea312..74369b6636c 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -210,13 +210,12 @@ pub fn provide(providers: &mut Providers) {
     providers.hir_attr_map = |tcx, id| {
         tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
     };
-    providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
+    providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id));
     providers.def_ident_span = |tcx, def_id| {
         let hir_id = tcx.local_def_id_to_hir_id(def_id);
         tcx.hir_opt_ident_span(hir_id)
     };
     providers.fn_arg_names = |tcx, def_id| {
-        let hir = tcx.hir();
         if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() {
             tcx.arena.alloc_from_iter(tcx.hir_body_param_names(body_id))
         } else if let Node::TraitItem(&TraitItem {
@@ -231,13 +230,15 @@ pub fn provide(providers: &mut Providers) {
             idents
         } else {
             span_bug!(
-                hir.span(tcx.local_def_id_to_hir_id(def_id)),
+                tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)),
                 "fn_arg_names: unexpected item {:?}",
                 def_id
             );
         }
     };
     providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
+    providers.local_trait_impls =
+        |tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
     providers.expn_that_defined =
         |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
     providers.in_scope_traits_map = |tcx, id| {
diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs
index 316ad80eb98..60ce8544aa0 100644
--- a/compiler/rustc_middle/src/hir/place.rs
+++ b/compiler/rustc_middle/src/hir/place.rs
@@ -53,7 +53,10 @@ pub struct Projection<'tcx> {
     pub kind: ProjectionKind,
 }
 
-/// A `Place` represents how a value is located in memory.
+/// A `Place` represents how a value is located in memory. This does not
+/// always correspond to a syntactic place expression. For example, when
+/// processing a pattern, a `Place` can be used to refer to the sub-value
+/// currently being inspected.
 ///
 /// This is an HIR version of [`rustc_middle::mir::Place`].
 #[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
@@ -67,7 +70,10 @@ pub struct Place<'tcx> {
     pub projections: Vec<Projection<'tcx>>,
 }
 
-/// A `PlaceWithHirId` represents how a value is located in memory.
+/// A `PlaceWithHirId` represents how a value is located in memory. This does not
+/// always correspond to a syntactic place expression. For example, when
+/// processing a pattern, a `Place` can be used to refer to the sub-value
+/// currently being inspected.
 ///
 /// This is an HIR version of [`rustc_middle::mir::Place`].
 #[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 88bf17070b9..d5a408fdfa6 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -51,8 +51,13 @@ impl LintLevelSource {
     }
 }
 
-/// A tuple of a lint level and its source.
-pub type LevelAndSource = (Level, LintLevelSource);
+/// Convenience helper for moving things around together that frequently are paired
+#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
+pub struct LevelAndSource {
+    pub level: Level,
+    pub lint_id: Option<LintExpectationId>,
+    pub src: LintLevelSource,
+}
 
 /// Return type for the `shallow_lint_levels_on` query.
 ///
@@ -69,14 +74,18 @@ pub struct ShallowLintLevelMap {
 ///
 /// The return of this function is suitable for diagnostics.
 pub fn reveal_actual_level(
-    level: Option<Level>,
+    level: Option<(Level, Option<LintExpectationId>)>,
     src: &mut LintLevelSource,
     sess: &Session,
     lint: LintId,
-    probe_for_lint_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource),
-) -> Level {
+    probe_for_lint_level: impl FnOnce(
+        LintId,
+    )
+        -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource),
+) -> (Level, Option<LintExpectationId>) {
     // If `level` is none then we actually assume the default level for this lint.
-    let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition()));
+    let (mut level, mut lint_id) =
+        level.unwrap_or_else(|| (lint.lint.default_level(sess.edition()), None));
 
     // If we're about to issue a warning, check at the last minute for any
     // directives against the warnings "lint". If, for example, there's an
@@ -88,16 +97,17 @@ pub fn reveal_actual_level(
     // future compatibility warning.
     if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
         let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
-        if let Some(configured_warning_level) = warnings_level {
+        if let Some((configured_warning_level, configured_lint_id)) = warnings_level {
             if configured_warning_level != Level::Warn {
                 level = configured_warning_level;
+                lint_id = configured_lint_id;
                 *src = warnings_src;
             }
         }
     }
 
     // Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn
-    level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src {
+    level = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = src {
         level
     } else {
         cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
@@ -108,7 +118,7 @@ pub fn reveal_actual_level(
         level = cmp::min(*driver_level, level);
     }
 
-    level
+    (level, lint_id)
 }
 
 impl ShallowLintLevelMap {
@@ -121,11 +131,11 @@ impl ShallowLintLevelMap {
         tcx: TyCtxt<'_>,
         id: LintId,
         start: HirId,
-    ) -> (Option<Level>, LintLevelSource) {
+    ) -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource) {
         if let Some(map) = self.specs.get(&start.local_id)
-            && let Some(&(level, src)) = map.get(&id)
+            && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
         {
-            return (Some(level), src);
+            return (Some((level, lint_id)), src);
         }
 
         let mut owner = start.owner;
@@ -137,9 +147,9 @@ impl ShallowLintLevelMap {
                 specs = &tcx.shallow_lint_levels_on(owner).specs;
             }
             if let Some(map) = specs.get(&parent.local_id)
-                && let Some(&(level, src)) = map.get(&id)
+                && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
             {
-                return (Some(level), src);
+                return (Some((level, lint_id)), src);
             }
         }
 
@@ -153,18 +163,18 @@ impl ShallowLintLevelMap {
         tcx: TyCtxt<'_>,
         lint: LintId,
         cur: HirId,
-    ) -> (Level, LintLevelSource) {
+    ) -> LevelAndSource {
         let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur);
-        let level = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
+        let (level, lint_id) = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
             self.probe_for_lint_level(tcx, lint, cur)
         });
-        (level, src)
+        LevelAndSource { level, lint_id, src }
     }
 }
 
 impl TyCtxt<'_> {
     /// Fetch and return the user-visible lint level for the given lint at the given HirId.
-    pub fn lint_level_at_node(self, lint: &'static Lint, id: HirId) -> (Level, LintLevelSource) {
+    pub fn lint_level_at_node(self, lint: &'static Lint, id: HirId) -> LevelAndSource {
         self.shallow_lint_levels_on(id.owner).lint_level_id_at_node(self, LintId::of(lint), id)
     }
 }
@@ -267,8 +277,7 @@ fn explain_lint_level_source(
 pub fn lint_level(
     sess: &Session,
     lint: &'static Lint,
-    level: Level,
-    src: LintLevelSource,
+    level: LevelAndSource,
     span: Option<MultiSpan>,
     decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
 ) {
@@ -278,11 +287,12 @@ pub fn lint_level(
     fn lint_level_impl(
         sess: &Session,
         lint: &'static Lint,
-        level: Level,
-        src: LintLevelSource,
+        level: LevelAndSource,
         span: Option<MultiSpan>,
         decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)>,
     ) {
+        let LevelAndSource { level, lint_id, src } = level;
+
         // Check for future incompatibility lints and issue a stronger warning.
         let future_incompatible = lint.future_incompatible;
 
@@ -301,7 +311,7 @@ pub fn lint_level(
                     return;
                 }
             }
-            Level::Expect(expect_id) => {
+            Level::Expect => {
                 // This case is special as we actually allow the lint itself in this context, but
                 // we can't return early like in the case for `Level::Allow` because we still
                 // need the lint diagnostic to be emitted to `rustc_error::DiagCtxtInner`.
@@ -309,10 +319,9 @@ pub fn lint_level(
                 // We can also not mark the lint expectation as fulfilled here right away, as it
                 // can still be cancelled in the decorate function. All of this means that we simply
                 // create a `Diag` and continue as we would for warnings.
-                rustc_errors::Level::Expect(expect_id)
+                rustc_errors::Level::Expect
             }
-            Level::ForceWarn(Some(expect_id)) => rustc_errors::Level::ForceWarning(Some(expect_id)),
-            Level::ForceWarn(None) => rustc_errors::Level::ForceWarning(None),
+            Level::ForceWarn => rustc_errors::Level::ForceWarning,
             Level::Warn => rustc_errors::Level::Warning,
             Level::Deny | Level::Forbid => rustc_errors::Level::Error,
         };
@@ -320,6 +329,9 @@ pub fn lint_level(
         if let Some(span) = span {
             err.span(span);
         }
+        if let Some(lint_id) = lint_id {
+            err.lint_id(lint_id);
+        }
 
         // If this code originates in a foreign macro, aka something that this crate
         // did not itself author, then it's likely that there's nothing this crate
@@ -350,7 +362,7 @@ pub fn lint_level(
         // the compiler. It is therefore not necessary to add any information for the user.
         // This will therefore directly call the decorate function which will in turn emit
         // the diagnostic.
-        if let Level::Expect(_) = level {
+        if let Level::Expect = level {
             decorate(&mut err);
             err.emit();
             return;
@@ -419,5 +431,5 @@ pub fn lint_level(
         explain_lint_level_source(lint, level, src, &mut err);
         err.emit()
     }
-    lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
+    lint_level_impl(sess, lint, level, span, Box::new(decorate))
 }
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 0cc72a261a5..00da1a6aeec 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -172,6 +172,8 @@ impl CodegenFnAttrs {
     /// * `#[no_mangle]` is present
     /// * `#[export_name(...)]` is present
     /// * `#[linkage]` is present
+    ///
+    /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint.
     pub fn contains_extern_indicator(&self) -> bool {
         self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
             || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 66ece8f0e52..92eab59dd02 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -175,7 +175,7 @@ impl Scope {
         let Some(hir_id) = self.hir_id(scope_tree) else {
             return DUMMY_SP;
         };
-        let span = tcx.hir().span(hir_id);
+        let span = tcx.hir_span(hir_id);
         if let ScopeData::Remainder(first_statement_index) = self.data {
             if let Node::Block(blk) = tcx.hir_node(hir_id) {
                 // Want span for scope starting after the
@@ -199,8 +199,6 @@ impl Scope {
     }
 }
 
-pub type ScopeDepth = u32;
-
 /// The region scope tree encodes information about region relationships.
 #[derive(Default, Debug, HashStable)]
 pub struct ScopeTree {
@@ -213,7 +211,7 @@ pub struct ScopeTree {
     /// conditional expression or repeating block. (Note that the
     /// enclosing scope ID for the block associated with a closure is
     /// the closure itself.)
-    pub parent_map: FxIndexMap<Scope, (Scope, ScopeDepth)>,
+    pub parent_map: FxIndexMap<Scope, Scope>,
 
     /// Maps from a variable or binding ID to the block in which that
     /// variable is declared.
@@ -328,7 +326,7 @@ pub struct YieldData {
 }
 
 impl ScopeTree {
-    pub fn record_scope_parent(&mut self, child: Scope, parent: Option<(Scope, ScopeDepth)>) {
+    pub fn record_scope_parent(&mut self, child: Scope, parent: Option<Scope>) {
         debug!("{:?}.parent = {:?}", child, parent);
 
         if let Some(p) = parent {
@@ -353,7 +351,7 @@ impl ScopeTree {
 
     /// Returns the narrowest scope that encloses `id`, if any.
     pub fn opt_encl_scope(&self, id: Scope) -> Option<Scope> {
-        self.parent_map.get(&id).cloned().map(|(p, _)| p)
+        self.parent_map.get(&id).cloned()
     }
 
     /// Returns the lifetime of the local variable `var_id`, if any.
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index ec128c8c478..9912e659b05 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -255,7 +255,7 @@ fn late_report_deprecation(
     // Calculating message for lint involves calling `self.def_path_str`,
     // which will by default invoke the expensive `visible_parent_map` query.
     // Skip all that work if the lint is allowed anyway.
-    if tcx.lint_level_at_node(lint, hir_id).0 == Level::Allow {
+    if tcx.lint_level_at_node(lint, hir_id).level == Level::Allow {
         return;
     }
 
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 83ada5c8afb..1ffe958dbdd 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -150,6 +150,7 @@ impl<'tcx> MonoItem<'tcx> {
 
         // If the function is #[naked] or contains any other attribute that requires exactly-once
         // instantiation:
+        // We emit an unused_attributes lint for this case, which should be kept in sync if possible.
         let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
         if codegen_fn_attrs.contains_extern_indicator()
             || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 4f86703e953..707c8d04d55 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -334,14 +334,19 @@ pub enum StatementKind<'tcx> {
     /// See [`Rvalue`] documentation for details on each of those.
     Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
 
-    /// This represents all the reading that a pattern match may do (e.g., inspecting constants and
-    /// discriminant values), and the kind of pattern it comes from. This is in order to adapt
-    /// potential error messages to these specific patterns.
+    /// When executed at runtime, this is a nop.
     ///
-    /// Note that this also is emitted for regular `let` bindings to ensure that locals that are
-    /// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
+    /// During static analysis, a fake read:
+    /// - requires that the value being read is initialized (or, in the case
+    ///   of closures, that it was fully initialized at some point in the past)
+    /// - constitutes a use of a value for the purposes of NLL (i.e. if the
+    ///   value being fake-read is a reference, the lifetime of that reference
+    ///   will be extended to cover the `FakeRead`)
+    /// - but, unlike an actual read, does *not* invalidate any exclusive
+    ///   borrows.
     ///
-    /// When executed at runtime this is a nop.
+    /// See [`FakeReadCause`] for more details on the situations in which a
+    /// `FakeRead` is emitted.
     ///
     /// Disallowed after drop elaboration.
     FakeRead(Box<(FakeReadCause, Place<'tcx>)>),
@@ -518,28 +523,59 @@ pub enum RetagKind {
 /// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, Hash, HashStable, PartialEq)]
 pub enum FakeReadCause {
-    /// Inject a fake read of the borrowed input at the end of each guards
-    /// code.
+    /// A fake read injected into a match guard to ensure that the discriminants
+    /// that are being matched on aren't modified while the match guard is being
+    /// evaluated.
+    ///
+    /// At the beginning of each match guard, a [fake borrow][FakeBorrowKind] is
+    /// inserted for each discriminant accessed in the entire `match` statement.
+    ///
+    /// Then, at the end of the match guard, a `FakeRead(ForMatchGuard)` is
+    /// inserted to keep the fake borrows alive until that point.
     ///
     /// This should ensure that you cannot change the variant for an enum while
     /// you are in the midst of matching on it.
     ForMatchGuard,
 
-    /// `let x: !; match x {}` doesn't generate any read of x so we need to
-    /// generate a read of x to check that it is initialized and safe.
+    /// Fake read of the scrutinee of a `match` or destructuring `let`
+    /// (i.e. `let` with non-trivial pattern).
+    ///
+    /// In `match x { ... }`, we generate a `FakeRead(ForMatchedPlace, x)`
+    /// and insert it into the `otherwise_block` (which is supposed to be
+    /// unreachable for irrefutable pattern-matches like `match` or `let`).
+    ///
+    /// This is necessary because `let x: !; match x {}` doesn't generate any
+    /// actual read of x, so we need to generate a `FakeRead` to check that it
+    /// is initialized.
+    ///
+    /// If the `FakeRead(ForMatchedPlace)` is being performed with a closure
+    /// that doesn't capture the required upvars, the `FakeRead` within the
+    /// closure is omitted entirely.
     ///
-    /// If a closure pattern matches a Place starting with an Upvar, then we introduce a
-    /// FakeRead for that Place outside the closure, in such a case this option would be
-    /// Some(closure_def_id).
-    /// Otherwise, the value of the optional LocalDefId will be None.
+    /// To make sure that this is still sound, if a closure matches against
+    /// a Place starting with an Upvar, we hoist the `FakeRead` to the
+    /// definition point of the closure.
+    ///
+    /// If the `FakeRead` comes from being hoisted out of a closure like this,
+    /// we record the `LocalDefId` of the closure. Otherwise, the `Option` will be `None`.
     //
     // We can use LocalDefId here since fake read statements are removed
     // before codegen in the `CleanupNonCodegenStatements` pass.
     ForMatchedPlace(Option<LocalDefId>),
 
-    /// A fake read of the RefWithinGuard version of a bind-by-value variable
-    /// in a match guard to ensure that its value hasn't change by the time
-    /// we create the OutsideGuard version.
+    /// A fake read injected into a match guard to ensure that the places
+    /// bound by the pattern are immutable for the duration of the match guard.
+    ///
+    /// Within a match guard, references are created for each place that the
+    /// pattern creates a binding for — this is known as the `RefWithinGuard`
+    /// version of the variables. To make sure that the references stay
+    /// alive until the end of the match guard, and properly prevent the
+    /// places in question from being modified, a `FakeRead(ForGuardBinding)`
+    /// is inserted at the end of the match guard.
+    ///
+    /// For details on how these references are created, see the extensive
+    /// documentation on `bind_matched_candidate_for_guard` in
+    /// `rustc_mir_build`.
     ForGuardBinding,
 
     /// Officially, the semantics of
@@ -552,22 +588,42 @@ pub enum FakeReadCause {
     /// However, if we see the simple pattern `let var = <expr>`, we optimize this to
     /// evaluate `<expr>` directly into the variable `var`. This is mostly unobservable,
     /// but in some cases it can affect the borrow checker, as in #53695.
-    /// Therefore, we insert a "fake read" here to ensure that we get
-    /// appropriate errors.
     ///
-    /// If a closure pattern matches a Place starting with an Upvar, then we introduce a
-    /// FakeRead for that Place outside the closure, in such a case this option would be
-    /// Some(closure_def_id).
-    /// Otherwise, the value of the optional DefId will be None.
+    /// Therefore, we insert a `FakeRead(ForLet)` immediately after each `let`
+    /// with a trivial pattern.
+    ///
+    /// FIXME: `ExprUseVisitor` has an entirely different opinion on what `FakeRead(ForLet)`
+    /// is supposed to mean. If it was accurate to what MIR lowering does,
+    /// would it even make sense to hoist these out of closures like
+    /// `ForMatchedPlace`?
     ForLet(Option<LocalDefId>),
 
-    /// If we have an index expression like
+    /// Currently, index expressions overloaded through the `Index` trait
+    /// get lowered differently than index expressions with builtin semantics
+    /// for arrays and slices — the latter will emit code to perform
+    /// bound checks, and then return a MIR place that will only perform the
+    /// indexing "for real" when it gets incorporated into an instruction.
     ///
-    /// (*x)[1][{ x = y; 4}]
+    /// This is observable in the fact that the following compiles:
     ///
-    /// then the first bounds check is invalidated when we evaluate the second
-    /// index expression. Thus we create a fake borrow of `x` across the second
-    /// indexer, which will cause a borrow check error.
+    /// ```
+    /// fn f(x: &mut [&mut [u32]], i: usize) {
+    ///     x[i][x[i].len() - 1] += 1;
+    /// }
+    /// ```
+    ///
+    /// However, we need to be careful to not let the user invalidate the
+    /// bound check with an expression like
+    ///
+    /// `(*x)[1][{ x = y; 4}]`
+    ///
+    /// Here, the first bounds check would be invalidated when we evaluate the
+    /// second index expression. To make sure that this doesn't happen, we
+    /// create a fake borrow of `x` and hold it while we evaluate the second
+    /// index.
+    ///
+    /// This borrow is kept alive by a `FakeRead(ForIndex)` at the end of its
+    /// scope.
     ForIndex,
 }
 
@@ -1612,6 +1668,42 @@ pub enum BinOp {
     Offset,
 }
 
+// Assignment operators, e.g. `+=`. See comments on the corresponding variants
+// in `BinOp` for details.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum AssignOp {
+    AddAssign,
+    SubAssign,
+    MulAssign,
+    DivAssign,
+    RemAssign,
+    BitXorAssign,
+    BitAndAssign,
+    BitOrAssign,
+    ShlAssign,
+    ShrAssign,
+}
+
+// Sometimes `BinOp` and `AssignOp` need the same treatment. The operations
+// covered by `AssignOp` are a subset of those covered by `BinOp`, so it makes
+// sense to convert `AssignOp` to `BinOp`.
+impl From<AssignOp> for BinOp {
+    fn from(op: AssignOp) -> BinOp {
+        match op {
+            AssignOp::AddAssign => BinOp::Add,
+            AssignOp::SubAssign => BinOp::Sub,
+            AssignOp::MulAssign => BinOp::Mul,
+            AssignOp::DivAssign => BinOp::Div,
+            AssignOp::RemAssign => BinOp::Rem,
+            AssignOp::BitXorAssign => BinOp::BitXor,
+            AssignOp::BitAndAssign => BinOp::BitAnd,
+            AssignOp::BitOrAssign => BinOp::BitOr,
+            AssignOp::ShlAssign => BinOp::Shl,
+            AssignOp::ShrAssign => BinOp::Shr,
+        }
+    }
+}
+
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
 #[cfg(target_pointer_width = "64")]
 mod size_asserts {
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index c382bcd726f..9ed1f10455a 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -586,7 +586,7 @@ impl Key for HirId {
     type Cache<V> = DefaultCache<Self, V>;
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.hir().span(*self)
+        tcx.hir_span(*self)
     }
 
     #[inline(always)]
@@ -599,7 +599,7 @@ impl Key for (LocalDefId, HirId) {
     type Cache<V> = DefaultCache<Self, V>;
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.hir().span(self.1)
+        tcx.hir_span(self.1)
     }
 
     #[inline(always)]
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d7ed703f4ae..0d5fba3cc69 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -267,6 +267,8 @@ rustc_queries! {
     ///
     /// This is a specialized instance of [`Self::type_of`] that detects query cycles.
     /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead.
+    /// This is used to improve the error message in cases where revealing the hidden type
+    /// for auto-trait leakage cycles.
     ///
     /// # Panics
     ///
@@ -278,6 +280,12 @@ rustc_queries! {
         }
         cycle_stash
     }
+    query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
+        desc { |tcx|
+            "computing type of opaque `{path}` via HIR typeck",
+            path = tcx.def_path_str(key),
+        }
+    }
 
     /// Returns whether the type alias given by `DefId` is lazy.
     ///
@@ -612,6 +620,7 @@ rustc_queries! {
 
     query check_coroutine_obligations(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) }
+        return_result_from_ensure_ok
     }
 
     /// MIR after our optimization passes have run. This is MIR that is ready
@@ -1033,13 +1042,12 @@ rustc_queries! {
     /// Unsafety-check this `LocalDefId`.
     query check_unsafety(key: LocalDefId) {
         desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) }
-        cache_on_disk_if { true }
     }
 
     /// Checks well-formedness of tail calls (`become f()`).
     query check_tail_calls(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
         desc { |tcx| "tail-call-checking `{}`", tcx.def_path_str(key) }
-        cache_on_disk_if { true }
+        return_result_from_ensure_ok
     }
 
     /// Returns the types assumed to be well formed while "inside" of the given item.
@@ -1308,7 +1316,7 @@ rustc_queries! {
 
     query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
         desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) }
-        cache_on_disk_if { true }
+        return_result_from_ensure_ok
     }
 
     /// Performs part of the privacy check and computes effective visibilities.
@@ -1502,6 +1510,11 @@ rustc_queries! {
         desc { "finding local trait impls" }
     }
 
+    /// Return all `impl` blocks of the given trait in the current crate.
+    query local_trait_impls(trait_id: DefId) -> &'tcx [LocalDefId] {
+        desc { "finding local trait impls of `{}`", tcx.def_path_str(trait_id) }
+    }
+
     /// Given a trait `trait_id`, return all known `impl` blocks.
     query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls {
         arena_cache
@@ -1602,7 +1615,6 @@ rustc_queries! {
     /// `Err(AlwaysRequiresDrop)` is returned.
     query adt_significant_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
         desc { |tcx| "computing when `{}` has a significant destructor", tcx.def_path_str(def_id) }
-        cache_on_disk_if { false }
     }
 
     /// Returns a list of types which (a) have a potentially significant destructor
@@ -1624,7 +1636,6 @@ rustc_queries! {
     /// Otherwise, there is a risk of query cycles.
     query list_significant_drop_tys(ty: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> &'tcx ty::List<Ty<'tcx>> {
         desc { |tcx| "computing when `{}` has a significant destructor", ty.value }
-        cache_on_disk_if { false }
     }
 
     /// Computes the layout of a type. Note that this implicitly
@@ -2512,7 +2523,6 @@ rustc_queries! {
     /// monomorphized.
     query check_mono_item(key: ty::Instance<'tcx>) {
         desc { "monomorphization-time checking" }
-        cache_on_disk_if { true }
     }
 
     /// Builds the set of functions that should be skipped for the move-size check.
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index 14e3ce8bef6..c6ecc679b7b 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -16,7 +16,8 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixed
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_session::Session;
 use rustc_span::hygiene::{
-    ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
+    ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext,
+    SyntaxContextDataNonRecursive as SyntaxContextData,
 };
 use rustc_span::source_map::Spanned;
 use rustc_span::{
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 6783bbf8bf4..8d373cb3b30 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -27,7 +27,7 @@ use tracing::instrument;
 
 use crate::middle::region;
 use crate::mir::interpret::AllocId;
-use crate::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
+use crate::mir::{self, AssignOp, BinOp, BorrowKind, FakeReadCause, UnOp};
 use crate::thir::visit::for_each_immediate_subpat;
 use crate::ty::adjustment::PointerCoercion;
 use crate::ty::layout::IntegerExt;
@@ -403,7 +403,7 @@ pub enum ExprKind<'tcx> {
     },
     /// A *non-overloaded* operation assignment, e.g. `lhs += rhs`.
     AssignOp {
-        op: BinOp,
+        op: AssignOp,
         lhs: ExprId,
         rhs: ExprId,
     },
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index 811bd8fb458..aa2ee756bc5 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -95,10 +95,16 @@ pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>),
 /// parameter environment.
 #[derive(PartialEq, Eq, Debug, Clone, TypeVisitable)]
 pub enum SelectionCandidate<'tcx> {
+    /// A built-in implementation for the `Sized` trait. This is preferred
+    /// over all other candidates.
+    SizedCandidate {
+        has_nested: bool,
+    },
+
     /// A builtin implementation for some specific traits, used in cases
     /// where we cannot rely an ordinary library implementations.
     ///
-    /// The most notable examples are `sized`, `Copy` and `Clone`. This is also
+    /// The most notable examples are `Copy` and `Clone`. This is also
     /// used for the `DiscriminantKind` and `Pointee` trait, both of which have
     /// an associated type.
     BuiltinCandidate {
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index cb245c0aec4..00fe5cb0c5d 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -236,7 +236,7 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
     }
 
     fn destructor(self, tcx: TyCtxt<'tcx>) -> Option<AdtDestructorKind> {
-        Some(match self.destructor(tcx)?.constness {
+        Some(match tcx.constness(self.destructor(tcx)?.did) {
             hir::Constness::Const => AdtDestructorKind::Const,
             hir::Constness::NotConst => AdtDestructorKind::NotConst,
         })
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 703b6ce9247..ff9096695d4 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -150,9 +150,9 @@ impl<'tcx> CapturedPlace<'tcx> {
     /// Return span pointing to use that resulted in selecting the captured path
     pub fn get_path_span(&self, tcx: TyCtxt<'tcx>) -> Span {
         if let Some(path_expr_id) = self.info.path_expr_id {
-            tcx.hir().span(path_expr_id)
+            tcx.hir_span(path_expr_id)
         } else if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id {
-            tcx.hir().span(capture_kind_expr_id)
+            tcx.hir_span(capture_kind_expr_id)
         } else {
             // Fallback on upvars mentioned if neither path or capture expr id is captured
 
@@ -166,9 +166,9 @@ impl<'tcx> CapturedPlace<'tcx> {
     /// Return span pointing to use that resulted in selecting the current capture kind
     pub fn get_capture_kind_span(&self, tcx: TyCtxt<'tcx>) -> Span {
         if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id {
-            tcx.hir().span(capture_kind_expr_id)
+            tcx.hir_span(capture_kind_expr_id)
         } else if let Some(path_expr_id) = self.info.path_expr_id {
-            tcx.hir().span(path_expr_id)
+            tcx.hir_span(path_expr_id)
         } else {
             // Fallback on upvars mentioned if neither path or capture expr id is captured
 
diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs
index 72263d84580..2f21d19e03c 100644
--- a/compiler/rustc_middle/src/ty/consts/valtree.rs
+++ b/compiler/rustc_middle/src/ty/consts/valtree.rs
@@ -33,7 +33,7 @@ pub enum ValTreeKind<'tcx> {
     /// The fields of any kind of aggregate. Structs, tuples and arrays are represented by
     /// listing their fields' values in order.
     ///
-    /// Enums are represented by storing their discriminant as a field, followed by all
+    /// Enums are represented by storing their variant index as a u32 field, followed by all
     /// the fields of the variant.
     ///
     /// ZST types are represented as an empty slice.
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 08d4c1f9cf2..162ca1f4af8 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -206,6 +206,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
         self.type_of(def_id)
     }
+    fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
+        self.type_of_opaque_hir_typeck(def_id)
+    }
 
     type AdtDef = ty::AdtDef<'tcx>;
     fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
@@ -446,6 +449,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
     }
 
+    fn is_default_trait(self, def_id: DefId) -> bool {
+        self.is_default_trait(def_id)
+    }
+
     fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
         lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
     }
@@ -1539,6 +1546,25 @@ impl<'tcx> TyCtxt<'tcx> {
         self.reserve_and_set_memory_dedup(alloc, salt)
     }
 
+    pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
+        match self.sess.opts.unstable_opts.experimental_default_bounds {
+            true => &[
+                LangItem::Sized,
+                LangItem::DefaultTrait1,
+                LangItem::DefaultTrait2,
+                LangItem::DefaultTrait3,
+                LangItem::DefaultTrait4,
+            ],
+            false => &[LangItem::Sized],
+        }
+    }
+
+    pub fn is_default_trait(self, def_id: DefId) -> bool {
+        self.default_traits()
+            .iter()
+            .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
+    }
+
     /// Returns a range of the start/end indices specified with the
     /// `rustc_layout_scalar_valid_range` attribute.
     // FIXME(eddyb) this is an awkward spot for this method, maybe move it?
@@ -1781,10 +1807,15 @@ impl<'tcx> TyCtxt<'tcx> {
         // - needs_metadata: for putting into crate metadata.
         // - instrument_coverage: for putting into coverage data (see
         //   `hash_mir_source`).
+        // - metrics_dir: metrics use the strict version hash in the filenames
+        //   for dumped metrics files to prevent overwriting distinct metrics
+        //   for similar source builds (may change in the future, this is part
+        //   of the proof of concept impl for the metrics initiative project goal)
         cfg!(debug_assertions)
             || self.sess.opts.incremental.is_some()
             || self.needs_metadata()
             || self.sess.instrument_coverage()
+            || self.sess.opts.unstable_opts.metrics_dir.is_some()
     }
 
     #[inline]
@@ -1930,10 +1961,10 @@ impl<'tcx> TyCtxt<'tcx> {
         // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
         // comp. engine itself.
         //
-        // This call also writes to the value of `source_span` and `expn_that_defined` queries.
+        // This call also writes to the value of the `source_span` query.
         // This is fine because:
-        // - those queries are `eval_always` so we won't miss their result changing;
-        // - this write will have happened before these queries are called.
+        // - that query is `eval_always` so we won't miss its result changing;
+        // - this write will have happened before that query is called.
         let def_id = self.untracked.definitions.write().create_def(parent, data);
 
         // This function modifies `self.definitions` using a side-effect.
@@ -3022,8 +3053,8 @@ impl<'tcx> TyCtxt<'tcx> {
         span: impl Into<MultiSpan>,
         decorator: impl for<'a> LintDiagnostic<'a, ()>,
     ) {
-        let (level, src) = self.lint_level_at_node(lint, hir_id);
-        lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
+        let level = self.lint_level_at_node(lint, hir_id);
+        lint_level(self.sess, lint, level, Some(span.into()), |lint| {
             decorator.decorate_lint(lint);
         })
     }
@@ -3040,8 +3071,8 @@ impl<'tcx> TyCtxt<'tcx> {
         span: impl Into<MultiSpan>,
         decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
     ) {
-        let (level, src) = self.lint_level_at_node(lint, hir_id);
-        lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
+        let level = self.lint_level_at_node(lint, hir_id);
+        lint_level(self.sess, lint, level, Some(span.into()), decorate);
     }
 
     /// Find the crate root and the appropriate span where `use` and outer attributes can be
@@ -3108,8 +3139,8 @@ impl<'tcx> TyCtxt<'tcx> {
         id: HirId,
         decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
     ) {
-        let (level, src) = self.lint_level_at_node(lint, id);
-        lint_level(self.sess, lint, level, src, None, decorate);
+        let level = self.lint_level_at_node(lint, id);
+        lint_level(self.sess, lint, level, None, decorate);
     }
 
     pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
@@ -3248,6 +3279,11 @@ impl<'tcx> TyCtxt<'tcx> {
         self.sess.opts.unstable_opts.next_solver.coherence
     }
 
+    #[allow(rustc::bad_opt_access)]
+    pub fn use_typing_mode_borrowck(self) -> bool {
+        self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
+    }
+
     pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
         self.opt_rpitit_info(def_id).is_some()
     }
diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs
index f25c48cf42a..8bddb5c0fd7 100644
--- a/compiler/rustc_middle/src/ty/erase_regions.rs
+++ b/compiler/rustc_middle/src/ty/erase_regions.rs
@@ -44,7 +44,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if ty.has_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) }
+        if !ty.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
+            ty
+        } else if ty.has_infer() {
+            ty.super_fold_with(self)
+        } else {
+            self.tcx.erase_regions_ty(ty)
+        }
     }
 
     fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
@@ -64,4 +70,20 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
             _ => self.tcx.lifetimes.re_erased,
         }
     }
+
+    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
+        if ct.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
+            ct.super_fold_with(self)
+        } else {
+            ct
+        }
+    }
+
+    fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
+        if p.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
+            p.super_fold_with(self)
+        } else {
+            p
+        }
+    }
 }
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index e3b3eccffb5..55ebd15248c 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -720,7 +720,7 @@ impl<'tcx> Instance<'tcx> {
             ty::TypingEnv::fully_monomorphized(),
             def_id,
             args,
-            ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP),
+            ty.ty_adt_def().and_then(|adt| tcx.hir_span_if_local(adt.did())).unwrap_or(DUMMY_SP),
         )
     }
 
@@ -732,7 +732,7 @@ impl<'tcx> Instance<'tcx> {
             ty::TypingEnv::fully_monomorphized(),
             def_id,
             args,
-            ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP),
+            ty.ty_adt_def().and_then(|adt| tcx.hir_span_if_local(adt.did())).unwrap_or(DUMMY_SP),
         )
     }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index ac98cbc8d6c..80f1bd7c6f4 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -48,7 +48,7 @@ use rustc_serialize::{Decodable, Encodable};
 use rustc_session::lint::LintBuffer;
 pub use rustc_session::lint::RegisteredTools;
 use rustc_span::hygiene::MacroKind;
-use rustc_span::{ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
+use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
 pub use rustc_type_ir::relate::VarianceDiagInfo;
 pub use rustc_type_ir::*;
 use tracing::{debug, instrument};
@@ -782,7 +782,22 @@ pub struct OpaqueHiddenType<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
+/// Whether we're currently in HIR typeck or MIR borrowck.
+#[derive(Debug, Clone, Copy)]
+pub enum DefiningScopeKind {
+    /// During writeback in typeck, we don't care about regions and simply
+    /// erase them. This means we also don't check whether regions are
+    /// universal in the opaque type key. This will only be checked in
+    /// MIR borrowck.
+    HirTypeck,
+    MirBorrowck,
+}
+
 impl<'tcx> OpaqueHiddenType<'tcx> {
+    pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> OpaqueHiddenType<'tcx> {
+        OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) }
+    }
+
     pub fn build_mismatch_error(
         &self,
         other: &Self,
@@ -808,8 +823,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
         self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
         tcx: TyCtxt<'tcx>,
-        // typeck errors have subpar spans for opaque types, so delay error reporting until borrowck.
-        ignore_errors: bool,
+        defining_scope_kind: DefiningScopeKind,
     ) -> Self {
         let OpaqueTypeKey { def_id, args } = opaque_type_key;
 
@@ -828,10 +842,19 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
         let map = args.iter().zip(id_args).collect();
         debug!("map = {:#?}", map);
 
-        // Convert the type from the function into a type valid outside
-        // the function, by replacing invalid regions with 'static,
-        // after producing an error for each of them.
-        self.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span, ignore_errors))
+        // Convert the type from the function into a type valid outside by mapping generic
+        // parameters to into the context of the opaque.
+        //
+        // We erase regions when doing this during HIR typeck.
+        let this = match defining_scope_kind {
+            DefiningScopeKind::HirTypeck => tcx.erase_regions(self),
+            DefiningScopeKind::MirBorrowck => self,
+        };
+        let result = this.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span));
+        if cfg!(debug_assertions) && matches!(defining_scope_kind, DefiningScopeKind::HirTypeck) {
+            assert_eq!(result.ty, tcx.erase_regions(result.ty));
+        }
+        result
     }
 }
 
@@ -953,7 +976,7 @@ impl<'tcx> rustc_type_ir::Flags for Clauses<'tcx> {
 /// environment. `ParamEnv` is the type that represents this information. See the
 /// [dev guide chapter][param_env_guide] for more information.
 ///
-/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
+/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 #[derive(HashStable, TypeVisitable, TypeFoldable)]
 pub struct ParamEnv<'tcx> {
@@ -977,7 +1000,7 @@ impl<'tcx> ParamEnv<'tcx> {
     /// to use an empty environment. See the [dev guide section][param_env_guide]
     /// for information on what a `ParamEnv` is and how to acquire one.
     ///
-    /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
+    /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html
     #[inline]
     pub fn empty() -> Self {
         Self::new(ListWithCachedTypeInfo::empty())
@@ -1119,17 +1142,13 @@ pub struct PseudoCanonicalInput<'tcx, T> {
 pub struct Destructor {
     /// The `DefId` of the destructor method
     pub did: DefId,
-    /// The constness of the destructor method
-    pub constness: hir::Constness,
 }
 
 // FIXME: consider combining this definition with regular `Destructor`
 #[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
 pub struct AsyncDestructor {
-    /// The `DefId` of the async destructor future constructor
-    pub ctor: DefId,
-    /// The `DefId` of the async destructor future type
-    pub future: DefId,
+    /// The `DefId` of the `impl AsyncDrop`
+    pub impl_did: LocalDefId,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 56c44c8a84c..c72efde0994 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -20,12 +20,6 @@ pub(super) struct ReverseMapper<'tcx> {
     /// for an explanation of this field.
     do_not_error: bool,
 
-    /// We do not want to emit any errors in typeck because
-    /// the spans in typeck are subpar at the moment.
-    /// Borrowck will do the same work again (this time with
-    /// lifetime information) and thus report better errors.
-    ignore_errors: bool,
-
     /// Span of function being checked.
     span: Span,
 }
@@ -35,9 +29,8 @@ impl<'tcx> ReverseMapper<'tcx> {
         tcx: TyCtxt<'tcx>,
         map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
         span: Span,
-        ignore_errors: bool,
     ) -> Self {
-        Self { tcx, map, do_not_error: false, ignore_errors, span }
+        Self { tcx, map, do_not_error: false, span }
     }
 
     fn fold_kind_no_missing_regions_error(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
@@ -176,20 +169,18 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
                     Some(u) => panic!("type mapped to unexpected kind: {u:?}"),
                     None => {
                         debug!(?param, ?self.map);
-                        if !self.ignore_errors {
-                            self.tcx
-                                .dcx()
-                                .struct_span_err(
-                                    self.span,
-                                    format!(
-                                        "type parameter `{ty}` is part of concrete type but not \
+                        let guar = self
+                            .tcx
+                            .dcx()
+                            .struct_span_err(
+                                self.span,
+                                format!(
+                                    "type parameter `{ty}` is part of concrete type but not \
                                           used in parameter list for the `impl Trait` type alias"
-                                    ),
-                                )
-                                .emit();
-                        }
-
-                        Ty::new_misc_error(self.tcx)
+                                ),
+                            )
+                            .emit();
+                        Ty::new_error(self.tcx, guar)
                     }
                 }
             }
@@ -217,8 +208,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
                                 ct: ct.to_string(),
                                 span: self.span,
                             })
-                            .emit_unless(self.ignore_errors);
-
+                            .emit();
                         ty::Const::new_error(self.tcx, guar)
                     }
                 }
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 19e2b574563..b56e0862692 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -65,9 +65,11 @@ trivially_parameterized_over_tcx! {
     crate::middle::lib_features::FeatureStability,
     crate::middle::resolve_bound_vars::ObjectLifetimeDefault,
     crate::mir::ConstQualifs,
+    ty::AsyncDestructor,
     ty::AssocItemContainer,
     ty::Asyncness,
     ty::DeducedParamAttrs,
+    ty::Destructor,
     ty::Generics,
     ty::ImplPolarity,
     ty::ImplTraitInTraitData,
@@ -111,7 +113,7 @@ trivially_parameterized_over_tcx! {
     rustc_span::Span,
     rustc_span::Symbol,
     rustc_span::def_id::DefPathHash,
-    rustc_span::hygiene::SyntaxContextData,
+    rustc_span::hygiene::SyntaxContextDataNonRecursive,
     rustc_span::Ident,
     rustc_type_ir::Variance,
     rustc_hir::Attribute,
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index dc2040aa5cf..5904deaaaad 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -139,8 +139,7 @@ pub trait Printer<'tcx>: Sized {
 
                     match key.disambiguated_data.data {
                         DefPathData::Closure => {
-                            // FIXME(async_closures): This is somewhat ugly.
-                            // We need to additionally print the `kind` field of a closure if
+                            // We need to additionally print the `kind` field of a coroutine if
                             // it is desugared from a coroutine-closure.
                             if let Some(hir::CoroutineKind::Desugared(
                                 _,
@@ -156,6 +155,10 @@ pub trait Printer<'tcx>: Sized {
                                 // Closures' own generics are only captures, don't print them.
                             }
                         }
+                        DefPathData::SyntheticCoroutineBody => {
+                            // Synthetic coroutine bodies have no distinct generics, since like
+                            // closures they're all just internal state of the coroutine.
+                        }
                         // This covers both `DefKind::AnonConst` and `DefKind::InlineConst`.
                         // Anon consts doesn't have their own generics, and inline consts' own
                         // generics are their inferred types, so don't print them.
diff --git a/compiler/rustc_middle/src/ty/rvalue_scopes.rs b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
index b00c8169a36..9bf6e3a7590 100644
--- a/compiler/rustc_middle/src/ty/rvalue_scopes.rs
+++ b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
@@ -38,7 +38,7 @@ impl RvalueScopes {
         let mut id = Scope { local_id: expr_id, data: ScopeData::Node };
         let mut backwards_incompatible = None;
 
-        while let Some(&(p, _)) = region_scope_tree.parent_map.get(&id) {
+        while let Some(&p) = region_scope_tree.parent_map.get(&id) {
             match p.data {
                 ScopeData::Destruction => {
                     debug!("temporary_scope({expr_id:?}) = {id:?} [enclosing]");
diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs
index 2d9e0331451..4881d611c12 100644
--- a/compiler/rustc_middle/src/ty/significant_drop_order.rs
+++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs
@@ -154,7 +154,7 @@ pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Span> {
             let dtor = if let Some(dtor) = tcx.adt_destructor(did) {
                 dtor.did
             } else if let Some(dtor) = tcx.adt_async_destructor(did) {
-                dtor.future
+                return Some(tcx.source_span(dtor.impl_did));
             } else {
                 return Some(try_local_did_span(did));
             };
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 60fd531b4d0..798ef352c40 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -86,15 +86,15 @@ impl fmt::Debug for ty::LateParamRegion {
 impl fmt::Debug for ty::LateParamRegionKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            ty::LateParamRegionKind::Anon(idx) => write!(f, "BrAnon({idx})"),
+            ty::LateParamRegionKind::Anon(idx) => write!(f, "LateAnon({idx})"),
             ty::LateParamRegionKind::Named(did, name) => {
                 if did.is_crate_root() {
-                    write!(f, "BrNamed({name})")
+                    write!(f, "LateNamed({name})")
                 } else {
-                    write!(f, "BrNamed({did:?}, {name})")
+                    write!(f, "LateNamed({did:?}, {name})")
                 }
             }
-            ty::LateParamRegionKind::ClosureEnv => write!(f, "BrEnv"),
+            ty::LateParamRegionKind::ClosureEnv => write!(f, "LateEnv"),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 74a94d82784..27ee363f1c1 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -8,7 +8,7 @@ use std::iter;
 use std::ops::{ControlFlow, Range};
 
 use hir::def::{CtorKind, DefKind};
-use rustc_abi::{ExternAbi, FIRST_VARIANT, FieldIdx, VariantIdx};
+use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
 use rustc_errors::{ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::LangItem;
@@ -1441,23 +1441,7 @@ impl<'tcx> Ty<'tcx> {
 
     #[tracing::instrument(level = "trace", skip(tcx))]
     pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
-        match self.kind() {
-            FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args),
-            FnPtr(sig_tys, hdr) => sig_tys.with(*hdr),
-            Error(_) => {
-                // ignore errors (#54954)
-                Binder::dummy(ty::FnSig {
-                    inputs_and_output: ty::List::empty(),
-                    c_variadic: false,
-                    safety: hir::Safety::Safe,
-                    abi: ExternAbi::Rust,
-                })
-            }
-            Closure(..) => bug!(
-                "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
-            ),
-            _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
-        }
+        self.kind().fn_sig(tcx)
     }
 
     #[inline]
@@ -2043,32 +2027,7 @@ impl<'tcx> Ty<'tcx> {
     /// nested types may be further simplified, the outermost [`TyKind`] or
     /// type constructor remains the same.
     pub fn is_known_rigid(self) -> bool {
-        match self.kind() {
-            Bool
-            | Char
-            | Int(_)
-            | Uint(_)
-            | Float(_)
-            | Adt(_, _)
-            | Foreign(_)
-            | Str
-            | Array(_, _)
-            | Pat(_, _)
-            | Slice(_)
-            | RawPtr(_, _)
-            | Ref(_, _, _)
-            | FnDef(_, _)
-            | FnPtr(..)
-            | Dynamic(_, _, _)
-            | Closure(_, _)
-            | CoroutineClosure(_, _)
-            | Coroutine(_, _)
-            | CoroutineWitness(..)
-            | Never
-            | Tuple(_)
-            | UnsafeBinder(_) => true,
-            Error(_) | Infer(_) | Alias(_, _) | Param(_) | Bound(_, _) | Placeholder(_) => false,
-        }
+        self.kind().is_known_rigid()
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 8fa1c569737..ea25ce65f77 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -129,21 +129,6 @@ impl<'tcx> TraitDef {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    /// `trait_def_id` MUST BE the `DefId` of a trait.
-    pub fn for_each_impl<F: FnMut(DefId)>(self, trait_def_id: DefId, mut f: F) {
-        let impls = self.trait_impls_of(trait_def_id);
-
-        for &impl_def_id in impls.blanket_impls.iter() {
-            f(impl_def_id);
-        }
-
-        for v in impls.non_blanket_impls.values() {
-            for &impl_def_id in v {
-                f(impl_def_id);
-            }
-        }
-    }
-
     /// Iterate over every impl that could possibly match the self type `self_ty`.
     ///
     /// `trait_def_id` MUST BE the `DefId` of a trait.
@@ -235,7 +220,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
         }
     }
 
-    for &impl_def_id in tcx.hir_trait_impls(trait_id) {
+    for &impl_def_id in tcx.local_trait_impls(trait_id) {
         let impl_def_id = impl_def_id.to_def_id();
 
         let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 06054e22e76..7c437abfe24 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -158,7 +158,7 @@ pub struct TypeckResults<'tcx> {
     /// We also store the type here, so that the compiler can use it as a hint
     /// for figuring out hidden types, even if they are only set in dead code
     /// (which doesn't show up in MIR).
-    pub concrete_opaque_types: FxIndexMap<ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>>,
+    pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
 
     /// Tracks the minimum captures required for a closure;
     /// see `MinCaptureInformationMap` for more details.
@@ -197,12 +197,6 @@ pub struct TypeckResults<'tcx> {
     /// formatting modified file tests/ui/coroutine/retain-resume-ref.rs
     pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
 
-    /// We sometimes treat byte string literals (which are of type `&[u8; N]`)
-    /// as `&[u8]`, depending on the pattern in which they are used.
-    /// This hashset records all instances where we behave
-    /// like this to allow `const_to_pat` to reliably handle this situation.
-    pub treat_byte_string_as_slice: ItemLocalSet,
-
     /// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
     /// on closure size.
     pub closure_size_eval: LocalDefIdMap<ClosureSizeProfileData<'tcx>>,
@@ -237,7 +231,6 @@ impl<'tcx> TypeckResults<'tcx> {
             closure_fake_reads: Default::default(),
             rvalue_scopes: Default::default(),
             coroutine_stalled_predicates: Default::default(),
-            treat_byte_string_as_slice: Default::default(),
             closure_size_eval: Default::default(),
             offset_of_data: Default::default(),
         }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index c0d4130336e..e4863896fc8 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -389,77 +389,83 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Calculate the destructor of a given type.
     pub fn calculate_dtor(
         self,
-        adt_did: DefId,
-        validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
+        adt_did: LocalDefId,
+        validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>,
     ) -> Option<ty::Destructor> {
         let drop_trait = self.lang_items().drop_trait()?;
         self.ensure_ok().coherent_trait(drop_trait).ok()?;
 
-        let ty = self.type_of(adt_did).instantiate_identity();
         let mut dtor_candidate = None;
-        self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
+        // `Drop` impls can only be written in the same crate as the adt, and cannot be blanket impls
+        for &impl_did in self.local_trait_impls(drop_trait) {
+            let Some(adt_def) = self.type_of(impl_did).skip_binder().ty_adt_def() else { continue };
+            if adt_def.did() != adt_did.to_def_id() {
+                continue;
+            }
+
             if validate(self, impl_did).is_err() {
                 // Already `ErrorGuaranteed`, no need to delay a span bug here.
-                return;
+                continue;
             }
 
             let Some(item_id) = self.associated_item_def_ids(impl_did).first() else {
                 self.dcx()
                     .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function");
-                return;
+                continue;
             };
 
-            if let Some((old_item_id, _)) = dtor_candidate {
+            if self.def_kind(item_id) != DefKind::AssocFn {
+                self.dcx().span_delayed_bug(self.def_span(item_id), "drop is not a function");
+                continue;
+            }
+
+            if let Some(old_item_id) = dtor_candidate {
                 self.dcx()
                     .struct_span_err(self.def_span(item_id), "multiple drop impls found")
                     .with_span_note(self.def_span(old_item_id), "other impl here")
                     .delay_as_bug();
             }
 
-            dtor_candidate = Some((*item_id, self.impl_trait_header(impl_did).unwrap().constness));
-        });
+            dtor_candidate = Some(*item_id);
+        }
 
-        let (did, constness) = dtor_candidate?;
-        Some(ty::Destructor { did, constness })
+        let did = dtor_candidate?;
+        Some(ty::Destructor { did })
     }
 
     /// Calculate the async destructor of a given type.
     pub fn calculate_async_dtor(
         self,
-        adt_did: DefId,
-        validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
+        adt_did: LocalDefId,
+        validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>,
     ) -> Option<ty::AsyncDestructor> {
         let async_drop_trait = self.lang_items().async_drop_trait()?;
         self.ensure_ok().coherent_trait(async_drop_trait).ok()?;
 
-        let ty = self.type_of(adt_did).instantiate_identity();
         let mut dtor_candidate = None;
-        self.for_each_relevant_impl(async_drop_trait, ty, |impl_did| {
+        // `AsyncDrop` impls can only be written in the same crate as the adt, and cannot be blanket impls
+        for &impl_did in self.local_trait_impls(async_drop_trait) {
+            let Some(adt_def) = self.type_of(impl_did).skip_binder().ty_adt_def() else { continue };
+            if adt_def.did() != adt_did.to_def_id() {
+                continue;
+            }
+
             if validate(self, impl_did).is_err() {
                 // Already `ErrorGuaranteed`, no need to delay a span bug here.
-                return;
+                continue;
             }
 
-            let [future, ctor] = self.associated_item_def_ids(impl_did) else {
-                self.dcx().span_delayed_bug(
-                    self.def_span(impl_did),
-                    "AsyncDrop impl without async_drop function or Dropper type",
-                );
-                return;
-            };
-
-            if let Some((_, _, old_impl_did)) = dtor_candidate {
+            if let Some(old_impl_did) = dtor_candidate {
                 self.dcx()
                     .struct_span_err(self.def_span(impl_did), "multiple async drop impls found")
                     .with_span_note(self.def_span(old_impl_did), "other impl here")
                     .delay_as_bug();
             }
 
-            dtor_candidate = Some((*future, *ctor, impl_did));
-        });
+            dtor_candidate = Some(impl_did);
+        }
 
-        let (future, ctor, _) = dtor_candidate?;
-        Some(ty::AsyncDestructor { future, ctor })
+        Some(ty::AsyncDestructor { impl_did: dtor_candidate? })
     }
 
     /// Returns async drop glue morphology for a definition. To get async drop
@@ -1546,55 +1552,6 @@ impl<'tcx> Ty<'tcx> {
     }
 }
 
-pub enum ExplicitSelf<'tcx> {
-    ByValue,
-    ByReference(ty::Region<'tcx>, hir::Mutability),
-    ByRawPointer(hir::Mutability),
-    ByBox,
-    Other,
-}
-
-impl<'tcx> ExplicitSelf<'tcx> {
-    /// Categorizes an explicit self declaration like `self: SomeType`
-    /// into either `self`, `&self`, `&mut self`, `Box<Self>`, or
-    /// `Other`.
-    /// This is mainly used to require the arbitrary_self_types feature
-    /// in the case of `Other`, to improve error messages in the common cases,
-    /// and to make `Other` dyn-incompatible.
-    ///
-    /// Examples:
-    ///
-    /// ```ignore (illustrative)
-    /// impl<'a> Foo for &'a T {
-    ///     // Legal declarations:
-    ///     fn method1(self: &&'a T); // ExplicitSelf::ByReference
-    ///     fn method2(self: &'a T); // ExplicitSelf::ByValue
-    ///     fn method3(self: Box<&'a T>); // ExplicitSelf::ByBox
-    ///     fn method4(self: Rc<&'a T>); // ExplicitSelf::Other
-    ///
-    ///     // Invalid cases will be caught by `check_method_receiver`:
-    ///     fn method_err1(self: &'a mut T); // ExplicitSelf::Other
-    ///     fn method_err2(self: &'static T) // ExplicitSelf::ByValue
-    ///     fn method_err3(self: &&T) // ExplicitSelf::ByReference
-    /// }
-    /// ```
-    ///
-    pub fn determine<P>(self_arg_ty: Ty<'tcx>, is_self_ty: P) -> ExplicitSelf<'tcx>
-    where
-        P: Fn(Ty<'tcx>) -> bool,
-    {
-        use self::ExplicitSelf::*;
-
-        match *self_arg_ty.kind() {
-            _ if is_self_ty(self_arg_ty) => ByValue,
-            ty::Ref(region, ty, mutbl) if is_self_ty(ty) => ByReference(region, mutbl),
-            ty::RawPtr(ty, mutbl) if is_self_ty(ty) => ByRawPointer(mutbl),
-            _ if self_arg_ty.boxed_ty().is_some_and(is_self_ty) => ByBox,
-            _ => Other,
-        }
-    }
-}
-
 /// Returns a list of types such that the given type needs drop if and only if
 /// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if
 /// this type always needs drop.
diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs
index 7dda68b8393..c4357fae104 100644
--- a/compiler/rustc_middle/src/util/bug.rs
+++ b/compiler/rustc_middle/src/util/bug.rs
@@ -49,7 +49,7 @@ fn opt_span_bug_fmt<S: Into<MultiSpan>>(
 pub fn trigger_delayed_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) {
     tcx.dcx().span_delayed_bug(
         tcx.def_span(key),
-        "delayed bug triggered by #[rustc_error(delayed_bug_from_inside_query)]",
+        "delayed bug triggered by #[rustc_delayed_bug_from_inside_query]",
     );
 }
 
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
index 50ca924baf9..fbe53081156 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
@@ -159,7 +159,7 @@ fn find_capture_matching_projections<'a, 'tcx>(
 ) -> Option<(usize, &'a Capture<'tcx>)> {
     let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections);
 
-    upvars.get_by_key_enumerated(var_hir_id.0).find(|(_, capture)| {
+    upvars.get_by_key_enumerated(var_hir_id.0.local_id).find(|(_, capture)| {
         let possible_ancestor_proj_kinds: Vec<_> =
             capture.captured_place.place.projections.iter().map(|proj| proj.kind).collect();
         is_ancestor_or_same_capture(&possible_ancestor_proj_kinds, &hir_projections)
@@ -258,7 +258,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
                 self.projection
             ),
             PlaceBase::Upvar { var_hir_id, closure_def_id: _ } => span_bug!(
-                cx.tcx.hir().span(var_hir_id.0),
+                cx.tcx.hir_span(var_hir_id.0),
                 "could not resolve upvar: {var_hir_id:?} + {:?}",
                 self.projection
             ),
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index 97d34b85f50..f9791776f71 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -416,7 +416,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     if let Some(mir_place) = place_builder.try_to_place(this) {
                         this.cfg.push_fake_read(
                             block,
-                            this.source_info(this.tcx.hir().span(*hir_id)),
+                            this.source_info(this.tcx.hir_span(*hir_id)),
                             *cause,
                             mir_place,
                         );
diff --git a/compiler/rustc_mir_build/src/builder/expr/stmt.rs b/compiler/rustc_mir_build/src/builder/expr/stmt.rs
index 7f8a0a34c31..2dff26f02f3 100644
--- a/compiler/rustc_mir_build/src/builder/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/stmt.rs
@@ -78,8 +78,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // because AssignOp is only legal for Copy types
                 // (overloaded ops should be desugared into a call).
                 let result = unpack!(
-                    block =
-                        this.build_binary_op(block, op, expr_span, lhs_ty, Operand::Copy(lhs), rhs)
+                    block = this.build_binary_op(
+                        block,
+                        op.into(),
+                        expr_span,
+                        lhs_ty,
+                        Operand::Copy(lhs),
+                        rhs
+                    )
                 );
                 this.cfg.push_assign(block, source_info, lhs, result);
 
diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs
index c8b69a6ec62..8ca9ab58e45 100644
--- a/compiler/rustc_mir_build/src/builder/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/mod.rs
@@ -13,7 +13,7 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Node};
+use rustc_hir::{self as hir, BindingMode, ByRef, HirId, ItemLocalId, Node};
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_index::{Idx, IndexSlice, IndexVec};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -48,11 +48,11 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
 /// this directly; instead use the cached version via `mir_built`.
 pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
     tcx.ensure_done().thir_abstract_const(def);
-    if let Err(e) = tcx.check_match(def) {
+    if let Err(e) = tcx.ensure_ok().check_match(def) {
         return construct_error(tcx, def, e);
     }
 
-    if let Err(err) = tcx.check_tail_calls(def) {
+    if let Err(err) = tcx.ensure_ok().check_tail_calls(def) {
         return construct_error(tcx, def, err);
     }
 
@@ -221,7 +221,7 @@ struct Builder<'a, 'tcx> {
     coverage_info: Option<coverageinfo::CoverageInfoBuilder>,
 }
 
-type CaptureMap<'tcx> = SortedIndexMultiMap<usize, HirId, Capture<'tcx>>;
+type CaptureMap<'tcx> = SortedIndexMultiMap<usize, ItemLocalId, Capture<'tcx>>;
 
 #[derive(Debug)]
 struct Capture<'tcx> {
@@ -457,7 +457,7 @@ fn construct_fn<'tcx>(
 
     // Figure out what primary body this item has.
     let body = tcx.hir_body_owned_by(fn_def);
-    let span_with_body = tcx.hir().span_with_body(fn_id);
+    let span_with_body = tcx.hir_span_with_body(fn_id);
     let return_ty_span = tcx
         .hir_fn_decl_by_hir_id(fn_id)
         .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def))
@@ -853,6 +853,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let capture_tys = upvar_args.upvar_tys();
 
         let tcx = self.tcx;
+        let mut upvar_owner = None;
         self.upvars = tcx
             .closure_captures(self.def_id)
             .iter()
@@ -866,6 +867,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
                     _ => bug!("Expected an upvar"),
                 };
+                let upvar_base = upvar_owner.get_or_insert(var_id.owner);
+                assert_eq!(*upvar_base, var_id.owner);
+                let var_id = var_id.local_id;
 
                 let mutability = captured_place.mutability;
 
diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs
index e56c0ae92ca..e42336a1dbb 100644
--- a/compiler/rustc_mir_build/src/builder/scope.rs
+++ b/compiler/rustc_mir_build/src/builder/scope.rs
@@ -1496,7 +1496,7 @@ fn build_scope_drops<'tcx>(
                 // path, then don't generate the drop. (We only take this into
                 // account for non-unwind paths so as not to disturb the
                 // caching mechanism.)
-                if scope.moved_locals.iter().any(|&o| o == local) {
+                if scope.moved_locals.contains(&local) {
                     continue;
                 }
 
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 7f2e7d5ca83..6fb9974fc8e 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -195,7 +195,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
 
     /// Whether the `unsafe_op_in_unsafe_fn` lint is `allow`ed at the current HIR node.
     fn unsafe_op_in_unsafe_fn_allowed(&self) -> bool {
-        self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, self.hir_context).0 == Level::Allow
+        self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, self.hir_context).level == Level::Allow
     }
 
     /// Handle closures/coroutines/inline-consts, which is unsafecked with their parent body.
@@ -292,8 +292,10 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 });
             }
             BlockSafety::ExplicitUnsafe(hir_id) => {
-                let used =
-                    matches!(self.tcx.lint_level_at_node(UNUSED_UNSAFE, hir_id), (Level::Allow, _));
+                let used = matches!(
+                    self.tcx.lint_level_at_node(UNUSED_UNSAFE, hir_id).level,
+                    Level::Allow
+                );
                 self.in_safety_context(
                     SafetyContext::UnsafeBlock {
                         span: block.span,
@@ -943,7 +945,7 @@ impl UnsafeOpKind {
             }
         });
         let unsafe_not_inherited_note = if let Some((id, _)) = note_non_inherited {
-            let span = tcx.hir().span(id);
+            let span = tcx.hir_span(id);
             let span = tcx.sess.source_map().guess_head_span(span);
             Some(UnsafeNotInheritedNote { span })
         } else {
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index b8af77245f2..31e22e69111 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -9,7 +9,7 @@ use rustc_middle::hir::place::{
     Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
 };
 use rustc_middle::middle::region;
-use rustc_middle::mir::{self, BinOp, BorrowKind, UnOp};
+use rustc_middle::mir::{self, AssignOp, BinOp, BorrowKind, UnOp};
 use rustc_middle::thir::*;
 use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCoercion,
@@ -489,7 +489,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
                     self.overloaded_operator(expr, Box::new([lhs, rhs]))
                 } else {
                     ExprKind::AssignOp {
-                        op: bin_op(op.node),
+                        op: assign_op(op.node),
                         lhs: self.mirror_expr(lhs),
                         rhs: self.mirror_expr(rhs),
                     }
@@ -1347,3 +1347,18 @@ fn bin_op(op: hir::BinOpKind) -> BinOp {
         _ => bug!("no equivalent for ast binop {:?}", op),
     }
 }
+
+fn assign_op(op: hir::AssignOpKind) -> AssignOp {
+    match op {
+        hir::AssignOpKind::AddAssign => AssignOp::AddAssign,
+        hir::AssignOpKind::SubAssign => AssignOp::SubAssign,
+        hir::AssignOpKind::MulAssign => AssignOp::MulAssign,
+        hir::AssignOpKind::DivAssign => AssignOp::DivAssign,
+        hir::AssignOpKind::RemAssign => AssignOp::RemAssign,
+        hir::AssignOpKind::BitXorAssign => AssignOp::BitXorAssign,
+        hir::AssignOpKind::BitAndAssign => AssignOp::BitAndAssign,
+        hir::AssignOpKind::BitOrAssign => AssignOp::BitOrAssign,
+        hir::AssignOpKind::ShlAssign => AssignOp::ShlAssign,
+        hir::AssignOpKind::ShrAssign => AssignOp::ShrAssign,
+    }
+}
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 095d3e75da1..9f5e2c06b22 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -1025,7 +1025,7 @@ fn find_fallback_pattern_typo<'tcx>(
     pat: &Pat<'tcx>,
     lint: &mut UnreachablePattern<'_>,
 ) {
-    if let (Level::Allow, _) = cx.tcx.lint_level_at_node(UNREACHABLE_PATTERNS, hir_id) {
+    if let Level::Allow = cx.tcx.lint_level_at_node(UNREACHABLE_PATTERNS, hir_id).level {
         // This is because we use `with_no_trimmed_paths` later, so if we never emit the lint we'd
         // ICE. At the same time, we don't really need to do all of this if we won't emit anything.
         return;
@@ -1174,7 +1174,7 @@ fn report_arm_reachability<'p, 'tcx>(
     for (arm, is_useful) in report.arm_usefulness.iter() {
         if let Usefulness::Redundant(explanation) = is_useful {
             let hir_id = arm.arm_data;
-            let arm_span = cx.tcx.hir().span(hir_id);
+            let arm_span = cx.tcx.hir_span(hir_id);
             let whole_arm_span = if is_match_arm {
                 // If the arm is followed by a comma, extend the span to include it.
                 let with_whitespace = sm.span_extend_while_whitespace(arm_span);
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 667d59d858e..372453688d2 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
@@ -58,25 +58,13 @@ struct ConstToPat<'tcx> {
     span: Span,
     id: hir::HirId,
 
-    treat_byte_string_as_slice: bool,
-
     c: ty::Const<'tcx>,
 }
 
 impl<'tcx> ConstToPat<'tcx> {
     fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
         trace!(?pat_ctxt.typeck_results.hir_owner);
-        ConstToPat {
-            tcx: pat_ctxt.tcx,
-            typing_env: pat_ctxt.typing_env,
-            span,
-            id,
-            treat_byte_string_as_slice: pat_ctxt
-                .typeck_results
-                .treat_byte_string_as_slice
-                .contains(&id.local_id),
-            c,
-        }
+        ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, id, c }
     }
 
     fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {
@@ -108,8 +96,6 @@ impl<'tcx> ConstToPat<'tcx> {
         uv: ty::UnevaluatedConst<'tcx>,
         ty: Ty<'tcx>,
     ) -> Box<Pat<'tcx>> {
-        trace!(self.treat_byte_string_as_slice);
-
         // It's not *technically* correct to be revealing opaque types here as borrowcheck has
         // not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
         // during typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
@@ -307,21 +293,8 @@ impl<'tcx> ConstToPat<'tcx> {
                             ty,
                         );
                     } else {
-                        // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
-                        // matching against references, you can only use byte string literals.
-                        // The typechecker has a special case for byte string literals, by treating them
-                        // as slices. This means we turn `&[T; N]` constants into slice patterns, which
-                        // has no negative effects on pattern matching, even if we're actually matching on
-                        // arrays.
-                        let pointee_ty = match *pointee_ty.kind() {
-                            ty::Array(elem_ty, _) if self.treat_byte_string_as_slice => {
-                                Ty::new_slice(tcx, elem_ty)
-                            }
-                            _ => *pointee_ty,
-                        };
                         // References have the same valtree representation as their pointee.
-                        let subpattern = self.valtree_to_pat(cv, pointee_ty);
-                        PatKind::Deref { subpattern }
+                        PatKind::Deref { subpattern: self.valtree_to_pat(cv, *pointee_ty) }
                     }
                 }
             },
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 4bfeab44bf4..d20e051548b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -11,7 +11,7 @@ use rustc_abi::{FieldIdx, Integer};
 use rustc_errors::codes::*;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
-use rustc_hir::{self as hir, RangeEnd};
+use rustc_hir::{self as hir, LangItem, RangeEnd};
 use rustc_index::Idx;
 use rustc_middle::mir::interpret::LitToConstInput;
 use rustc_middle::thir::{
@@ -130,7 +130,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
         // Lower the endpoint into a temporary `PatKind` that will then be
         // deconstructed to obtain the constant value and other data.
-        let mut kind: PatKind<'tcx> = self.lower_pat_expr(expr);
+        let mut kind: PatKind<'tcx> = self.lower_pat_expr(expr, None);
 
         // Unpeel any ascription or inline-const wrapper nodes.
         loop {
@@ -294,7 +294,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
             hir::PatKind::Never => PatKind::Never,
 
-            hir::PatKind::Expr(value) => self.lower_pat_expr(value),
+            hir::PatKind::Expr(value) => self.lower_pat_expr(value, Some(ty)),
 
             hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => {
                 let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref());
@@ -630,7 +630,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     /// - Paths (e.g. `FOO`, `foo::BAR`, `Option::None`)
     /// - Inline const blocks (e.g. `const { 1 + 1 }`)
     /// - Literals, possibly negated (e.g. `-128u8`, `"hello"`)
-    fn lower_pat_expr(&mut self, expr: &'tcx hir::PatExpr<'tcx>) -> PatKind<'tcx> {
+    fn lower_pat_expr(
+        &mut self,
+        expr: &'tcx hir::PatExpr<'tcx>,
+        pat_ty: Option<Ty<'tcx>>,
+    ) -> PatKind<'tcx> {
         let (lit, neg) = match &expr.kind {
             hir::PatExprKind::Path(qpath) => {
                 return self.lower_path(qpath, expr.hir_id, expr.span).kind;
@@ -641,7 +645,31 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             hir::PatExprKind::Lit { lit, negated } => (lit, *negated),
         };
 
-        let ct_ty = self.typeck_results.node_type(expr.hir_id);
+        // We handle byte string literal patterns by using the pattern's type instead of the
+        // literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference,
+        // the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the
+        // pattern's type means we'll properly translate it to a slice reference pattern. This works
+        // because slices and arrays have the same valtree representation.
+        // HACK: As an exception, use the literal's type if `pat_ty` is `String`; this can happen if
+        // `string_deref_patterns` is enabled. There's a special case for that when lowering to MIR.
+        // FIXME(deref_patterns): This hack won't be necessary once `string_deref_patterns` is
+        // superseded by a more general implementation of deref patterns.
+        let ct_ty = match pat_ty {
+            Some(pat_ty)
+                if let ty::Adt(def, _) = *pat_ty.kind()
+                    && self.tcx.is_lang_item(def.did(), LangItem::String) =>
+            {
+                if !self.tcx.features().string_deref_patterns() {
+                    span_bug!(
+                        expr.span,
+                        "matching on `String` went through without enabling string_deref_patterns"
+                    );
+                }
+                self.typeck_results.node_type(expr.hir_id)
+            }
+            Some(pat_ty) => pat_ty,
+            None => self.typeck_results.node_type(expr.hir_id),
+        };
         let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
         let constant = self.tcx.at(expr.span).lit_to_const(lit_input);
         self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
index ceea72c6755..375db17fb73 100644
--- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
+++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
@@ -53,9 +53,13 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> {
         //
         //     #[const_mutation_allowed]
         //     pub const LOG: Log = Log { msg: "" };
-        match self.tcx.calculate_dtor(def_id, |_, _| Ok(())) {
-            Some(_) => None,
-            None => Some(def_id),
+        // FIXME: this should not be checking for `Drop` impls,
+        // but whether it or any field has a Drop impl (`needs_drop`)
+        // as fields' Drop impls may make this observable, too.
+        match self.tcx.type_of(def_id).skip_binder().ty_adt_def().map(|adt| adt.has_dtor(self.tcx))
+        {
+            Some(true) => None,
+            Some(false) | None => Some(def_id),
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 89a306c6104..dd0e07f2218 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -219,6 +219,8 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
         mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id()));
     dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(()));
 
+    // Feed HIR because we try to access this body's attrs in the inliner.
+    body_def.feed_hir();
     // Inherited from the by-ref coroutine.
     body_def.codegen_fn_attrs(tcx.codegen_fn_attrs(coroutine_def_id).clone());
     body_def.coverage_attr_on(tcx.coverage_attr_on(coroutine_def_id));
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index d83c0d40a7e..73bd2d0705e 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -96,7 +96,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
         }
     } else {
         // Extract coverage spans from MIR statements/terminators as normal.
-        extract_refined_covspans(mir_body, hir_info, graph, &mut code_mappings);
+        extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings);
     }
 
     branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph));
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 8befe9c5d8d..f57a158e3e4 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,7 +1,9 @@
 use std::collections::VecDeque;
+use std::iter;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
 use tracing::{debug, debug_span, instrument};
 
@@ -11,8 +13,9 @@ use crate::coverage::{ExtractedHirInfo, mappings, unexpand};
 
 mod from_mir;
 
-pub(super) fn extract_refined_covspans(
-    mir_body: &mir::Body<'_>,
+pub(super) fn extract_refined_covspans<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    mir_body: &mir::Body<'tcx>,
     hir_info: &ExtractedHirInfo,
     graph: &CoverageGraph,
     code_mappings: &mut impl Extend<mappings::CodeMapping>,
@@ -50,7 +53,7 @@ pub(super) fn extract_refined_covspans(
     // First, perform the passes that need macro information.
     covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb));
     remove_unwanted_expansion_spans(&mut covspans);
-    split_visible_macro_spans(&mut covspans);
+    shrink_visible_macro_spans(tcx, &mut covspans);
 
     // We no longer need the extra information in `SpanFromMir`, so convert to `Covspan`.
     let mut covspans = covspans.into_iter().map(SpanFromMir::into_covspan).collect::<Vec<_>>();
@@ -83,9 +86,7 @@ pub(super) fn extract_refined_covspans(
     // Split the covspans into separate buckets that don't overlap any holes.
     let buckets = divide_spans_into_buckets(covspans, &holes);
 
-    for mut covspans in buckets {
-        // Make sure each individual bucket is internally sorted.
-        covspans.sort_by(compare_covspans);
+    for covspans in buckets {
         let _span = debug_span!("processing bucket", ?covspans).entered();
 
         let mut covspans = remove_unwanted_overlapping_spans(covspans);
@@ -129,82 +130,50 @@ fn remove_unwanted_expansion_spans(covspans: &mut Vec<SpanFromMir>) {
 }
 
 /// When a span corresponds to a macro invocation that is visible from the
-/// function body, split it into two parts. The first part covers just the
-/// macro name plus `!`, and the second part covers the rest of the macro
-/// invocation. This seems to give better results for code that uses macros.
-fn split_visible_macro_spans(covspans: &mut Vec<SpanFromMir>) {
-    let mut extra_spans = vec![];
-
-    covspans.retain(|covspan| {
-        let Some(ExpnKind::Macro(MacroKind::Bang, visible_macro)) = covspan.expn_kind else {
-            return true;
-        };
-
-        let split_len = visible_macro.as_str().len() as u32 + 1;
-        let (before, after) = covspan.span.split_at(split_len);
-        if !covspan.span.contains(before) || !covspan.span.contains(after) {
-            // Something is unexpectedly wrong with the split point.
-            // The debug assertion in `split_at` will have already caught this,
-            // but in release builds it's safer to do nothing and maybe get a
-            // bug report for unexpected coverage, rather than risk an ICE.
-            return true;
+/// function body, truncate it to just the macro name plus `!`.
+/// This seems to give better results for code that uses macros.
+fn shrink_visible_macro_spans(tcx: TyCtxt<'_>, covspans: &mut Vec<SpanFromMir>) {
+    let source_map = tcx.sess.source_map();
+
+    for covspan in covspans {
+        if matches!(covspan.expn_kind, Some(ExpnKind::Macro(MacroKind::Bang, _))) {
+            covspan.span = source_map.span_through_char(covspan.span, '!');
         }
-
-        extra_spans.push(SpanFromMir::new(before, covspan.expn_kind.clone(), covspan.bcb));
-        extra_spans.push(SpanFromMir::new(after, covspan.expn_kind.clone(), covspan.bcb));
-        false // Discard the original covspan that we just split.
-    });
-
-    // The newly-split spans are added at the end, so any previous sorting
-    // is not preserved.
-    covspans.extend(extra_spans);
+    }
 }
 
 /// Uses the holes to divide the given covspans into buckets, such that:
-/// - No span in any hole overlaps a bucket (truncating the spans if necessary).
+/// - No span in any hole overlaps a bucket (discarding spans if necessary).
 /// - The spans in each bucket are strictly after all spans in previous buckets,
 ///   and strictly before all spans in subsequent buckets.
 ///
-/// The resulting buckets are sorted relative to each other, but might not be
-/// internally sorted.
+/// The lists of covspans and holes must be sorted.
+/// The resulting buckets are sorted relative to each other, and each bucket's
+/// contents are sorted.
 #[instrument(level = "debug")]
 fn divide_spans_into_buckets(input_covspans: Vec<Covspan>, holes: &[Hole]) -> Vec<Vec<Covspan>> {
     debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
     debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
 
-    // Now we're ready to start carving holes out of the initial coverage spans,
-    // and grouping them in buckets separated by the holes.
+    // Now we're ready to start grouping spans into buckets separated by holes.
 
     let mut input_covspans = VecDeque::from(input_covspans);
-    let mut fragments = vec![];
 
     // For each hole:
     // - Identify the spans that are entirely or partly before the hole.
-    // - Put those spans in a corresponding bucket, truncated to the start of the hole.
-    // - If one of those spans also extends after the hole, put the rest of it
-    //   in a "fragments" vector that is processed by the next hole.
+    // - Discard any that overlap with the hole.
+    // - Add the remaining identified spans to the corresponding bucket.
     let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
     for (hole, bucket) in holes.iter().zip(&mut buckets) {
-        let fragments_from_prev = std::mem::take(&mut fragments);
-
-        // Only inspect spans that precede or overlap this hole,
-        // leaving the rest to be inspected by later holes.
-        // (This relies on the spans and holes both being sorted.)
-        let relevant_input_covspans =
-            drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi());
-
-        for covspan in fragments_from_prev.into_iter().chain(relevant_input_covspans) {
-            let (before, after) = covspan.split_around_hole_span(hole.span);
-            bucket.extend(before);
-            fragments.extend(after);
-        }
+        bucket.extend(
+            drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi())
+                .filter(|c| !c.span.overlaps(hole.span)),
+        );
     }
 
-    // After finding the spans before each hole, any remaining fragments/spans
-    // form their own final bucket, after the final hole.
+    // Any remaining spans form their own final bucket, after the final hole.
     // (If there were no holes, this will just be all of the initial spans.)
-    fragments.extend(input_covspans);
-    buckets.push(fragments);
+    buckets.push(Vec::from(input_covspans));
 
     buckets
 }
@@ -215,7 +184,7 @@ fn drain_front_while<'a, T>(
     queue: &'a mut VecDeque<T>,
     mut pred_fn: impl FnMut(&T) -> bool,
 ) -> impl Iterator<Item = T> {
-    std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None })
+    iter::from_fn(move || queue.pop_front_if(|x| pred_fn(x)))
 }
 
 /// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines"
@@ -258,22 +227,6 @@ struct Covspan {
 }
 
 impl Covspan {
-    /// Splits this covspan into 0-2 parts:
-    /// - The part that is strictly before the hole span, if any.
-    /// - The part that is strictly after the hole span, if any.
-    fn split_around_hole_span(&self, hole_span: Span) -> (Option<Self>, Option<Self>) {
-        let before = try {
-            let span = self.span.trim_end(hole_span)?;
-            Self { span, ..*self }
-        };
-        let after = try {
-            let span = self.span.trim_start(hole_span)?;
-            Self { span, ..*self }
-        };
-
-        (before, after)
-    }
-
     /// If `self` and `other` can be merged (i.e. they have the same BCB),
     /// mutates `self.span` to also include `other.span` and returns true.
     ///
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index 1faa2171c0b..804cd8ab3f7 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -120,22 +120,20 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
         // an `if condition { block }` has a span that includes the executed block, if true,
         // but for coverage, the code region executed, up to *and* through the SwitchInt,
         // actually stops before the if's block.)
-        TerminatorKind::Unreachable // Unreachable blocks are not connected to the MIR CFG
+        TerminatorKind::Unreachable
         | TerminatorKind::Assert { .. }
         | TerminatorKind::Drop { .. }
         | TerminatorKind::SwitchInt { .. }
-        // For `FalseEdge`, only the `real` branch is taken, so it is similar to a `Goto`.
         | TerminatorKind::FalseEdge { .. }
         | TerminatorKind::Goto { .. } => None,
 
         // Call `func` operand can have a more specific span when part of a chain of calls
-        TerminatorKind::Call { ref func, .. }
-        | TerminatorKind::TailCall { ref func, .. } => {
+        TerminatorKind::Call { ref func, .. } | TerminatorKind::TailCall { ref func, .. } => {
             let mut span = terminator.source_info.span;
-            if let mir::Operand::Constant(box constant) = func {
-                if constant.span.lo() > span.lo() {
-                    span = span.with_lo(constant.span.lo());
-                }
+            if let mir::Operand::Constant(constant) = func
+                && span.contains(constant.span)
+            {
+                span = constant.span;
             }
             Some(span)
         }
@@ -147,9 +145,7 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
         | TerminatorKind::Yield { .. }
         | TerminatorKind::CoroutineDrop
         | TerminatorKind::FalseUnwind { .. }
-        | TerminatorKind::InlineAsm { .. } => {
-            Some(terminator.source_info.span)
-        }
+        | TerminatorKind::InlineAsm { .. } => Some(terminator.source_info.span),
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 0a54c780f31..68bc0ffce6b 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -3,14 +3,16 @@
 //! MIR may contain repeated and/or redundant computations. The objective of this pass is to detect
 //! such redundancies and re-use the already-computed result when possible.
 //!
-//! In a first pass, we compute a symbolic representation of values that are assigned to SSA
-//! locals. This symbolic representation is defined by the `Value` enum. Each produced instance of
-//! `Value` is interned as a `VnIndex`, which allows us to cheaply compute identical values.
-//!
 //! From those assignments, we construct a mapping `VnIndex -> Vec<(Local, Location)>` of available
 //! values, the locals in which they are stored, and the assignment location.
 //!
-//! In a second pass, we traverse all (non SSA) assignments `x = rvalue` and operands. For each
+//! We traverse all assignments `x = rvalue` and operands.
+//!
+//! For each SSA one, we compute a symbolic representation of values that are assigned to SSA
+//! locals. This symbolic representation is defined by the `Value` enum. Each produced instance of
+//! `Value` is interned as a `VnIndex`, which allows us to cheaply compute identical values.
+//!
+//! For each non-SSA
 //! one, we compute the `VnIndex` of the rvalue. If this `VnIndex` is associated to a constant, we
 //! replace the rvalue/operand by that constant. Otherwise, if there is an SSA local `y`
 //! associated to this `VnIndex`, and if its definition location strictly dominates the assignment
@@ -91,7 +93,7 @@ use rustc_const_eval::interpret::{
     ImmTy, Immediate, InterpCx, MemPlaceMeta, MemoryKind, OpTy, Projectable, Scalar,
     intern_const_alloc_for_constprop,
 };
-use rustc_data_structures::fx::FxIndexSet;
+use rustc_data_structures::fx::{FxIndexSet, MutableValues};
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_hir::def::DefKind;
 use rustc_index::bit_set::DenseBitSet;
@@ -107,7 +109,7 @@ use rustc_span::def_id::DefId;
 use smallvec::SmallVec;
 use tracing::{debug, instrument, trace};
 
-use crate::ssa::{AssignedValue, SsaLocals};
+use crate::ssa::SsaLocals;
 
 pub(super) struct GVN;
 
@@ -126,31 +128,11 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
         let dominators = body.basic_blocks.dominators().clone();
 
         let mut state = VnState::new(tcx, body, typing_env, &ssa, dominators, &body.local_decls);
-        ssa.for_each_assignment_mut(
-            body.basic_blocks.as_mut_preserves_cfg(),
-            |local, value, location| {
-                let value = match value {
-                    // We do not know anything of this assigned value.
-                    AssignedValue::Arg | AssignedValue::Terminator => None,
-                    // Try to get some insight.
-                    AssignedValue::Rvalue(rvalue) => {
-                        let value = state.simplify_rvalue(rvalue, location);
-                        // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
-                        // `local` as reusable if we have an exact type match.
-                        if state.local_decls[local].ty != rvalue.ty(state.local_decls, tcx) {
-                            return;
-                        }
-                        value
-                    }
-                };
-                // `next_opaque` is `Some`, so `new_opaque` must return `Some`.
-                let value = value.or_else(|| state.new_opaque()).unwrap();
-                state.assign(local, value);
-            },
-        );
 
-        // Stop creating opaques during replacement as it is useless.
-        state.next_opaque = None;
+        for local in body.args_iter().filter(|&local| ssa.is_ssa(local)) {
+            let opaque = state.new_opaque();
+            state.assign(local, opaque);
+        }
 
         let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec();
         for bb in reverse_postorder {
@@ -250,14 +232,14 @@ struct VnState<'body, 'tcx> {
     locals: IndexVec<Local, Option<VnIndex>>,
     /// Locals that are assigned that value.
     // This vector does not hold all the values of `VnIndex` that we create.
-    // It stops at the largest value created in the first phase of collecting assignments.
     rev_locals: IndexVec<VnIndex, SmallVec<[Local; 1]>>,
     values: FxIndexSet<Value<'tcx>>,
     /// Values evaluated as constants if possible.
     evaluated: IndexVec<VnIndex, Option<OpTy<'tcx>>>,
     /// Counter to generate different values.
-    /// This is an option to stop creating opaques during replacement.
-    next_opaque: Option<usize>,
+    next_opaque: usize,
+    /// Cache the deref values.
+    derefs: Vec<VnIndex>,
     /// Cache the value of the `unsized_locals` features, to avoid fetching it repeatedly in a loop.
     feature_unsized_locals: bool,
     ssa: &'body SsaLocals,
@@ -289,7 +271,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             rev_locals: IndexVec::with_capacity(num_values),
             values: FxIndexSet::with_capacity_and_hasher(num_values, Default::default()),
             evaluated: IndexVec::with_capacity(num_values),
-            next_opaque: Some(1),
+            next_opaque: 1,
+            derefs: Vec::new(),
             feature_unsized_locals: tcx.features().unsized_locals(),
             ssa,
             dominators,
@@ -310,32 +293,31 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             let evaluated = self.eval_to_const(index);
             let _index = self.evaluated.push(evaluated);
             debug_assert_eq!(index, _index);
-            // No need to push to `rev_locals` if we finished listing assignments.
-            if self.next_opaque.is_some() {
-                let _index = self.rev_locals.push(SmallVec::new());
-                debug_assert_eq!(index, _index);
-            }
+            let _index = self.rev_locals.push(SmallVec::new());
+            debug_assert_eq!(index, _index);
         }
         index
     }
 
+    fn next_opaque(&mut self) -> usize {
+        let next_opaque = self.next_opaque;
+        self.next_opaque += 1;
+        next_opaque
+    }
+
     /// Create a new `Value` for which we have no information at all, except that it is distinct
     /// from all the others.
     #[instrument(level = "trace", skip(self), ret)]
-    fn new_opaque(&mut self) -> Option<VnIndex> {
-        let next_opaque = self.next_opaque.as_mut()?;
-        let value = Value::Opaque(*next_opaque);
-        *next_opaque += 1;
-        Some(self.insert(value))
+    fn new_opaque(&mut self) -> VnIndex {
+        let value = Value::Opaque(self.next_opaque());
+        self.insert(value)
     }
 
     /// Create a new `Value::Address` distinct from all the others.
     #[instrument(level = "trace", skip(self), ret)]
-    fn new_pointer(&mut self, place: Place<'tcx>, kind: AddressKind) -> Option<VnIndex> {
-        let next_opaque = self.next_opaque.as_mut()?;
-        let value = Value::Address { place, kind, provenance: *next_opaque };
-        *next_opaque += 1;
-        Some(self.insert(value))
+    fn new_pointer(&mut self, place: Place<'tcx>, kind: AddressKind) -> VnIndex {
+        let value = Value::Address { place, kind, provenance: self.next_opaque() };
+        self.insert(value)
     }
 
     fn get(&self, index: VnIndex) -> &Value<'tcx> {
@@ -345,6 +327,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
     /// Record that `local` is assigned `value`. `local` must be SSA.
     #[instrument(level = "trace", skip(self))]
     fn assign(&mut self, local: Local, value: VnIndex) {
+        debug_assert!(self.ssa.is_ssa(local));
         self.locals[local] = Some(value);
 
         // Only register the value if its type is `Sized`, as we will emit copies of it.
@@ -355,21 +338,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         }
     }
 
-    fn insert_constant(&mut self, value: Const<'tcx>) -> Option<VnIndex> {
+    fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex {
         let disambiguator = if value.is_deterministic() {
             // The constant is deterministic, no need to disambiguate.
             0
         } else {
             // Multiple mentions of this constant will yield different values,
             // so assign a different `disambiguator` to ensure they do not get the same `VnIndex`.
-            let next_opaque = self.next_opaque.as_mut()?;
-            let disambiguator = *next_opaque;
-            *next_opaque += 1;
+            let disambiguator = self.next_opaque();
             // `disambiguator: 0` means deterministic.
             debug_assert_ne!(disambiguator, 0);
             disambiguator
         };
-        Some(self.insert(Value::Constant { value, disambiguator }))
+        self.insert(Value::Constant { value, disambiguator })
     }
 
     fn insert_bool(&mut self, flag: bool) -> VnIndex {
@@ -390,6 +371,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::ZERO, values))
     }
 
+    fn insert_deref(&mut self, value: VnIndex) -> VnIndex {
+        let value = self.insert(Value::Projection(value, ProjectionElem::Deref));
+        self.derefs.push(value);
+        value
+    }
+
+    fn invalidate_derefs(&mut self) {
+        for deref in std::mem::take(&mut self.derefs) {
+            let opaque = self.next_opaque();
+            *self.values.get_index_mut2(deref.index()).unwrap() = Value::Opaque(opaque);
+        }
+    }
+
     #[instrument(level = "trace", skip(self), ret)]
     fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
         use Value::*;
@@ -648,15 +642,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         let proj = match proj {
             ProjectionElem::Deref => {
                 let ty = place.ty(self.local_decls, self.tcx).ty;
-                // unsound: https://github.com/rust-lang/rust/issues/130853
-                if self.tcx.sess.opts.unstable_opts.unsound_mir_opts
-                    && let Some(Mutability::Not) = ty.ref_mutability()
+                if let Some(Mutability::Not) = ty.ref_mutability()
                     && let Some(pointee_ty) = ty.builtin_deref(true)
                     && pointee_ty.is_freeze(self.tcx, self.typing_env())
                 {
                     // An immutable borrow `_x` always points to the same value for the
                     // lifetime of the borrow, so we can merge all instances of `*_x`.
-                    ProjectionElem::Deref
+                    return Some(self.insert_deref(value));
                 } else {
                     return None;
                 }
@@ -830,7 +822,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         location: Location,
     ) -> Option<VnIndex> {
         match *operand {
-            Operand::Constant(ref constant) => self.insert_constant(constant.const_),
+            Operand::Constant(ref constant) => Some(self.insert_constant(constant.const_)),
             Operand::Copy(ref mut place) | Operand::Move(ref mut place) => {
                 let value = self.simplify_place_value(place, location)?;
                 if let Some(const_) = self.try_as_constant(value) {
@@ -866,11 +858,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             Rvalue::Aggregate(..) => return self.simplify_aggregate(rvalue, location),
             Rvalue::Ref(_, borrow_kind, ref mut place) => {
                 self.simplify_place_projection(place, location);
-                return self.new_pointer(*place, AddressKind::Ref(borrow_kind));
+                return Some(self.new_pointer(*place, AddressKind::Ref(borrow_kind)));
             }
             Rvalue::RawPtr(mutbl, ref mut place) => {
                 self.simplify_place_projection(place, location);
-                return self.new_pointer(*place, AddressKind::Address(mutbl));
+                return Some(self.new_pointer(*place, AddressKind::Address(mutbl)));
             }
             Rvalue::WrapUnsafeBinder(ref mut op, ty) => {
                 let value = self.simplify_operand(op, location)?;
@@ -1034,7 +1026,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
 
             if is_zst {
                 let ty = rvalue.ty(self.local_decls, tcx);
-                return self.insert_constant(Const::zero_sized(ty));
+                return Some(self.insert_constant(Const::zero_sized(ty)));
             }
         }
 
@@ -1063,11 +1055,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
         };
 
-        let fields: Option<Vec<_>> = field_ops
+        let mut fields: Vec<_> = field_ops
             .iter_mut()
-            .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque()))
+            .map(|op| self.simplify_operand(op, location).unwrap_or_else(|| self.new_opaque()))
             .collect();
-        let mut fields = fields?;
 
         if let AggregateTy::RawPtr { data_pointer_ty, output_pointer_ty } = &mut ty {
             let mut was_updated = false;
@@ -1107,9 +1098,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
         }
 
-        // unsound: https://github.com/rust-lang/rust/issues/132353
-        if tcx.sess.opts.unstable_opts.unsound_mir_opts
-            && let AggregateTy::Def(_, _) = ty
+        if let AggregateTy::Def(_, _) = ty
             && let Some(value) =
                 self.simplify_aggregate_to_copy(rvalue, location, &fields, variant_index)
         {
@@ -1195,7 +1184,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             ) if let ty::Slice(..) = to.builtin_deref(true).unwrap().kind()
                 && let ty::Array(_, len) = from.builtin_deref(true).unwrap().kind() =>
             {
-                return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
+                return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len)));
             }
             _ => Value::UnaryOp(op, arg_index),
         };
@@ -1391,7 +1380,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_), _) = kind {
             // Each reification of a generic fn may get a different pointer.
             // Do not try to merge them.
-            return self.new_opaque();
+            return Some(self.new_opaque());
         }
 
         let mut was_ever_updated = false;
@@ -1507,7 +1496,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         // Trivial case: we are fetching a statically known length.
         let place_ty = place.ty(self.local_decls, self.tcx).ty;
         if let ty::Array(_, len) = place_ty.kind() {
-            return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
+            return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len)));
         }
 
         let mut inner = self.simplify_place_value(place, location)?;
@@ -1529,7 +1518,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             && let Some(to) = to.builtin_deref(true)
             && let ty::Slice(..) = to.kind()
         {
-            return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
+            return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len)));
         }
 
         // Fallback: a symbolic `Len`.
@@ -1739,41 +1728,70 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
         self.tcx
     }
 
-    fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, location: Location) {
+    fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
         self.simplify_place_projection(place, location);
+        if context.is_mutating_use() && !place.projection.is_empty() {
+            // Non-local mutation maybe invalidate deref.
+            self.invalidate_derefs();
+        }
+        self.super_place(place, context, location);
     }
 
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
         self.simplify_operand(operand, location);
+        self.super_operand(operand, location);
     }
 
     fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, location: Location) {
         if let StatementKind::Assign(box (ref mut lhs, ref mut rvalue)) = stmt.kind {
             self.simplify_place_projection(lhs, location);
 
-            // Do not try to simplify a constant, it's already in canonical shape.
-            if matches!(rvalue, Rvalue::Use(Operand::Constant(_))) {
-                return;
+            let value = self.simplify_rvalue(rvalue, location);
+            let value = if let Some(local) = lhs.as_local()
+                && self.ssa.is_ssa(local)
+                // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
+                // `local` as reusable if we have an exact type match.
+                && self.local_decls[local].ty == rvalue.ty(self.local_decls, self.tcx)
+            {
+                let value = value.unwrap_or_else(|| self.new_opaque());
+                self.assign(local, value);
+                Some(value)
+            } else {
+                value
+            };
+            if let Some(value) = value {
+                if let Some(const_) = self.try_as_constant(value) {
+                    *rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
+                } else if let Some(local) = self.try_as_local(value, location)
+                    && *rvalue != Rvalue::Use(Operand::Move(local.into()))
+                {
+                    *rvalue = Rvalue::Use(Operand::Copy(local.into()));
+                    self.reused_locals.insert(local);
+                }
             }
+        }
+        self.super_statement(stmt, location);
+    }
 
-            let value = lhs
-                .as_local()
-                .and_then(|local| self.locals[local])
-                .or_else(|| self.simplify_rvalue(rvalue, location));
-            let Some(value) = value else { return };
-
-            if let Some(const_) = self.try_as_constant(value) {
-                *rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
-            } else if let Some(local) = self.try_as_local(value, location)
-                && *rvalue != Rvalue::Use(Operand::Move(local.into()))
+    fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
+        if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator {
+            if let Some(local) = destination.as_local()
+                && self.ssa.is_ssa(local)
             {
-                *rvalue = Rvalue::Use(Operand::Copy(local.into()));
-                self.reused_locals.insert(local);
+                let opaque = self.new_opaque();
+                self.assign(local, opaque);
             }
-
-            return;
         }
-        self.super_statement(stmt, location);
+        // Function calls and ASM may invalidate (nested) derefs. We must handle them carefully.
+        // Currently, only preserving derefs for trivial terminators like SwitchInt and Goto.
+        let safe_to_preserve_derefs = matches!(
+            terminator.kind,
+            TerminatorKind::SwitchInt { .. } | TerminatorKind::Goto { .. }
+        );
+        if !safe_to_preserve_derefs {
+            self.invalidate_derefs();
+        }
+        self.super_terminator(terminator, location);
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index da346dfc48c..2eff6b31372 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -78,20 +78,20 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
     /// GVN can also do this optimization, but GVN is only run at mir-opt-level 2 so having this in
     /// InstSimplify helps unoptimized builds.
     fn simplify_repeated_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
-        let Rvalue::Aggregate(box AggregateKind::Array(_), fields) = rvalue else {
+        let Rvalue::Aggregate(box AggregateKind::Array(_), fields) = &*rvalue else {
             return;
         };
         if fields.len() < 5 {
             return;
         }
-        let first = &fields[rustc_abi::FieldIdx::ZERO];
+        let (first, rest) = fields[..].split_first().unwrap();
         let Operand::Constant(first) = first else {
             return;
         };
         let Ok(first_val) = first.const_.eval(self.tcx, self.typing_env, first.span) else {
             return;
         };
-        if fields.iter().all(|field| {
+        if rest.iter().all(|field| {
             let Operand::Constant(field) = field else {
                 return false;
             };
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 205d388f4fb..6429d3f67ec 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -12,6 +12,7 @@
 #![feature(map_try_insert)]
 #![feature(never_type)]
 #![feature(try_blocks)]
+#![feature(vec_deque_pop_if)]
 #![feature(yeet_expr)]
 // tidy-alphabetical-end
 
@@ -528,7 +529,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
         | DefKind::Static { .. }
         | DefKind::Const
         | DefKind::AssocConst => {
-            if let Err(guar) = tcx.check_well_formed(root.expect_local()) {
+            if let Err(guar) = tcx.ensure_ok().check_well_formed(root.expect_local()) {
                 body.tainted_by_errors = Some(guar);
             }
         }
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index 3d512fb064e..edd0cabca49 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -32,12 +32,6 @@ pub(super) struct SsaLocals {
     borrowed_locals: DenseBitSet<Local>,
 }
 
-pub(super) enum AssignedValue<'a, 'tcx> {
-    Arg,
-    Rvalue(&'a mut Rvalue<'tcx>),
-    Terminator,
-}
-
 impl SsaLocals {
     pub(super) fn new<'tcx>(
         tcx: TyCtxt<'tcx>,
@@ -152,38 +146,6 @@ impl SsaLocals {
         })
     }
 
-    pub(super) fn for_each_assignment_mut<'tcx>(
-        &self,
-        basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
-        mut f: impl FnMut(Local, AssignedValue<'_, 'tcx>, Location),
-    ) {
-        for &local in &self.assignment_order {
-            match self.assignments[local] {
-                Set1::One(DefLocation::Argument) => f(
-                    local,
-                    AssignedValue::Arg,
-                    Location { block: START_BLOCK, statement_index: 0 },
-                ),
-                Set1::One(DefLocation::Assignment(loc)) => {
-                    let bb = &mut basic_blocks[loc.block];
-                    // `loc` must point to a direct assignment to `local`.
-                    let stmt = &mut bb.statements[loc.statement_index];
-                    let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else {
-                        bug!()
-                    };
-                    assert_eq!(target.as_local(), Some(local));
-                    f(local, AssignedValue::Rvalue(rvalue), loc)
-                }
-                Set1::One(DefLocation::CallReturn { call, .. }) => {
-                    let bb = &mut basic_blocks[call];
-                    let loc = Location { block: call, statement_index: bb.statements.len() };
-                    f(local, AssignedValue::Terminator, loc)
-                }
-                _ => {}
-            }
-        }
-    }
-
     /// Compute the equivalence classes for locals, based on copy statements.
     ///
     /// The returned vector maps each local to the one it copies. In the following case:
diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl
index aae2d79c161..6b6653e7de0 100644
--- a/compiler/rustc_monomorphize/messages.ftl
+++ b/compiler/rustc_monomorphize/messages.ftl
@@ -48,7 +48,7 @@ monomorphize_large_assignments =
     .note = The current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
 
 monomorphize_no_optimized_mir =
-    missing optimized MIR for an item in the crate `{$crate_name}`
+    missing optimized MIR for `{$instance}` in the crate `{$crate_name}`
     .note = missing optimized MIR for this item (was the crate `{$crate_name}` compiled with `--emit=metadata`?)
 
 monomorphize_recursion_limit =
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 2a1b20ba48b..6e676ac6b8d 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -989,6 +989,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
         tcx.dcx().emit_fatal(NoOptimizedMir {
             span: tcx.def_span(def_id),
             crate_name: tcx.crate_name(def_id.krate),
+            instance: instance.to_string(),
         });
     }
 
diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs
index dffa372279f..adfe096f0cd 100644
--- a/compiler/rustc_monomorphize/src/errors.rs
+++ b/compiler/rustc_monomorphize/src/errors.rs
@@ -24,6 +24,7 @@ pub(crate) struct NoOptimizedMir {
     #[note]
     pub span: Span,
     pub crate_name: Symbol,
+    pub instance: String,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs
index 259b39e2b9e..c4b6b18c45d 100644
--- a/compiler/rustc_next_trait_solver/src/delegate.rs
+++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -62,14 +62,12 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
         universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
     ) -> <Self::Interner as Interner>::GenericArg;
 
-    // FIXME: Can we implement this in terms of `add` and `inject`?
-    fn insert_hidden_type(
+    fn register_hidden_type_in_storage(
         &self,
         opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
-        param_env: <Self::Interner as Interner>::ParamEnv,
         hidden_ty: <Self::Interner as Interner>::Ty,
-        goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
-    ) -> Result<(), NoSolution>;
+        span: <Self::Interner as Interner>::Span,
+    ) -> Option<<Self::Interner as Interner>::Ty>;
 
     fn add_item_bounds_for_hidden_type(
         &self,
@@ -79,14 +77,6 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
         hidden_ty: <Self::Interner as Interner>::Ty,
         goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
     );
-
-    fn inject_new_hidden_type_unchecked(
-        &self,
-        key: ty::OpaqueTypeKey<Self::Interner>,
-        hidden_ty: <Self::Interner as Interner>::Ty,
-        span: <Self::Interner as Interner>::Span,
-    );
-
     fn reset_opaque_types(&self);
 
     fn fetch_eligible_assoc_item(
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index a5142de2d39..c2fb592c3f3 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -37,12 +37,16 @@ where
         | ty::Never
         | ty::Char => Ok(ty::Binder::dummy(vec![])),
 
+        // This branch is only for `experimental_default_bounds`.
+        // Other foreign types were rejected earlier in
+        // `disqualify_auto_trait_candidate_due_to_possible_impl`.
+        ty::Foreign(..) => Ok(ty::Binder::dummy(vec![])),
+
         // Treat `str` like it's defined as `struct str([u8]);`
         ty::Str => Ok(ty::Binder::dummy(vec![Ty::new_slice(cx, Ty::new_u8(cx))])),
 
         ty::Dynamic(..)
         | ty::Param(..)
-        | ty::Foreign(..)
         | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
         | ty::Placeholder(..)
         | ty::Bound(..)
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index ac6b521f665..4edc293ad80 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -425,7 +425,8 @@ where
 
     fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
         for &(key, ty) in opaque_types {
-            self.delegate.inject_new_hidden_type_unchecked(key, ty, self.origin_span);
+            let prev = self.delegate.register_hidden_type_in_storage(key, ty, self.origin_span);
+            assert_eq!(prev, None);
         }
     }
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 7ef36d0e9ae..148ba02252d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -387,7 +387,8 @@ where
         };
 
         for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
-            ecx.delegate.inject_new_hidden_type_unchecked(key, ty, ecx.origin_span);
+            let prev = ecx.delegate.register_hidden_type_in_storage(key, ty, ecx.origin_span);
+            assert_eq!(prev, None);
         }
 
         if !ecx.nested_goals.is_empty() {
@@ -1070,16 +1071,12 @@ where
         self.delegate.fetch_eligible_assoc_item(goal_trait_ref, trait_assoc_def_id, impl_def_id)
     }
 
-    pub(super) fn insert_hidden_type(
+    pub(super) fn register_hidden_type_in_storage(
         &mut self,
         opaque_type_key: ty::OpaqueTypeKey<I>,
-        param_env: I::ParamEnv,
         hidden_ty: I::Ty,
-    ) -> Result<(), NoSolution> {
-        let mut goals = Vec::new();
-        self.delegate.insert_hidden_type(opaque_type_key, param_env, hidden_ty, &mut goals)?;
-        self.add_goals(GoalSource::Misc, goals);
-        Ok(())
+    ) -> Option<I::Ty> {
+        self.delegate.register_hidden_type_in_storage(opaque_type_key, hidden_ty, self.origin_span)
     }
 
     pub(super) fn add_item_bounds_for_hidden_type(
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index 199f0c7512e..7641e9a16ee 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -330,6 +330,7 @@ where
             // During analysis, opaques are rigid unless they may be defined by
             // the current body.
             TypingMode::Analysis { defining_opaque_types: non_rigid_opaques }
+            | TypingMode::Borrowck { defining_opaque_types: non_rigid_opaques }
             | TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => {
                 !def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id))
             }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
index 817dffa127b..aa89e77bb6f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
@@ -86,8 +86,44 @@ where
                 }
 
                 // Otherwise, define a new opaque type
-                // FIXME: should we use `inject_hidden_type_unchecked` here?
-                self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
+                let prev = self.register_hidden_type_in_storage(opaque_type_key, expected);
+                assert_eq!(prev, None);
+                self.add_item_bounds_for_hidden_type(
+                    def_id.into(),
+                    opaque_ty.args,
+                    goal.param_env,
+                    expected,
+                );
+                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            }
+            // Very similar to `TypingMode::Analysis` with some notably differences:
+            // - we accept opaque types even if they have non-universal arguments
+            // - we do a structural lookup instead of semantically unifying regions
+            // - the hidden type starts out as the type from HIR typeck with fresh region
+            //   variables instead of a fully unconstrained inference variable
+            TypingMode::Borrowck { defining_opaque_types } => {
+                let Some(def_id) = opaque_ty
+                    .def_id
+                    .as_local()
+                    .filter(|&def_id| defining_opaque_types.contains(&def_id))
+                else {
+                    self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
+                    return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+                };
+
+                let opaque_type_key = ty::OpaqueTypeKey { def_id, args: opaque_ty.args };
+                let actual = self
+                    .register_hidden_type_in_storage(opaque_type_key, expected)
+                    .unwrap_or_else(|| {
+                        let actual =
+                            cx.type_of_opaque_hir_typeck(def_id).instantiate(cx, opaque_ty.args);
+                        let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() {
+                            ty::ReErased => self.next_region_var(),
+                            _ => re,
+                        });
+                        actual
+                    });
+                self.eq(goal.param_env, expected, actual)?;
                 self.add_item_bounds_for_hidden_type(
                     def_id.into(),
                     opaque_ty.args,
diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
index eba496fa226..ecffbbff7a2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
@@ -62,6 +62,7 @@ where
                     response_no_constraints(cx, input, Certainty::overflow(false))
                 }
                 TypingMode::Analysis { .. }
+                | TypingMode::Borrowck { .. }
                 | TypingMode::PostBorrowckAnalysis { .. }
                 | TypingMode::PostAnalysis => Err(NoSolution),
             },
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index b72f776e5cb..d42c9980f46 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -72,6 +72,7 @@ where
             (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() {
                 TypingMode::Coherence => Certainty::AMBIGUOUS,
                 TypingMode::Analysis { .. }
+                | TypingMode::Borrowck { .. }
                 | TypingMode::PostBorrowckAnalysis { .. }
                 | TypingMode::PostAnalysis => return Err(NoSolution),
             },
@@ -1086,6 +1087,25 @@ where
         goal: Goal<I, TraitPredicate<I>>,
     ) -> Option<Result<Candidate<I>, NoSolution>> {
         let self_ty = goal.predicate.self_ty();
+        let check_impls = || {
+            let mut disqualifying_impl = None;
+            self.cx().for_each_relevant_impl(
+                goal.predicate.def_id(),
+                goal.predicate.self_ty(),
+                |impl_def_id| {
+                    disqualifying_impl = Some(impl_def_id);
+                },
+            );
+            if let Some(def_id) = disqualifying_impl {
+                trace!(?def_id, ?goal, "disqualified auto-trait implementation");
+                // No need to actually consider the candidate here,
+                // since we do that in `consider_impl_candidate`.
+                return Some(Err(NoSolution));
+            } else {
+                None
+            }
+        };
+
         match self_ty.kind() {
             // Stall int and float vars until they are resolved to a concrete
             // numerical type. That's because the check for impls below treats
@@ -1096,6 +1116,10 @@ where
                 Some(self.forced_ambiguity(MaybeCause::Ambiguity))
             }
 
+            // Backward compatibility for default auto traits.
+            // Test: ui/traits/default_auto_traits/extern-types.rs
+            ty::Foreign(..) if self.cx().is_default_trait(goal.predicate.def_id()) => check_impls(),
+
             // These types cannot be structurally decomposed into constituent
             // types, and therefore have no built-in auto impl.
             ty::Dynamic(..)
@@ -1156,24 +1180,7 @@ where
             | ty::Never
             | ty::Tuple(_)
             | ty::Adt(_, _)
-            | ty::UnsafeBinder(_) => {
-                let mut disqualifying_impl = None;
-                self.cx().for_each_relevant_impl(
-                    goal.predicate.def_id(),
-                    goal.predicate.self_ty(),
-                    |impl_def_id| {
-                        disqualifying_impl = Some(impl_def_id);
-                    },
-                );
-                if let Some(def_id) = disqualifying_impl {
-                    trace!(?def_id, ?goal, "disqualified auto-trait implementation");
-                    // No need to actually consider the candidate here,
-                    // since we do that in `consider_impl_candidate`.
-                    return Some(Err(NoSolution));
-                } else {
-                    None
-                }
-            }
+            | ty::UnsafeBinder(_) => check_impls(),
             ty::Error(_) => None,
         }
     }
@@ -1294,7 +1301,6 @@ where
                 .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
                 .map(|c| c.result)
                 .collect();
-
             return if let Some(response) = self.try_merge_responses(&where_bounds) {
                 Ok((response, Some(TraitGoalProvenVia::ParamEnv)))
             } else {
@@ -1315,9 +1321,18 @@ where
             };
         }
 
+        // If there are *only* global where bounds, then make sure to return that this
+        // is still reported as being proven-via the param-env so that rigid projections
+        // operate correctly.
+        let proven_via =
+            if candidates.iter().all(|c| matches!(c.source, CandidateSource::ParamEnv(_))) {
+                TraitGoalProvenVia::ParamEnv
+            } else {
+                TraitGoalProvenVia::Misc
+            };
         let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect();
         if let Some(response) = self.try_merge_responses(&all_candidates) {
-            Ok((response, Some(TraitGoalProvenVia::Misc)))
+            Ok((response, Some(proven_via)))
         } else {
             self.flounder(&all_candidates).map(|r| (r, None))
         }
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 3253222b8f2..93fa89b68b9 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -838,8 +838,6 @@ parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression int
 
 parse_unexpected_expr_in_pat_create_guard_sugg = consider moving the expression to a match arm guard
 
-parse_unexpected_expr_in_pat_inline_const_sugg = consider wrapping the expression in an inline `const` (requires `{"#"}![feature(inline_const_pat)]`)
-
 parse_unexpected_expr_in_pat_update_guard_sugg = consider moving the expression to the match arm guard
 
 parse_unexpected_if_with_if = unexpected `if` in the condition expression
@@ -860,7 +858,7 @@ parse_unexpected_parentheses_in_match_arm_pattern = unexpected parentheses surro
 parse_unexpected_self_in_generic_parameters = unexpected keyword `Self` in generic parameters
     .note = you cannot use `Self` as a generic parameter because it is reserved for associated items
 
-parse_unexpected_token_after_dot = unexpected token: `{$actual}`
+parse_unexpected_token_after_dot = unexpected token: {$actual}
 
 parse_unexpected_token_after_label = expected `while`, `for`, `loop` or `{"{"}` after a label
     .suggestion_remove_label = consider removing the label
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index f813c3380fc..dfdef018bc3 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -810,16 +810,16 @@ pub(crate) enum WrapInParentheses {
 
 #[derive(Diagnostic)]
 #[diag(parse_array_brackets_instead_of_braces)]
-pub(crate) struct ArrayBracketsInsteadOfSpaces {
+pub(crate) struct ArrayBracketsInsteadOfBraces {
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
-    pub sub: ArrayBracketsInsteadOfSpacesSugg,
+    pub sub: ArrayBracketsInsteadOfBracesSugg,
 }
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
-pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
+pub(crate) struct ArrayBracketsInsteadOfBracesSugg {
     #[suggestion_part(code = "[")]
     pub left: Span,
     #[suggestion_part(code = "]")]
@@ -1696,10 +1696,10 @@ pub(crate) struct SelfArgumentPointer {
 
 #[derive(Diagnostic)]
 #[diag(parse_unexpected_token_after_dot)]
-pub(crate) struct UnexpectedTokenAfterDot<'a> {
+pub(crate) struct UnexpectedTokenAfterDot {
     #[primary_span]
     pub span: Span,
-    pub actual: Cow<'a, str>,
+    pub actual: String,
 }
 
 #[derive(Diagnostic)]
@@ -2769,17 +2769,6 @@ pub(crate) enum UnexpectedExpressionInPatternSugg {
         /// The statement's block's indentation.
         indentation: String,
     },
-
-    #[multipart_suggestion(
-        parse_unexpected_expr_in_pat_inline_const_sugg,
-        applicability = "maybe-incorrect"
-    )]
-    InlineConst {
-        #[suggestion_part(code = "const {{ ")]
-        start_span: Span,
-        #[suggestion_part(code = " }}")]
-        end_span: Span,
-    },
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 92e83577f1b..841d967d934 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -4,22 +4,21 @@ use core::mem;
 use core::ops::{Bound, ControlFlow};
 
 use ast::mut_visit::{self, MutVisitor};
-use ast::token::{IdentIsRaw, MetaVarKind};
+use ast::token::IdentIsRaw;
 use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered};
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Delimiter, Token, TokenKind};
+use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, Token, TokenKind};
 use rustc_ast::tokenstream::TokenTree;
 use rustc_ast::util::case::Case;
 use rustc_ast::util::classify;
 use rustc_ast::util::parser::{AssocOp, ExprPrecedence, Fixity, prec_let_scrutinee_needs_par};
 use rustc_ast::visit::{Visitor, walk_expr};
 use rustc_ast::{
-    self as ast, AnonConst, Arm, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy,
-    ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl, FnRetTy, Label, MacCall,
-    MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind,
-    YieldKind,
+    self as ast, AnonConst, Arm, AssignOp, AssignOpKind, AttrStyle, AttrVec, BinOp, BinOpKind,
+    BlockCheckMode, CaptureBy, ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl,
+    FnRetTy, Label, MacCall, MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, TyKind,
+    UnOp, UnsafeBinderCastKind, YieldKind,
 };
-use rustc_ast_pretty::pprust;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic};
 use rustc_lexer::unescape::unescape_char;
@@ -360,7 +359,7 @@ impl<'a> Parser<'a> {
             (
                 Some(
                     AssocOp::Binary(BinOpKind::Shr | BinOpKind::Gt | BinOpKind::Ge)
-                    | AssocOp::AssignOp(BinOpKind::Shr),
+                    | AssocOp::AssignOp(AssignOpKind::ShrAssign),
                 ),
                 _,
             ) if self.restrictions.contains(Restrictions::CONST_EXPR) => {
@@ -605,7 +604,7 @@ impl<'a> Parser<'a> {
             // can't continue an expression after an ident
             token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
             token::Literal(..) | token::Pound => true,
-            _ => t.is_whole_expr(),
+            _ => t.is_metavar_expr(),
         };
         self.token.is_ident_named(sym::not) && self.look_ahead(1, token_cannot_continue_expr)
     }
@@ -641,6 +640,13 @@ impl<'a> Parser<'a> {
             TokenKind::NtIdent(..) | TokenKind::NtLifetime(..) | TokenKind::Interpolated(..) => {
                 self.prev_token.span
             }
+            TokenKind::CloseDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(_))) => {
+                // `expr.span` is the interpolated span, because invisible open
+                // and close delims both get marked with the same span, one
+                // that covers the entire thing between them. (See
+                // `rustc_expand::mbe::transcribe::transcribe`.)
+                self.prev_token.span
+            }
             _ => expr.span,
         }
     }
@@ -979,12 +985,30 @@ impl<'a> Parser<'a> {
     }
 
     fn error_unexpected_after_dot(&self) {
-        let actual = pprust::token_to_string(&self.token);
+        let actual = super::token_descr(&self.token);
         let span = self.token.span;
         let sm = self.psess.source_map();
         let (span, actual) = match (&self.token.kind, self.subparser_name) {
-            (token::Eof, Some(_)) if let Ok(actual) = sm.span_to_snippet(sm.next_point(span)) => {
-                (span.shrink_to_hi(), actual.into())
+            (token::Eof, Some(_)) if let Ok(snippet) = sm.span_to_snippet(sm.next_point(span)) => {
+                (span.shrink_to_hi(), format!("`{}`", snippet))
+            }
+            (token::CloseDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(_))), _) => {
+                // No need to report an error. This case will only occur when parsing a pasted
+                // metavariable, and we should have emitted an error when parsing the macro call in
+                // the first place. E.g. in this code:
+                // ```
+                // macro_rules! m { ($e:expr) => { $e }; }
+                //
+                // fn main() {
+                //     let f = 1;
+                //     m!(f.);
+                // }
+                // ```
+                // we'll get an error "unexpected token: `)` when parsing the `m!(f.)`, so we don't
+                // want to issue a second error when parsing the expansion `«f.»` (where `«`/`»`
+                // represent the invisible delimiters).
+                self.dcx().span_delayed_bug(span, "bad dot expr in metavariable");
+                return;
             }
             _ => (span, actual),
         };
@@ -1294,7 +1318,7 @@ impl<'a> Parser<'a> {
 
     /// Assuming we have just parsed `.`, continue parsing into an expression.
     fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
-        if self.token.uninterpolated_span().at_least_rust_2018() && self.eat_keyword(exp!(Await)) {
+        if self.token_uninterpolated_span().at_least_rust_2018() && self.eat_keyword(exp!(Await)) {
             return Ok(self.mk_await_expr(self_arg, lo));
         }
 
@@ -1364,17 +1388,33 @@ impl<'a> Parser<'a> {
         let span = self.token.span;
         if let token::Interpolated(nt) = &self.token.kind {
             match &**nt {
-                token::NtExpr(e) | token::NtLiteral(e) => {
-                    let e = e.clone();
-                    self.bump();
-                    return Ok(e);
-                }
                 token::NtBlock(block) => {
                     let block = block.clone();
                     self.bump();
                     return Ok(self.mk_expr(self.prev_token.span, ExprKind::Block(block, None)));
                 }
             };
+        } else if let Some(expr) = self.eat_metavar_seq_with_matcher(
+            |mv_kind| matches!(mv_kind, MetaVarKind::Expr { .. }),
+            |this| {
+                // Force collection (as opposed to just `parse_expr`) is required to avoid the
+                // attribute duplication seen in #138478.
+                let expr = this.parse_expr_force_collect();
+                // FIXME(nnethercote) Sometimes with expressions we get a trailing comma, possibly
+                // related to the FIXME in `collect_tokens_for_expr`. Examples are the multi-line
+                // `assert_eq!` calls involving arguments annotated with `#[rustfmt::skip]` in
+                // `compiler/rustc_index/src/bit_set/tests.rs`.
+                if this.token.kind == token::Comma {
+                    this.bump();
+                }
+                expr
+            },
+        ) {
+            return Ok(expr);
+        } else if let Some(lit) =
+            self.eat_metavar_seq(MetaVarKind::Literal, |this| this.parse_literal_maybe_minus())
+        {
+            return Ok(lit);
         } else if let Some(path) = self.eat_metavar_seq(MetaVarKind::Path, |this| {
             this.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))
         }) {
@@ -1471,9 +1511,9 @@ impl<'a> Parser<'a> {
                 this.parse_expr_let(restrictions)
             } else if this.eat_keyword(exp!(Underscore)) {
                 Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore))
-            } else if this.token.uninterpolated_span().at_least_rust_2018() {
+            } 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.token.uninterpolated_span().at_least_rust_2024()
+                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)
@@ -2062,87 +2102,107 @@ impl<'a> Parser<'a> {
             .or_else(|()| self.handle_missing_lit(Parser::mk_meta_item_lit_char))
     }
 
-    fn recover_after_dot(&mut self) -> Option<Token> {
-        let mut recovered = None;
+    fn recover_after_dot(&mut self) {
         if self.token == token::Dot {
             // Attempt to recover `.4` as `0.4`. We don't currently have any syntax where
             // dot would follow an optional literal, so we do this unconditionally.
-            recovered = self.look_ahead(1, |next_token| {
+            let recovered = self.look_ahead(1, |next_token| {
+                // If it's an integer that looks like a float, then recover as such.
+                //
+                // We will never encounter the exponent part of a floating
+                // point literal here, since there's no use of the exponent
+                // syntax that also constitutes a valid integer, so we need
+                // not check for that.
                 if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) =
                     next_token.kind
+                    && suffix.is_none_or(|s| s == sym::f32 || s == sym::f64)
+                    && symbol.as_str().chars().all(|c| c.is_numeric() || c == '_')
+                    && self.token.span.hi() == next_token.span.lo()
                 {
-                    // If this integer looks like a float, then recover as such.
-                    //
-                    // We will never encounter the exponent part of a floating
-                    // point literal here, since there's no use of the exponent
-                    // syntax that also constitutes a valid integer, so we need
-                    // not check for that.
-                    if suffix.is_none_or(|s| s == sym::f32 || s == sym::f64)
-                        && symbol.as_str().chars().all(|c| c.is_numeric() || c == '_')
-                        && self.token.span.hi() == next_token.span.lo()
-                    {
-                        let s = String::from("0.") + symbol.as_str();
-                        let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix);
-                        return Some(Token::new(kind, self.token.span.to(next_token.span)));
-                    }
+                    let s = String::from("0.") + symbol.as_str();
+                    let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix);
+                    Some(Token::new(kind, self.token.span.to(next_token.span)))
+                } else {
+                    None
                 }
-                None
             });
-            if let Some(token) = &recovered {
-                self.bump();
+            if let Some(recovered) = recovered {
                 self.dcx().emit_err(errors::FloatLiteralRequiresIntegerPart {
-                    span: token.span,
-                    suggestion: token.span.shrink_to_lo(),
+                    span: recovered.span,
+                    suggestion: recovered.span.shrink_to_lo(),
                 });
+                self.bump();
+                self.token = recovered;
             }
         }
+    }
 
-        recovered
+    /// Keep this in sync with `Token::can_begin_literal_maybe_minus` and
+    /// `Lit::from_token` (excluding unary negation).
+    fn eat_token_lit(&mut self) -> Option<token::Lit> {
+        match self.token.uninterpolate().kind {
+            token::Ident(name, IdentIsRaw::No) if name.is_bool_lit() => {
+                self.bump();
+                Some(token::Lit::new(token::Bool, name, None))
+            }
+            token::Literal(token_lit) => {
+                self.bump();
+                Some(token_lit)
+            }
+            token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
+                MetaVarKind::Literal,
+            ))) => {
+                let lit = self
+                    .eat_metavar_seq(MetaVarKind::Literal, |this| this.parse_literal_maybe_minus())
+                    .expect("metavar seq literal");
+                let ast::ExprKind::Lit(token_lit) = lit.kind else {
+                    panic!("didn't reparse a literal");
+                };
+                Some(token_lit)
+            }
+            token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
+                mv_kind @ MetaVarKind::Expr { can_begin_literal_maybe_minus: true, .. },
+            ))) => {
+                let expr = self
+                    .eat_metavar_seq(mv_kind, |this| this.parse_expr())
+                    .expect("metavar seq expr");
+                let ast::ExprKind::Lit(token_lit) = expr.kind else {
+                    panic!("didn't reparse an expr");
+                };
+                Some(token_lit)
+            }
+            _ => None,
+        }
     }
 
     /// Matches `lit = true | false | token_lit`.
     /// Returns `None` if the next token is not a literal.
-    pub(super) fn parse_opt_token_lit(&mut self) -> Option<(token::Lit, Span)> {
-        let recovered = self.recover_after_dot();
-        let token = recovered.as_ref().unwrap_or(&self.token);
-        let span = token.span;
-
-        token::Lit::from_token(token).map(|token_lit| {
-            self.bump();
-            (token_lit, span)
-        })
+    fn parse_opt_token_lit(&mut self) -> Option<(token::Lit, Span)> {
+        self.recover_after_dot();
+        let span = self.token.span;
+        self.eat_token_lit().map(|token_lit| (token_lit, span))
     }
 
     /// Matches `lit = true | false | token_lit`.
     /// Returns `None` if the next token is not a literal.
-    pub(super) fn parse_opt_meta_item_lit(&mut self) -> Option<MetaItemLit> {
-        let recovered = self.recover_after_dot();
-        let token = recovered.as_ref().unwrap_or(&self.token);
-        match token::Lit::from_token(token) {
-            Some(lit) => {
-                match MetaItemLit::from_token_lit(lit, token.span) {
-                    Ok(lit) => {
-                        self.bump();
-                        Some(lit)
-                    }
-                    Err(err) => {
-                        let span = token.uninterpolated_span();
-                        self.bump();
-                        let guar = report_lit_error(self.psess, err, lit, span);
-                        // Pack possible quotes and prefixes from the original literal into
-                        // the error literal's symbol so they can be pretty-printed faithfully.
-                        let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
-                        let symbol = Symbol::intern(&suffixless_lit.to_string());
-                        let lit = token::Lit::new(token::Err(guar), symbol, lit.suffix);
-                        Some(
-                            MetaItemLit::from_token_lit(lit, span)
-                                .unwrap_or_else(|_| unreachable!()),
-                        )
-                    }
+    fn parse_opt_meta_item_lit(&mut self) -> Option<MetaItemLit> {
+        self.recover_after_dot();
+        let span = self.token.span;
+        let uninterpolated_span = self.token_uninterpolated_span();
+        self.eat_token_lit().map(|token_lit| {
+            match MetaItemLit::from_token_lit(token_lit, span) {
+                Ok(lit) => lit,
+                Err(err) => {
+                    let guar = report_lit_error(&self.psess, err, token_lit, uninterpolated_span);
+                    // Pack possible quotes and prefixes from the original literal into
+                    // the error literal's symbol so they can be pretty-printed faithfully.
+                    let suffixless_lit = token::Lit::new(token_lit.kind, token_lit.symbol, None);
+                    let symbol = Symbol::intern(&suffixless_lit.to_string());
+                    let token_lit = token::Lit::new(token::Err(guar), symbol, token_lit.suffix);
+                    MetaItemLit::from_token_lit(token_lit, uninterpolated_span).unwrap()
                 }
             }
-            None => None,
-        }
+        })
     }
 
     pub(super) fn expect_no_tuple_index_suffix(&self, span: Span, suffix: Symbol) {
@@ -2166,9 +2226,10 @@ impl<'a> Parser<'a> {
     /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
     /// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
     pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
-        if let token::Interpolated(nt) = &self.token.kind {
-            match &**nt {
-                // FIXME(nnethercote) The `NtExpr` case should only match if
+        if let Some(expr) = self.eat_metavar_seq_with_matcher(
+            |mv_kind| matches!(mv_kind, MetaVarKind::Expr { .. }),
+            |this| {
+                // FIXME(nnethercote) The `expr` case should only match if
                 // `e` is an `ExprKind::Lit` or an `ExprKind::Unary` containing
                 // an `UnOp::Neg` and an `ExprKind::Lit`, like how
                 // `can_begin_literal_maybe_minus` works. But this method has
@@ -2178,13 +2239,14 @@ impl<'a> Parser<'a> {
                 // `ExprKind::Path` must be accepted when parsing range
                 // patterns. That requires some care. So for now, we continue
                 // being less strict here than we should be.
-                token::NtExpr(e) | token::NtLiteral(e) => {
-                    let e = e.clone();
-                    self.bump();
-                    return Ok(e);
-                }
-                _ => {}
-            };
+                this.parse_expr()
+            },
+        ) {
+            return Ok(expr);
+        } else if let Some(lit) =
+            self.eat_metavar_seq(MetaVarKind::Literal, |this| this.parse_literal_maybe_minus())
+        {
+            return Ok(lit);
         }
 
         let lo = self.token.span;
@@ -2200,7 +2262,9 @@ impl<'a> Parser<'a> {
     }
 
     fn is_array_like_block(&mut self) -> bool {
-        self.look_ahead(1, |t| matches!(t.kind, TokenKind::Ident(..) | TokenKind::Literal(_)))
+        matches!(self.token.kind, TokenKind::OpenDelim(Delimiter::Brace))
+            && self
+                .look_ahead(1, |t| matches!(t.kind, TokenKind::Ident(..) | TokenKind::Literal(_)))
             && self.look_ahead(2, |t| t == &token::Comma)
             && self.look_ahead(3, |t| t.can_begin_expr())
     }
@@ -2212,9 +2276,9 @@ impl<'a> Parser<'a> {
         let mut snapshot = self.create_snapshot_for_diagnostic();
         match snapshot.parse_expr_array_or_repeat(exp!(CloseBrace)) {
             Ok(arr) => {
-                let guar = self.dcx().emit_err(errors::ArrayBracketsInsteadOfSpaces {
+                let guar = self.dcx().emit_err(errors::ArrayBracketsInsteadOfBraces {
                     span: arr.span,
-                    sub: errors::ArrayBracketsInsteadOfSpacesSugg {
+                    sub: errors::ArrayBracketsInsteadOfBracesSugg {
                         left: lo,
                         right: snapshot.prev_token.span,
                     },
@@ -2328,7 +2392,7 @@ impl<'a> Parser<'a> {
         let movability =
             if self.eat_keyword(exp!(Static)) { Movability::Static } else { Movability::Movable };
 
-        let coroutine_kind = if self.token.uninterpolated_span().at_least_rust_2018() {
+        let coroutine_kind = if self.token_uninterpolated_span().at_least_rust_2018() {
             self.parse_coroutine_kind(Case::Sensitive)
         } else {
             None
@@ -2337,7 +2401,8 @@ impl<'a> Parser<'a> {
         let capture_clause = self.parse_capture_clause()?;
         let (fn_decl, fn_arg_span) = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_token.span;
-        let mut body = match fn_decl.output {
+        let mut body = match &fn_decl.output {
+            // No return type.
             FnRetTy::Default(_) => {
                 let restrictions =
                     self.restrictions - Restrictions::STMT_EXPR - Restrictions::ALLOW_LET;
@@ -2349,11 +2414,8 @@ impl<'a> Parser<'a> {
                     Err(err) => self.recover_closure_body(err, before, prev, token, lo, decl_hi)?,
                 }
             }
-            _ => {
-                // If an explicit return type is given, require a block to appear (RFC 968).
-                let body_lo = self.token.span;
-                self.parse_expr_block(None, body_lo, BlockCheckMode::Default)?
-            }
+            // Explicit return type (`->`) needs block `-> T { }`.
+            FnRetTy::Ty(ty) => self.parse_closure_block_body(ty.span)?,
         };
 
         match coroutine_kind {
@@ -2405,6 +2467,49 @@ impl<'a> Parser<'a> {
         Ok(closure)
     }
 
+    /// If an explicit return type is given, require a block to appear (RFC 968).
+    fn parse_closure_block_body(&mut self, ret_span: Span) -> PResult<'a, P<Expr>> {
+        if self.may_recover()
+            && self.token.can_begin_expr()
+            && !matches!(self.token.kind, TokenKind::OpenDelim(Delimiter::Brace))
+            && !self.token.is_whole_block()
+        {
+            let snapshot = self.create_snapshot_for_diagnostic();
+            let restrictions =
+                self.restrictions - Restrictions::STMT_EXPR - Restrictions::ALLOW_LET;
+            let tok = self.token.clone();
+            match self.parse_expr_res(restrictions, AttrWrapper::empty()) {
+                Ok((expr, _)) => {
+                    let descr = super::token_descr(&tok);
+                    let mut diag = self
+                        .dcx()
+                        .struct_span_err(tok.span, format!("expected `{{`, found {descr}"));
+                    diag.span_label(
+                        ret_span,
+                        "explicit return type requires closure body to be enclosed in braces",
+                    );
+                    diag.multipart_suggestion_verbose(
+                        "wrap the expression in curly braces",
+                        vec![
+                            (expr.span.shrink_to_lo(), "{ ".to_string()),
+                            (expr.span.shrink_to_hi(), " }".to_string()),
+                        ],
+                        Applicability::MachineApplicable,
+                    );
+                    diag.emit();
+                    return Ok(expr);
+                }
+                Err(diag) => {
+                    diag.cancel();
+                    self.restore_snapshot(snapshot);
+                }
+            }
+        }
+
+        let body_lo = self.token.span;
+        self.parse_expr_block(None, body_lo, BlockCheckMode::Default)
+    }
+
     /// Parses an optional `move` or `use` prefix to a closure-like construct.
     fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
         if self.eat_keyword(exp!(Move)) {
@@ -2836,7 +2941,7 @@ impl<'a> Parser<'a> {
     /// Parses `for await? <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
     fn parse_expr_for(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         let is_await =
-            self.token.uninterpolated_span().at_least_rust_2018() && self.eat_keyword(exp!(Await));
+            self.token_uninterpolated_span().at_least_rust_2018() && self.eat_keyword(exp!(Await));
 
         if is_await {
             self.psess.gated_spans.gate(sym::async_for_loop, self.prev_token.span);
@@ -3426,7 +3531,7 @@ impl<'a> Parser<'a> {
         self.token.is_keyword(kw::Try)
             && self
                 .look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace) || t.is_whole_block())
-            && self.token.uninterpolated_span().at_least_rust_2018()
+            && self.token_uninterpolated_span().at_least_rust_2018()
     }
 
     /// Parses an `async move? {...}` or `gen move? {...}` expression.
@@ -3809,8 +3914,8 @@ impl<'a> Parser<'a> {
         self.dcx().emit_err(errors::LeftArrowOperator { span });
     }
 
-    fn mk_assign_op(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
-        ExprKind::AssignOp(binop, lhs, rhs)
+    fn mk_assign_op(&self, assign_op: AssignOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
+        ExprKind::AssignOp(assign_op, lhs, rhs)
     }
 
     fn mk_range(
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index aad18578375..9405b58ab3b 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -34,10 +34,10 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
-    fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemInfo> {
+    fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemKind> {
         let safety = self.parse_safety(Case::Sensitive);
         self.expect_keyword(exp!(Mod))?;
-        let id = self.parse_ident()?;
+        let ident = self.parse_ident()?;
         let mod_kind = if self.eat(exp!(Semi)) {
             ModKind::Unloaded
         } else {
@@ -46,7 +46,7 @@ impl<'a> Parser<'a> {
             attrs.extend(inner_attrs);
             ModKind::Loaded(items, Inline::Yes, inner_span, Ok(()))
         };
-        Ok((id, ItemKind::Mod(safety, mod_kind)))
+        Ok(ItemKind::Mod(safety, ident, mod_kind))
     }
 
     /// Parses the contents of a module (inner attributes followed by module items).
@@ -115,8 +115,6 @@ impl<'a> Parser<'a> {
     }
 }
 
-pub(super) type ItemInfo = (Ident, ItemKind);
-
 impl<'a> Parser<'a> {
     pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<P<Item>>> {
         let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
@@ -163,11 +161,11 @@ impl<'a> Parser<'a> {
                 fn_parse_mode,
                 Case::Sensitive,
             )?;
-            if let Some((ident, kind)) = kind {
+            if let Some(kind) = kind {
                 this.error_on_unconsumed_default(def, &kind);
                 let span = lo.to(this.prev_token.span);
                 let id = DUMMY_NODE_ID;
-                let item = Item { ident, attrs, id, kind, vis, span, tokens: None };
+                let item = Item { attrs, id, kind, vis, span, tokens: None };
                 return Ok((Some(item), Trailing::No, UsePreAttrPos::No));
             }
 
@@ -208,7 +206,7 @@ impl<'a> Parser<'a> {
         def: &mut Defaultness,
         fn_parse_mode: FnParseMode,
         case: Case,
-    ) -> PResult<'a, Option<ItemInfo>> {
+    ) -> PResult<'a, Option<ItemKind>> {
         let check_pub = def == &Defaultness::Final;
         let mut def_ = || mem::replace(def, Defaultness::Final);
 
@@ -218,17 +216,15 @@ impl<'a> Parser<'a> {
             // FUNCTION ITEM
             let (ident, sig, generics, contract, body) =
                 self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
-            (
+            ItemKind::Fn(Box::new(Fn {
+                defaultness: def_(),
                 ident,
-                ItemKind::Fn(Box::new(Fn {
-                    defaultness: def_(),
-                    sig,
-                    generics,
-                    contract,
-                    body,
-                    define_opaque: None,
-                })),
-            )
+                sig,
+                generics,
+                contract,
+                body,
+                define_opaque: None,
+            }))
         } else if self.eat_keyword(exp!(Extern)) {
             if self.eat_keyword(exp!(Crate)) {
                 // EXTERN CRATE
@@ -247,8 +243,7 @@ impl<'a> Parser<'a> {
             // STATIC ITEM
             self.bump(); // `static`
             let mutability = self.parse_mutability();
-            let (ident, item) = self.parse_static_item(safety, mutability)?;
-            (ident, ItemKind::Static(Box::new(item)))
+            self.parse_static_item(safety, mutability)?
         } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
             // CONST ITEM
             if self.token.is_keyword(kw::Impl) {
@@ -258,16 +253,14 @@ impl<'a> Parser<'a> {
                 self.recover_const_mut(const_span);
                 self.recover_missing_kw_before_item()?;
                 let (ident, generics, ty, expr) = self.parse_const_item()?;
-                (
+                ItemKind::Const(Box::new(ConstItem {
+                    defaultness: def_(),
                     ident,
-                    ItemKind::Const(Box::new(ConstItem {
-                        defaultness: def_(),
-                        generics,
-                        ty,
-                        expr,
-                        define_opaque: None,
-                    })),
-                )
+                    generics,
+                    ty,
+                    expr,
+                    define_opaque: None,
+                }))
             }
         } else if self.check_keyword(exp!(Trait)) || self.check_auto_or_unsafe_trait_item() {
             // TRAIT ITEM
@@ -334,14 +327,14 @@ impl<'a> Parser<'a> {
                 self.recover_missing_kw_before_item()?;
             }
             // MACRO INVOCATION ITEM
-            (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?)))
+            ItemKind::MacCall(P(self.parse_item_macro(vis)?))
         } else {
             return Ok(None);
         };
         Ok(Some(info))
     }
 
-    fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemInfo>> {
+    fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
         let span = self.token.span;
         let token_name = super::token_descr(&self.token);
         let snapshot = self.create_snapshot_for_diagnostic();
@@ -359,7 +352,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn parse_use_item(&mut self) -> PResult<'a, ItemInfo> {
+    fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
         let tree = self.parse_use_tree()?;
         if let Err(mut e) = self.expect_semi() {
             match tree.kind {
@@ -373,7 +366,7 @@ impl<'a> Parser<'a> {
             }
             return Err(e);
         }
-        Ok((Ident::empty(), ItemKind::Use(tree)))
+        Ok(ItemKind::Use(tree))
     }
 
     /// When parsing a statement, would the start of a path be an item?
@@ -483,7 +476,7 @@ impl<'a> Parser<'a> {
         if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
     }
 
-    fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
+    fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemKind>> {
         // To be expanded
         Ok(None)
     }
@@ -577,7 +570,7 @@ impl<'a> Parser<'a> {
         &mut self,
         attrs: &mut AttrVec,
         defaultness: Defaultness,
-    ) -> PResult<'a, ItemInfo> {
+    ) -> PResult<'a, ItemKind> {
         let safety = self.parse_safety(Case::Sensitive);
         self.expect_keyword(exp!(Impl))?;
 
@@ -598,7 +591,7 @@ impl<'a> Parser<'a> {
         }
 
         // Parse stray `impl async Trait`
-        if (self.token.uninterpolated_span().at_least_rust_2018()
+        if (self.token_uninterpolated_span().at_least_rust_2018()
             && self.token.is_keyword(kw::Async))
             || self.is_kw_followed_by_ident(kw::Async)
         {
@@ -687,7 +680,7 @@ impl<'a> Parser<'a> {
             }
             None => (None, ty_first), // impl Type
         };
-        let item_kind = ItemKind::Impl(Box::new(Impl {
+        Ok(ItemKind::Impl(Box::new(Impl {
             safety,
             polarity,
             defaultness,
@@ -696,12 +689,10 @@ impl<'a> Parser<'a> {
             of_trait,
             self_ty,
             items: impl_items,
-        }));
-
-        Ok((Ident::empty(), item_kind))
+        })))
     }
 
-    fn parse_item_delegation(&mut self) -> PResult<'a, ItemInfo> {
+    fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
         let span = self.token.span;
         self.expect_keyword(exp!(Reuse))?;
 
@@ -724,7 +715,7 @@ impl<'a> Parser<'a> {
             })
         };
 
-        let (ident, item_kind) = if self.eat_path_sep() {
+        let item_kind = if self.eat_path_sep() {
             let suffixes = if self.eat(exp!(Star)) {
                 None
             } else {
@@ -732,7 +723,7 @@ impl<'a> Parser<'a> {
                 Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
             };
             let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? };
-            (Ident::empty(), ItemKind::DelegationMac(Box::new(deleg)))
+            ItemKind::DelegationMac(Box::new(deleg))
         } else {
             let rename = rename(self)?;
             let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
@@ -740,17 +731,18 @@ impl<'a> Parser<'a> {
                 id: DUMMY_NODE_ID,
                 qself,
                 path,
+                ident,
                 rename,
                 body: body(self)?,
                 from_glob: false,
             };
-            (ident, ItemKind::Delegation(Box::new(deleg)))
+            ItemKind::Delegation(Box::new(deleg))
         };
 
         let span = span.to(self.prev_token.span);
         self.psess.gated_spans.gate(sym::fn_delegation, span);
 
-        Ok((ident, item_kind))
+        Ok(item_kind)
     }
 
     fn parse_item_list<T>(
@@ -885,7 +877,7 @@ impl<'a> Parser<'a> {
             && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
         {
             self.bump(); // `default`
-            Defaultness::Default(self.prev_token.uninterpolated_span())
+            Defaultness::Default(self.prev_token_uninterpolated_span())
         } else {
             Defaultness::Final
         }
@@ -900,7 +892,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
-    fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> {
+    fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
         let safety = self.parse_safety(Case::Sensitive);
         // Parse optional `auto` prefix.
         let is_auto = if self.eat_keyword(exp!(Auto)) {
@@ -941,15 +933,12 @@ impl<'a> Parser<'a> {
 
             self.psess.gated_spans.gate(sym::trait_alias, whole_span);
 
-            Ok((ident, ItemKind::TraitAlias(generics, bounds)))
+            Ok(ItemKind::TraitAlias(ident, generics, bounds))
         } else {
             // It's a normal trait.
             generics.where_clause = self.parse_where_clause()?;
             let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
-            Ok((
-                ident,
-                ItemKind::Trait(Box::new(Trait { is_auto, safety, generics, bounds, items })),
-            ))
+            Ok(ItemKind::Trait(Box::new(Trait { is_auto, safety, ident, generics, bounds, items })))
         }
     }
 
@@ -977,11 +966,12 @@ impl<'a> Parser<'a> {
         force_collect: ForceCollect,
     ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
         Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
-            |Item { attrs, id, span, vis, ident, kind, tokens }| {
+            |Item { attrs, id, span, vis, kind, tokens }| {
                 let kind = match AssocItemKind::try_from(kind) {
                     Ok(kind) => kind,
                     Err(kind) => match kind {
                         ItemKind::Static(box StaticItem {
+                            ident,
                             ty,
                             safety: _,
                             mutability: _,
@@ -991,6 +981,7 @@ impl<'a> Parser<'a> {
                             self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
                             AssocItemKind::Const(Box::new(ConstItem {
                                 defaultness: Defaultness::Final,
+                                ident,
                                 generics: Generics::default(),
                                 ty,
                                 expr,
@@ -1000,7 +991,7 @@ impl<'a> Parser<'a> {
                         _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
                     },
                 };
-                Some(P(Item { attrs, id, span, vis, ident, kind, tokens }))
+                Some(P(Item { attrs, id, span, vis, kind, tokens }))
             },
         ))
     }
@@ -1010,7 +1001,7 @@ impl<'a> Parser<'a> {
     /// TypeAlias = "type" Ident Generics (":" GenericBounds)? WhereClause ("=" Ty)? WhereClause ";" ;
     /// ```
     /// The `"type"` has already been eaten.
-    fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemInfo> {
+    fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
         let ident = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
 
@@ -1045,16 +1036,14 @@ impl<'a> Parser<'a> {
 
         self.expect_semi()?;
 
-        Ok((
+        Ok(ItemKind::TyAlias(Box::new(TyAlias {
+            defaultness,
             ident,
-            ItemKind::TyAlias(Box::new(TyAlias {
-                defaultness,
-                generics,
-                where_clauses,
-                bounds,
-                ty,
-            })),
-        ))
+            generics,
+            where_clauses,
+            bounds,
+            ty,
+        })))
     }
 
     /// Parses a `UseTree`.
@@ -1158,16 +1147,16 @@ impl<'a> Parser<'a> {
     /// extern crate foo;
     /// extern crate bar as foo;
     /// ```
-    fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemInfo> {
+    fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
         // Accept `extern crate name-like-this` for better diagnostics
-        let orig_name = self.parse_crate_name_with_dashes()?;
-        let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
-            (rename, Some(orig_name.name))
+        let orig_ident = self.parse_crate_name_with_dashes()?;
+        let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
+            (Some(orig_ident.name), rename)
         } else {
-            (orig_name, None)
+            (None, orig_ident)
         };
         self.expect_semi()?;
-        Ok((item_name, ItemKind::ExternCrate(orig_name)))
+        Ok(ItemKind::ExternCrate(orig_name, item_ident))
     }
 
     fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
@@ -1218,8 +1207,8 @@ impl<'a> Parser<'a> {
         &mut self,
         attrs: &mut AttrVec,
         mut safety: Safety,
-    ) -> PResult<'a, ItemInfo> {
-        let extern_span = self.prev_token.uninterpolated_span();
+    ) -> PResult<'a, ItemKind> {
+        let extern_span = self.prev_token_uninterpolated_span();
         let abi = self.parse_abi(); // ABI?
         // FIXME: This recovery should be tested better.
         if safety == Safety::Default
@@ -1230,13 +1219,12 @@ impl<'a> Parser<'a> {
             safety = Safety::Unsafe(self.token.span);
             let _ = self.eat_keyword(exp!(Unsafe));
         }
-        let module = ast::ForeignMod {
+        Ok(ItemKind::ForeignMod(ast::ForeignMod {
             extern_span,
             safety,
             abi,
             items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
-        };
-        Ok((Ident::empty(), ItemKind::ForeignMod(module)))
+        }))
     }
 
     /// Parses a foreign item (one in an `extern { ... }` block).
@@ -1246,11 +1234,11 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, Option<Option<P<ForeignItem>>>> {
         let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: false };
         Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
-            |Item { attrs, id, span, vis, ident, kind, tokens }| {
+            |Item { attrs, id, span, vis, kind, tokens }| {
                 let kind = match ForeignItemKind::try_from(kind) {
                     Ok(kind) => kind,
                     Err(kind) => match kind {
-                        ItemKind::Const(box ConstItem { ty, expr, .. }) => {
+                        ItemKind::Const(box ConstItem { ident, ty, expr, .. }) => {
                             let const_span = Some(span.with_hi(ident.span.lo()))
                                 .filter(|span| span.can_be_used_for_suggestions());
                             self.dcx().emit_err(errors::ExternItemCannotBeConst {
@@ -1258,6 +1246,7 @@ impl<'a> Parser<'a> {
                                 const_span,
                             });
                             ForeignItemKind::Static(Box::new(StaticItem {
+                                ident,
                                 ty,
                                 mutability: Mutability::Not,
                                 expr,
@@ -1268,7 +1257,7 @@ impl<'a> Parser<'a> {
                         _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
                     },
                 };
-                Some(P(Item { attrs, id, span, vis, ident, kind, tokens }))
+                Some(P(Item { attrs, id, span, vis, kind, tokens }))
             },
         ))
     }
@@ -1301,12 +1290,24 @@ impl<'a> Parser<'a> {
     }
 
     fn is_unsafe_foreign_mod(&self) -> bool {
-        self.token.is_keyword(kw::Unsafe)
-            && self.is_keyword_ahead(1, &[kw::Extern])
-            && self.look_ahead(
-                2 + self.look_ahead(2, |t| t.can_begin_string_literal() as usize),
-                |t| *t == token::OpenDelim(Delimiter::Brace),
-            )
+        // Look for `unsafe`.
+        if !self.token.is_keyword(kw::Unsafe) {
+            return false;
+        }
+        // Look for `extern`.
+        if !self.is_keyword_ahead(1, &[kw::Extern]) {
+            return false;
+        }
+
+        // Look for the optional ABI string literal.
+        let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
+
+        // Look for the `{`. Use `tree_look_ahead` because the ABI (if present)
+        // might be a metavariable i.e. an invisible-delimited sequence, and
+        // `tree_look_ahead` will consider that a single element when looking
+        // ahead.
+        self.tree_look_ahead(n, |t| matches!(t, TokenTree::Delimited(_, _, Delimiter::Brace, _)))
+            == Some(true)
     }
 
     fn is_static_global(&mut self) -> bool {
@@ -1343,13 +1344,13 @@ impl<'a> Parser<'a> {
         const_span: Span,
         attrs: &mut AttrVec,
         defaultness: Defaultness,
-    ) -> PResult<'a, ItemInfo> {
+    ) -> PResult<'a, ItemKind> {
         let impl_span = self.token.span;
         let err = self.expected_ident_found_err();
 
         // Only try to recover if this is implementing a trait for a type
-        let mut impl_info = match self.parse_item_impl(attrs, defaultness) {
-            Ok(impl_info) => impl_info,
+        let mut item_kind = match self.parse_item_impl(attrs, defaultness) {
+            Ok(item_kind) => item_kind,
             Err(recovery_error) => {
                 // Recovery failed, raise the "expected identifier" error
                 recovery_error.cancel();
@@ -1357,7 +1358,7 @@ impl<'a> Parser<'a> {
             }
         };
 
-        match &mut impl_info.1 {
+        match &mut item_kind {
             ItemKind::Impl(box Impl { of_trait: Some(trai), constness, .. }) => {
                 *constness = Const::Yes(const_span);
 
@@ -1374,10 +1375,11 @@ impl<'a> Parser<'a> {
             _ => unreachable!(),
         }
 
-        Ok(impl_info)
+        Ok(item_kind)
     }
 
-    /// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in `mutability`.
+    /// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in
+    /// `mutability`.
     ///
     /// ```ebnf
     /// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
@@ -1386,7 +1388,7 @@ impl<'a> Parser<'a> {
         &mut self,
         safety: Safety,
         mutability: Mutability,
-    ) -> PResult<'a, (Ident, StaticItem)> {
+    ) -> PResult<'a, ItemKind> {
         let ident = self.parse_ident()?;
 
         if self.token == TokenKind::Lt && self.may_recover() {
@@ -1398,7 +1400,8 @@ impl<'a> Parser<'a> {
         // FIXME: This could maybe benefit from `.may_recover()`?
         let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
             (true, false) => self.parse_ty()?,
-            // If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing type.
+            // If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing
+            // type.
             (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
         };
 
@@ -1406,7 +1409,8 @@ impl<'a> Parser<'a> {
 
         self.expect_semi()?;
 
-        Ok((ident, StaticItem { ty, safety, mutability, expr, define_opaque: None }))
+        let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
+        Ok(ItemKind::Static(Box::new(item)))
     }
 
     /// Parse a constant item with the prefix `"const"` already parsed.
@@ -1531,7 +1535,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an enum declaration.
-    fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
+    fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
         if self.token.is_keyword(kw::Struct) {
             let span = self.prev_token.span.to(self.token.span);
             let err = errors::EnumStructMutuallyExclusive { span };
@@ -1544,7 +1548,7 @@ impl<'a> Parser<'a> {
         }
 
         let prev_span = self.prev_token.span;
-        let id = self.parse_ident()?;
+        let ident = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
         generics.where_clause = self.parse_where_clause()?;
 
@@ -1555,10 +1559,10 @@ impl<'a> Parser<'a> {
             (thin_vec![], Trailing::No)
         } else {
             self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
-                p.parse_enum_variant(id.span)
+                p.parse_enum_variant(ident.span)
             })
             .map_err(|mut err| {
-                err.span_label(id.span, "while parsing this enum");
+                err.span_label(ident.span, "while parsing this enum");
                 if self.token == token::Colon {
                     let snapshot = self.create_snapshot_for_diagnostic();
                     self.bump();
@@ -1584,7 +1588,7 @@ impl<'a> Parser<'a> {
         };
 
         let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
-        Ok((id, ItemKind::Enum(enum_definition, generics)))
+        Ok(ItemKind::Enum(ident, enum_definition, generics))
     }
 
     fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
@@ -1676,8 +1680,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `struct Foo { ... }`.
-    fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
-        let class_name = self.parse_ident()?;
+    fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
+        let ident = self.parse_ident()?;
 
         let mut generics = self.parse_generics()?;
 
@@ -1698,7 +1702,7 @@ impl<'a> Parser<'a> {
         let vdata = if self.token.is_keyword(kw::Where) {
             let tuple_struct_body;
             (generics.where_clause, tuple_struct_body) =
-                self.parse_struct_where_clause(class_name, generics.span)?;
+                self.parse_struct_where_clause(ident, generics.span)?;
 
             if let Some(body) = tuple_struct_body {
                 // If we see a misplaced tuple struct body: `struct Foo<T> where T: Copy, (T);`
@@ -1712,7 +1716,7 @@ impl<'a> Parser<'a> {
                 // If we see: `struct Foo<T> where T: Copy { ... }`
                 let (fields, recovered) = self.parse_record_struct_body(
                     "struct",
-                    class_name.span,
+                    ident.span,
                     generics.where_clause.has_where_token,
                 )?;
                 VariantData::Struct { fields, recovered }
@@ -1724,7 +1728,7 @@ impl<'a> Parser<'a> {
         } else if self.token == token::OpenDelim(Delimiter::Brace) {
             let (fields, recovered) = self.parse_record_struct_body(
                 "struct",
-                class_name.span,
+                ident.span,
                 generics.where_clause.has_where_token,
             )?;
             VariantData::Struct { fields, recovered }
@@ -1740,12 +1744,12 @@ impl<'a> Parser<'a> {
             return Err(self.dcx().create_err(err));
         };
 
-        Ok((class_name, ItemKind::Struct(vdata, generics)))
+        Ok(ItemKind::Struct(ident, vdata, generics))
     }
 
     /// Parses `union Foo { ... }`.
-    fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
-        let class_name = self.parse_ident()?;
+    fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
+        let ident = self.parse_ident()?;
 
         let mut generics = self.parse_generics()?;
 
@@ -1753,14 +1757,14 @@ impl<'a> Parser<'a> {
             generics.where_clause = self.parse_where_clause()?;
             let (fields, recovered) = self.parse_record_struct_body(
                 "union",
-                class_name.span,
+                ident.span,
                 generics.where_clause.has_where_token,
             )?;
             VariantData::Struct { fields, recovered }
         } else if self.token == token::OpenDelim(Delimiter::Brace) {
             let (fields, recovered) = self.parse_record_struct_body(
                 "union",
-                class_name.span,
+                ident.span,
                 generics.where_clause.has_where_token,
             )?;
             VariantData::Struct { fields, recovered }
@@ -1772,7 +1776,7 @@ impl<'a> Parser<'a> {
             return Err(err);
         };
 
-        Ok((class_name, ItemKind::Union(vdata, generics)))
+        Ok(ItemKind::Union(ident, vdata, generics))
     }
 
     /// This function parses the fields of record structs:
@@ -2124,15 +2128,17 @@ impl<'a> Parser<'a> {
                 }
             } else if self.eat_keyword(exp!(Struct)) {
                 match self.parse_item_struct() {
-                    Ok((ident, _)) => self
-                        .dcx()
-                        .struct_span_err(
-                            lo.with_hi(ident.span.hi()),
-                            format!("structs are not allowed in {adt_ty} definitions"),
-                        )
-                        .with_help(
-                            "consider creating a new `struct` definition instead of nesting",
-                        ),
+                    Ok(item) => {
+                        let ItemKind::Struct(ident, ..) = item else { unreachable!() };
+                        self.dcx()
+                            .struct_span_err(
+                                lo.with_hi(ident.span.hi()),
+                                format!("structs are not allowed in {adt_ty} definitions"),
+                            )
+                            .with_help(
+                                "consider creating a new `struct` definition instead of nesting",
+                            )
+                    }
                     Err(err) => {
                         err.cancel();
                         self.restore_snapshot(snapshot);
@@ -2177,7 +2183,7 @@ impl<'a> Parser<'a> {
     /// MacParams = "(" TOKEN_STREAM ")" ;
     /// DeclMac = "macro" Ident MacParams? MacBody ;
     /// ```
-    fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> {
+    fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
         let ident = self.parse_ident()?;
         let body = if self.check(exp!(OpenBrace)) {
             self.parse_delim_args()? // `MacBody`
@@ -2199,7 +2205,7 @@ impl<'a> Parser<'a> {
         };
 
         self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
-        Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, macro_rules: false })))
+        Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
     }
 
     /// Is this a possibly malformed start of a `macro_rules! foo` item definition?
@@ -2228,7 +2234,7 @@ impl<'a> Parser<'a> {
         &mut self,
         vis: &Visibility,
         has_bang: bool,
-    ) -> PResult<'a, ItemInfo> {
+    ) -> PResult<'a, ItemKind> {
         self.expect_keyword(exp!(MacroRules))?; // `macro_rules`
 
         if has_bang {
@@ -2246,7 +2252,7 @@ impl<'a> Parser<'a> {
         self.eat_semi_for_macro_if_needed(&body);
         self.complain_if_pub_macro(vis, true);
 
-        Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, macro_rules: true })))
+        Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
     }
 
     /// Item macro invocations or `macro_rules!` definitions need inherited visibility.
@@ -2610,13 +2616,36 @@ impl<'a> Parser<'a> {
                 })
             // `extern ABI fn`
             || self.check_keyword_case(exp!(Extern), case)
+                // Use `tree_look_ahead` because `ABI` might be a metavariable,
+                // i.e. an invisible-delimited sequence, and `tree_look_ahead`
+                // will consider that a single element when looking ahead.
                 && self.look_ahead(1, |t| t.can_begin_string_literal())
-                && (self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case)) ||
+                && (self.tree_look_ahead(2, |tt| {
+                    match tt {
+                        TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
+                        TokenTree::Delimited(..) => false,
+                    }
+                }) == Some(true) ||
                     // This branch is only for better diagnostics; `pub`, `unsafe`, etc. are not
                     // allowed here.
                     (self.may_recover()
-                        && self.look_ahead(2, |t| ALL_QUALS.iter().any(|exp| t.is_keyword(exp.kw)))
-                        && self.look_ahead(3, |t| t.is_keyword_case(kw::Fn, case))))
+                        && self.tree_look_ahead(2, |tt| {
+                            match tt {
+                                TokenTree::Token(t, _) =>
+                                    ALL_QUALS.iter().any(|exp| {
+                                        t.is_keyword(exp.kw)
+                                    }),
+                                TokenTree::Delimited(..) => false,
+                            }
+                        }) == Some(true)
+                        && self.tree_look_ahead(3, |tt| {
+                            match tt {
+                                TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
+                                TokenTree::Delimited(..) => false,
+                            }
+                        }) == Some(true)
+                    )
+                )
     }
 
     /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration,
@@ -2752,7 +2781,7 @@ impl<'a> Parser<'a> {
                             .expect("Span extracted directly from keyword should always work");
 
                         err.span_suggestion(
-                            self.token.uninterpolated_span(),
+                            self.token_uninterpolated_span(),
                             format!("`{original_kw}` already used earlier, remove this one"),
                             "",
                             Applicability::MachineApplicable,
@@ -2763,7 +2792,7 @@ impl<'a> Parser<'a> {
                     else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
                         let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
                         if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
-                            let misplaced_qual_sp = self.token.uninterpolated_span();
+                            let misplaced_qual_sp = self.token_uninterpolated_span();
                             let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
 
                             err.span_suggestion(
@@ -2931,13 +2960,30 @@ impl<'a> Parser<'a> {
                 let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
                 this.eat_incorrect_doc_comment_for_param_type();
                 let mut ty = this.parse_ty_for_param();
-                if ty.is_ok()
-                    && this.token != token::Comma
-                    && this.token != token::CloseDelim(Delimiter::Parenthesis)
-                {
-                    // This wasn't actually a type, but a pattern looking like a type,
-                    // so we are going to rollback and re-parse for recovery.
-                    ty = this.unexpected_any();
+
+                if let Ok(t) = &ty {
+                    // Check for trailing angle brackets
+                    if let TyKind::Path(_, Path { segments, .. }) = &t.kind {
+                        if let Some(segment) = segments.last() {
+                            if let Some(guar) =
+                                this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
+                            {
+                                return Ok((
+                                    dummy_arg(segment.ident, guar),
+                                    Trailing::No,
+                                    UsePreAttrPos::No,
+                                ));
+                            }
+                        }
+                    }
+
+                    if this.token != token::Comma
+                        && this.token != token::CloseDelim(Delimiter::Parenthesis)
+                    {
+                        // This wasn't actually a type, but a pattern looking like a type,
+                        // so we are going to rollback and re-parse for recovery.
+                        ty = this.unexpected_any();
+                    }
                 }
                 match ty {
                     Ok(ty) => {
@@ -2948,6 +2994,7 @@ impl<'a> Parser<'a> {
                     }
                     // If this is a C-variadic argument and we hit an error, return the error.
                     Err(err) if this.token == token::DotDotDot => return Err(err),
+                    Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
                     // Recover from attempting to parse the argument as a type without pattern.
                     Err(err) => {
                         err.cancel();
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index a79b4048288..3b0861a9942 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -24,8 +24,8 @@ pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
 use path::PathStyle;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{
-    self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, NtPatKind, Token,
-    TokenKind,
+    self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, NtExprKind, NtPatKind,
+    Token, TokenKind,
 };
 use rustc_ast::tokenstream::{AttrsTarget, Spacing, TokenStream, TokenTree};
 use rustc_ast::util::case::Case;
@@ -101,6 +101,7 @@ pub enum ForceCollect {
 #[macro_export]
 macro_rules! maybe_whole {
     ($p:expr, $constructor:ident, |$x:ident| $e:expr) => {
+        #[allow(irrefutable_let_patterns)] // FIXME: temporary
         if let token::Interpolated(nt) = &$p.token.kind
             && let token::$constructor(x) = &**nt
         {
@@ -299,6 +300,10 @@ impl TokenTreeCursor {
         self.stream.get(self.index)
     }
 
+    fn look_ahead(&self, n: usize) -> Option<&TokenTree> {
+        self.stream.get(self.index + n)
+    }
+
     #[inline]
     fn bump(&mut self) {
         self.index += 1;
@@ -507,6 +512,14 @@ impl<'a> Parser<'a> {
         self
     }
 
+    #[inline]
+    fn with_recovery<T>(&mut self, recovery: Recovery, f: impl FnOnce(&mut Self) -> T) -> T {
+        let old = mem::replace(&mut self.recovery, recovery);
+        let res = f(self);
+        self.recovery = old;
+        res
+    }
+
     /// Whether the parser is allowed to recover from broken code.
     ///
     /// If this returns false, recovering broken code into valid code (especially if this recovery does lookahead)
@@ -765,7 +778,14 @@ impl<'a> Parser<'a> {
             && match_mv_kind(mv_kind)
         {
             self.bump();
-            let res = f(self).expect("failed to reparse {mv_kind:?}");
+
+            // Recovery is disabled when parsing macro arguments, so it must
+            // also be disabled when reparsing pasted macro arguments,
+            // otherwise we get inconsistent results (e.g. #137874).
+            let res = self.with_recovery(Recovery::Forbidden, |this| {
+                f(this).expect("failed to reparse {mv_kind:?}")
+            });
+
             if let token::CloseDelim(delim) = self.token.kind
                 && let Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind)) = delim
                 && match_mv_kind(mv_kind)
@@ -1290,6 +1310,17 @@ impl<'a> Parser<'a> {
         looker(&token)
     }
 
+    /// Like `lookahead`, but skips over token trees rather than tokens. Useful
+    /// when looking past possible metavariable pasting sites.
+    pub fn tree_look_ahead<R>(
+        &self,
+        dist: usize,
+        looker: impl FnOnce(&TokenTree) -> R,
+    ) -> Option<R> {
+        assert_ne!(dist, 0);
+        self.token_cursor.curr.look_ahead(dist - 1).map(looker)
+    }
+
     /// Returns whether any of the given keywords are `dist` tokens ahead of the current one.
     pub(crate) fn is_keyword_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {
         self.look_ahead(dist, |t| kws.iter().any(|&kw| t.is_keyword(kw)))
@@ -1297,14 +1328,14 @@ impl<'a> Parser<'a> {
 
     /// Parses asyncness: `async` or nothing.
     fn parse_coroutine_kind(&mut self, case: Case) -> Option<CoroutineKind> {
-        let span = self.token.uninterpolated_span();
+        let span = self.token_uninterpolated_span();
         if self.eat_keyword_case(exp!(Async), case) {
             // FIXME(gen_blocks): Do we want to unconditionally parse `gen` and then
             // error if edition <= 2024, like we do with async and edition <= 2018?
-            if self.token.uninterpolated_span().at_least_rust_2024()
+            if self.token_uninterpolated_span().at_least_rust_2024()
                 && self.eat_keyword_case(exp!(Gen), case)
             {
-                let gen_span = self.prev_token.uninterpolated_span();
+                let gen_span = self.prev_token_uninterpolated_span();
                 Some(CoroutineKind::AsyncGen {
                     span: span.to(gen_span),
                     closure_id: DUMMY_NODE_ID,
@@ -1317,7 +1348,7 @@ impl<'a> Parser<'a> {
                     return_impl_trait_id: DUMMY_NODE_ID,
                 })
             }
-        } else if self.token.uninterpolated_span().at_least_rust_2024()
+        } else if self.token_uninterpolated_span().at_least_rust_2024()
             && self.eat_keyword_case(exp!(Gen), case)
         {
             Some(CoroutineKind::Gen {
@@ -1333,9 +1364,9 @@ impl<'a> Parser<'a> {
     /// Parses fn unsafety: `unsafe`, `safe` or nothing.
     fn parse_safety(&mut self, case: Case) -> Safety {
         if self.eat_keyword_case(exp!(Unsafe), case) {
-            Safety::Unsafe(self.prev_token.uninterpolated_span())
+            Safety::Unsafe(self.prev_token_uninterpolated_span())
         } else if self.eat_keyword_case(exp!(Safe), case) {
-            Safety::Safe(self.prev_token.uninterpolated_span())
+            Safety::Safe(self.prev_token_uninterpolated_span())
         } else {
             Safety::Default
         }
@@ -1362,7 +1393,7 @@ impl<'a> Parser<'a> {
                 .look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace) || t.is_whole_block())
             && self.eat_keyword_case(exp!(Const), case)
         {
-            Const::Yes(self.prev_token.uninterpolated_span())
+            Const::Yes(self.prev_token_uninterpolated_span())
         } else {
             Const::No
         }
@@ -1370,9 +1401,6 @@ impl<'a> Parser<'a> {
 
     /// Parses inline const expressions.
     fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
-        if pat {
-            self.psess.gated_spans.gate(sym::inline_const_pat, span);
-        }
         self.expect_keyword(exp!(Const))?;
         let (attrs, blk) = self.parse_inner_attrs_and_block(None)?;
         let anon_const = AnonConst {
@@ -1380,7 +1408,17 @@ impl<'a> Parser<'a> {
             value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
         };
         let blk_span = anon_const.value.span;
-        Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(anon_const), attrs))
+        let kind = if pat {
+            let guar = self
+                .dcx()
+                .struct_span_err(blk_span, "`inline_const_pat` has been removed")
+                .with_help("use a named `const`-item or an `if`-guard instead")
+                .emit();
+            ExprKind::Err(guar)
+        } else {
+            ExprKind::ConstBlock(anon_const)
+        };
+        Ok(self.mk_expr_with_attrs(span.to(blk_span), kind, attrs))
     }
 
     /// Parses mutability (`mut` or nothing).
@@ -1699,6 +1737,35 @@ impl<'a> Parser<'a> {
     pub fn approx_token_stream_pos(&self) -> u32 {
         self.num_bump_calls
     }
+
+    /// For interpolated `self.token`, returns a span of the fragment to which
+    /// the interpolated token refers. For all other tokens this is just a
+    /// regular span. It is particularly important to use this for identifiers
+    /// and lifetimes for which spans affect name resolution and edition
+    /// checks. Note that keywords are also identifiers, so they should use
+    /// this if they keep spans or perform edition checks.
+    pub fn token_uninterpolated_span(&self) -> Span {
+        match &self.token.kind {
+            token::NtIdent(ident, _) | token::NtLifetime(ident, _) => ident.span,
+            token::Interpolated(nt) => nt.use_span(),
+            token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(_))) => {
+                self.look_ahead(1, |t| t.span)
+            }
+            _ => self.token.span,
+        }
+    }
+
+    /// Like `token_uninterpolated_span`, but works on `self.prev_token`.
+    pub fn prev_token_uninterpolated_span(&self) -> Span {
+        match &self.prev_token.kind {
+            token::NtIdent(ident, _) | token::NtLifetime(ident, _) => ident.span,
+            token::Interpolated(nt) => nt.use_span(),
+            token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(_))) => {
+                self.look_ahead(0, |t| t.span)
+            }
+            _ => self.prev_token.span,
+        }
+    }
 }
 
 pub(crate) fn make_unclosed_delims_error(
@@ -1751,6 +1818,8 @@ pub enum ParseNtResult {
     Item(P<ast::Item>),
     Stmt(P<ast::Stmt>),
     Pat(P<ast::Pat>, NtPatKind),
+    Expr(P<ast::Expr>, NtExprKind),
+    Literal(P<ast::Expr>),
     Ty(P<ast::Ty>),
     Meta(P<ast::AttrItem>),
     Path(P<ast::Path>),
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 1123755ce00..b4e540d670d 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -48,10 +48,6 @@ impl<'a> Parser<'a> {
         /// Old variant of `may_be_ident`. Being phased out.
         fn nt_may_be_ident(nt: &Nonterminal) -> bool {
             match nt {
-                NtExpr(_)
-                | NtLiteral(_) // `true`, `false`
-                => true,
-
                 NtBlock(_) => false,
             }
         }
@@ -95,7 +91,7 @@ impl<'a> Parser<'a> {
                 token::OpenDelim(Delimiter::Brace) => true,
                 token::NtLifetime(..) => true,
                 token::Interpolated(nt) => match &**nt {
-                    NtBlock(_) | NtExpr(_) | NtLiteral(_) => true,
+                    NtBlock(_) => true,
                 },
                 token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k {
                     MetaVarKind::Block
@@ -179,10 +175,14 @@ impl<'a> Parser<'a> {
                     pat_kind,
                 ));
             }
-            NonterminalKind::Expr(_) => NtExpr(self.parse_expr_force_collect()?),
+            NonterminalKind::Expr(expr_kind) => {
+                return Ok(ParseNtResult::Expr(self.parse_expr_force_collect()?, expr_kind));
+            }
             NonterminalKind::Literal => {
-                // The `:literal` matcher does not support attributes
-                NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?)
+                // The `:literal` matcher does not support attributes.
+                return Ok(ParseNtResult::Literal(
+                    self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?,
+                ));
             }
             NonterminalKind::Ty => {
                 return Ok(ParseNtResult::Ty(
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index ec14c5718da..9612f71b2af 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -631,15 +631,6 @@ impl<'a> Parser<'a> {
                             ident,
                             indentation,
                         });
-
-                        // help: wrap the expr in a `const { expr }`
-                        // FIXME(inline_const_pat): once stabilized, remove this check and remove the `(requires #[feature(inline_const_pat)])` note from the message
-                        if self.parser.psess.unstable_features.is_nightly_build() {
-                            err.subdiagnostic(UnexpectedExpressionInPatternSugg::InlineConst {
-                                start_span: expr_span.shrink_to_lo(),
-                                end_span: expr_span.shrink_to_hi(),
-                            });
-                        }
                     },
                 );
             }
@@ -1261,7 +1252,7 @@ impl<'a> Parser<'a> {
                 || *t == token::Dot // e.g. `.5` for recovery;
                 || matches!(t.kind, token::Literal(..) | token::Minus)
                 || t.is_bool_lit()
-                || t.is_whole_expr()
+                || t.is_metavar_expr()
                 || t.is_lifetime() // recover `'a` instead of `'a'`
                 || (self.may_recover() // recover leading `(`
                     && *t == token::OpenDelim(Delimiter::Parenthesis)
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 97cd4d2117f..2cd09aa8959 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -73,7 +73,20 @@ impl<'a> Parser<'a> {
             });
         }
 
-        let stmt = if self.token.is_keyword(kw::Let) {
+        let stmt = if self.token.is_keyword(kw::Super) && self.is_keyword_ahead(1, &[kw::Let]) {
+            self.collect_tokens(None, attrs, force_collect, |this, attrs| {
+                this.expect_keyword(exp!(Super))?;
+                this.psess.gated_spans.gate(sym::super_let, this.prev_token.span);
+                this.expect_keyword(exp!(Let))?;
+                let local = this.parse_local(attrs)?; // FIXME(mara): implement super let
+                let trailing = Trailing::from(capture_semi && this.token == token::Semi);
+                Ok((
+                    this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)),
+                    trailing,
+                    UsePreAttrPos::No,
+                ))
+            })?
+        } else if self.token.is_keyword(kw::Let) {
             self.collect_tokens(None, attrs, force_collect, |this, attrs| {
                 this.expect_keyword(exp!(Let))?;
                 let local = this.parse_local(attrs)?;
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index 471966d086d..49ae6cb9b72 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -2922,7 +2922,7 @@ fn out_of_line_mod() {
         .unwrap()
         .unwrap();
 
-        let ast::ItemKind::Mod(_, mod_kind) = &item.kind else { panic!() };
+        let ast::ItemKind::Mod(_, _, mod_kind) = &item.kind else { panic!() };
         assert_matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2);
     });
 }
diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs
index 886438fd583..add3c970201 100644
--- a/compiler/rustc_parse/src/parser/token_type.rs
+++ b/compiler/rustc_parse/src/parser/token_type.rs
@@ -114,6 +114,7 @@ pub enum TokenType {
     KwSelfUpper,
     KwStatic,
     KwStruct,
+    KwSuper,
     KwTrait,
     KwTry,
     KwType,
@@ -250,6 +251,7 @@ impl TokenType {
             KwSelfUpper,
             KwStatic,
             KwStruct,
+            KwSuper,
             KwTrait,
             KwTry,
             KwType,
@@ -324,6 +326,7 @@ impl TokenType {
             TokenType::KwSelfUpper => Some(kw::SelfUpper),
             TokenType::KwStatic => Some(kw::Static),
             TokenType::KwStruct => Some(kw::Struct),
+            TokenType::KwSuper => Some(kw::Super),
             TokenType::KwTrait => Some(kw::Trait),
             TokenType::KwTry => Some(kw::Try),
             TokenType::KwType => Some(kw::Type),
@@ -549,6 +552,7 @@ macro_rules! exp {
     (SelfUpper)      => { exp!(@kw, SelfUpper,  KwSelfUpper) };
     (Static)         => { exp!(@kw, Static,     KwStatic) };
     (Struct)         => { exp!(@kw, Struct,     KwStruct) };
+    (Super)          => { exp!(@kw, Super,      KwSuper) };
     (Trait)          => { exp!(@kw, Trait,      KwTrait) };
     (Try)            => { exp!(@kw, Try,        KwTry) };
     (Type)           => { exp!(@kw, Type,       KwType) };
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index b45ebae079c..93705da22c4 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -775,7 +775,7 @@ impl<'a> Parser<'a> {
     /// Is a `dyn B0 + ... + Bn` type allowed here?
     fn is_explicit_dyn_type(&mut self) -> bool {
         self.check_keyword(exp!(Dyn))
-            && (self.token.uninterpolated_span().at_least_rust_2018()
+            && (self.token_uninterpolated_span().at_least_rust_2018()
                 || self.look_ahead(1, |t| {
                     (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::Star)
                         && !can_continue_type_after_non_fn_ident(t)
@@ -998,13 +998,13 @@ impl<'a> Parser<'a> {
             BoundConstness::Never
         };
 
-        let asyncness = if self.token.uninterpolated_span().at_least_rust_2018()
+        let asyncness = if self.token_uninterpolated_span().at_least_rust_2018()
             && self.eat_keyword(exp!(Async))
         {
             self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
             BoundAsyncness::Async(self.prev_token.span)
         } else if self.may_recover()
-            && self.token.uninterpolated_span().is_rust_2015()
+            && self.token_uninterpolated_span().is_rust_2015()
             && self.is_kw_followed_by_ident(kw::Async)
         {
             self.bump(); // eat `async`
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 06398dd4f72..bea86801ed7 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -383,6 +383,10 @@ passes_inline_ignored_constants =
     .warn = {-passes_previously_accepted}
     .note = {-passes_see_issue(issue: "65833")}
 
+passes_inline_ignored_for_exported =
+    `#[inline]` is ignored on externally exported functions
+    .help = externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
+
 passes_inline_ignored_function_prototype =
     `#[inline]` is ignored on function prototypes
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 1e1fb42a48f..669349f3380 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -35,7 +35,7 @@ use rustc_session::lint::builtin::{
     UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
 };
 use rustc_session::parse::feature_err;
-use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, kw, sym};
+use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, kw, sym};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
 use rustc_trait_selection::traits::ObligationCtxt;
@@ -451,6 +451,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 });
             }
         }
+
+        // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
+        if let Some(did) = hir_id.as_owner()
+            && self.tcx.def_kind(did).has_codegen_attrs()
+            && !matches!(attr.meta_item_list().as_deref(), Some([item]) if item.has_name(sym::never))
+        {
+            let attrs = self.tcx.codegen_fn_attrs(did);
+            // Not checking naked as `#[inline]` is forbidden for naked functions anyways.
+            if attrs.contains_extern_indicator() {
+                self.tcx.emit_node_span_lint(
+                    UNUSED_ATTRIBUTES,
+                    hir_id,
+                    attr.span(),
+                    errors::InlineIgnoredForExported {},
+                );
+            }
+        }
     }
 
     /// Checks that `#[coverage(..)]` is applied to a function/closure/method,
@@ -1021,14 +1038,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we
             // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the
             // `#[doc(keyword = "SelfTy")` attribute in `library/std/src/keyword_docs.rs`.
-            s <= kw::Union || s == sym::SelfTy
+            s.is_reserved(|| edition::LATEST_STABLE_EDITION) || s.is_weak() || s == sym::SelfTy
         }
 
-        let doc_keyword = meta.value_str().unwrap_or(kw::Empty);
-        if doc_keyword == kw::Empty {
-            self.doc_attr_str_error(meta, "keyword");
-            return;
-        }
+        let doc_keyword = match meta.value_str() {
+            Some(value) if value != kw::Empty => value,
+            _ => return self.doc_attr_str_error(meta, "keyword"),
+        };
+
         let item_kind = match self.tcx.hir_node(hir_id) {
             hir::Node::Item(item) => Some(&item.kind),
             _ => None,
@@ -1140,7 +1157,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     errors::DocInlineOnlyUse {
                         attr_span: meta.span(),
                         item_span: (attr.style() == AttrStyle::Outer)
-                            .then(|| self.tcx.hir().span(hir_id)),
+                            .then(|| self.tcx.hir_span(hir_id)),
                     },
                 );
             }
@@ -1162,7 +1179,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 errors::DocMaskedOnlyExternCrate {
                     attr_span: meta.span(),
                     item_span: (attr.style() == AttrStyle::Outer)
-                        .then(|| self.tcx.hir().span(hir_id)),
+                        .then(|| self.tcx.hir_span(hir_id)),
                 },
             );
             return;
@@ -1176,7 +1193,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 errors::DocMaskedNotExternCrateSelf {
                     attr_span: meta.span(),
                     item_span: (attr.style() == AttrStyle::Outer)
-                        .then(|| self.tcx.hir().span(hir_id)),
+                        .then(|| self.tcx.hir_span(hir_id)),
                 },
             );
         }
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index f77e1db42d4..0060e726a8e 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -19,8 +19,8 @@ use rustc_middle::middle::privacy::Level;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::{bug, span_bug};
-use rustc_session::lint;
 use rustc_session::lint::builtin::DEAD_CODE;
+use rustc_session::lint::{self, LintExpectationId};
 use rustc_span::{Symbol, sym};
 
 use crate::errors::{
@@ -421,10 +421,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 }
                 hir::ItemKind::ForeignMod { .. } => {}
                 hir::ItemKind::Trait(..) => {
-                    for impl_def_id in self.tcx.all_impls(item.owner_id.to_def_id()) {
-                        if let Some(local_def_id) = impl_def_id.as_local()
-                            && let ItemKind::Impl(impl_ref) =
-                                self.tcx.hir_expect_item(local_def_id).kind
+                    for &impl_def_id in self.tcx.local_trait_impls(item.owner_id.def_id) {
+                        if let ItemKind::Impl(impl_ref) = self.tcx.hir_expect_item(impl_def_id).kind
                         {
                             // skip items
                             // mark dependent traits live
@@ -698,8 +696,8 @@ fn has_allow_dead_code_or_lang_attr(
 
     fn has_allow_expect_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         let hir_id = tcx.local_def_id_to_hir_id(def_id);
-        let lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;
-        matches!(lint_level, lint::Allow | lint::Expect(_))
+        let lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).level;
+        matches!(lint_level, lint::Allow | lint::Expect)
     }
 
     fn has_used_like_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
@@ -917,7 +915,7 @@ fn live_symbols_and_ignored_derived_traits(
 struct DeadItem {
     def_id: LocalDefId,
     name: Symbol,
-    level: lint::Level,
+    level: (lint::Level, Option<LintExpectationId>),
 }
 
 struct DeadVisitor<'tcx> {
@@ -961,9 +959,10 @@ impl<'tcx> DeadVisitor<'tcx> {
         ShouldWarnAboutField::Yes
     }
 
-    fn def_lint_level(&self, id: LocalDefId) -> lint::Level {
+    fn def_lint_level(&self, id: LocalDefId) -> (lint::Level, Option<LintExpectationId>) {
         let hir_id = self.tcx.local_def_id_to_hir_id(id);
-        self.tcx.lint_level_at_node(DEAD_CODE, hir_id).0
+        let level = self.tcx.lint_level_at_node(DEAD_CODE, hir_id);
+        (level.level, level.lint_id)
     }
 
     // # Panics
@@ -1131,7 +1130,8 @@ impl<'tcx> DeadVisitor<'tcx> {
         if dead_codes.is_empty() {
             return;
         }
-        dead_codes.sort_by_key(|v| v.level);
+        // FIXME: `dead_codes` should probably be morally equivalent to `IndexMap<(Level, LintExpectationId), (DefId, Symbol)>`
+        dead_codes.sort_by_key(|v| v.level.0);
         for group in dead_codes.chunk_by(|a, b| a.level == b.level) {
             self.lint_at_single_level(&group, participle, Some(def_id), report_on);
         }
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index e13d94c1031..17a729f422a 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -41,8 +41,8 @@ fn report_duplicate_item(
     original_def_id: DefId,
     item_def_id: DefId,
 ) {
-    let orig_span = tcx.hir().span_if_local(original_def_id);
-    let duplicate_span = tcx.hir().span_if_local(item_def_id);
+    let orig_span = tcx.hir_span_if_local(original_def_id);
+    let duplicate_span = tcx.hir_span_if_local(item_def_id);
     tcx.dcx().emit_err(DuplicateDiagnosticItemInCrate {
         duplicate_span,
         orig_span,
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index d2729876ebb..2a435c4b2e0 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -24,7 +24,7 @@ struct EntryContext<'tcx> {
 }
 
 fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
-    let any_exe = tcx.crate_types().iter().any(|ty| *ty == CrateType::Executable);
+    let any_exe = tcx.crate_types().contains(&CrateType::Executable);
     if !any_exe {
         // No need to find a main function.
         return None;
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 0ee17430aab..4e3e0324205 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1441,6 +1441,11 @@ pub(crate) struct OnlyHasEffectOn {
     pub target_name: String,
 }
 
+#[derive(LintDiagnostic)]
+#[diag(passes_inline_ignored_for_exported)]
+#[help]
+pub(crate) struct InlineIgnoredForExported {}
+
 #[derive(Diagnostic)]
 #[diag(passes_object_lifetime_err)]
 pub(crate) struct ObjectLifetimeErr {
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index 9d4b46cd306..664bd4ad0a2 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -268,22 +268,22 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
 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::ExternCrate(..) => Target::ExternCrate,
             ast::ItemKind::Use(_) => Target::Use,
             ast::ItemKind::Static(_) => Target::Static,
             ast::ItemKind::Const(_) => Target::Const,
             ast::ItemKind::Fn(_) | ast::ItemKind::Delegation(..) => Target::Fn,
-            ast::ItemKind::Mod(_, _) => Target::Mod,
+            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::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::TraitAlias(..) => Target::TraitAlias,
             ast::ItemKind::Impl(_) => Target::Impl,
-            ast::ItemKind::MacroDef(_) => Target::MacroDef,
+            ast::ItemKind::MacroDef(..) => Target::MacroDef,
             ast::ItemKind::MacCall(_) | ast::ItemKind::DelegationMac(_) => {
                 unreachable!("macros should have been expanded")
             }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 9e55914f8f2..d7baad69c78 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -726,7 +726,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
 
         annotator.annotate(
             CRATE_DEF_ID,
-            tcx.hir().span(CRATE_HIR_ID),
+            tcx.hir_span(CRATE_HIR_ID),
             None,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
@@ -980,7 +980,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                                     // Calculating message for lint involves calling `self.def_path_str`,
                                     // which will by default invoke the expensive `visible_parent_map` query.
                                     // Skip all that work if the lint is allowed anyway.
-                                    if self.tcx.lint_level_at_node(DEPRECATED, id).0
+                                    if self.tcx.lint_level_at_node(DEPRECATED, id).level
                                         == lint::Level::Allow
                                     {
                                         return;
@@ -1099,7 +1099,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     if is_staged_api {
         let effective_visibilities = &tcx.effective_visibilities(());
         let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities };
-        missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID));
+        missing.check_missing_stability(CRATE_DEF_ID, tcx.hir_span(CRATE_HIR_ID));
         tcx.hir_walk_toplevel_module(&mut missing);
         tcx.hir_visit_all_item_likes_in_crate(&mut missing);
     }
diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs
index 585cda1d24b..3da744dc8c0 100644
--- a/compiler/rustc_pattern_analysis/src/lints.rs
+++ b/compiler/rustc_pattern_analysis/src/lints.rs
@@ -1,3 +1,4 @@
+use rustc_middle::lint::LevelAndSource;
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::ErrorGuaranteed;
 use tracing::instrument;
@@ -64,7 +65,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>(
     scrut_ty: RevealedTy<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
     if !matches!(
-        rcx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, rcx.match_lint_level).0,
+        rcx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, rcx.match_lint_level).level,
         rustc_session::lint::Level::Allow
     ) {
         let witnesses = collect_nonexhaustive_missing_variants(rcx, pat_column)?;
@@ -88,13 +89,13 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>(
         // arm. This no longer makes sense so we warn users, to avoid silently breaking their
         // usage of the lint.
         for arm in arms {
-            let (lint_level, lint_level_source) =
+            let LevelAndSource { level, src, .. } =
                 rcx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.arm_data);
-            if !matches!(lint_level, rustc_session::lint::Level::Allow) {
+            if !matches!(level, rustc_session::lint::Level::Allow) {
                 let decorator = NonExhaustiveOmittedPatternLintOnArm {
-                    lint_span: lint_level_source.span(),
+                    lint_span: src.span(),
                     suggest_lint_on_match: rcx.whole_match_span.map(|span| span.shrink_to_lo()),
-                    lint_level: lint_level.as_str(),
+                    lint_level: level.as_str(),
                     lint_name: "non_exhaustive_omitted_patterns",
                 };
 
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index a25a80cd45f..31c4ee0fa0b 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -135,7 +135,10 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// Returns the hidden type corresponding to this key if the body under analysis is allowed to
     /// know it.
     fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
-        self.typeck_results.concrete_opaque_types.get(&key).map(|x| x.ty)
+        self.typeck_results
+            .concrete_opaque_types
+            .get(&key.def_id)
+            .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
     }
     // This can take a non-revealed `Ty` because it reveals opaques itself.
     pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 3238c7a0912..19ccc5587d6 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -870,6 +870,17 @@ macro_rules! define_queries {
                 }
             }
 
+            pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindStruct<'tcx> {
+                DepKindStruct {
+                    is_anon: true,
+                    is_eval_always: false,
+                    fingerprint_style: FingerprintStyle::Opaque,
+                    force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")),
+                    try_load_from_on_disk_cache: None,
+                    name: &"AnonZeroDeps",
+                }
+            }
+
             pub(crate) fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
                 DepKindStruct {
                     is_anon: true,
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 495f34733f7..9f34417973e 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -50,7 +50,7 @@ rustc_index::newtype_index! {
 rustc_data_structures::static_assert_size!(Option<DepNodeIndex>, 4);
 
 impl DepNodeIndex {
-    const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::ZERO;
+    const SINGLETON_ZERO_DEPS_ANON_NODE: DepNodeIndex = DepNodeIndex::ZERO;
     pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1);
 }
 
@@ -66,6 +66,7 @@ pub struct MarkFrame<'a> {
     parent: Option<&'a MarkFrame<'a>>,
 }
 
+#[derive(Debug)]
 pub(super) enum DepNodeColor {
     Red,
     Green(DepNodeIndex),
@@ -139,13 +140,13 @@ impl<D: Deps> DepGraph<D> {
 
         let colors = DepNodeColorMap::new(prev_graph_node_count);
 
-        // Instantiate a dependy-less node only once for anonymous queries.
+        // Instantiate a node with zero dependencies only once for anonymous queries.
         let _green_node_index = current.alloc_node(
-            DepNode { kind: D::DEP_KIND_NULL, hash: current.anon_id_seed.into() },
+            DepNode { kind: D::DEP_KIND_ANON_ZERO_DEPS, hash: current.anon_id_seed.into() },
             EdgesVec::new(),
             Fingerprint::ZERO,
         );
-        assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_DEPENDENCYLESS_ANON_NODE);
+        assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_ZERO_DEPS_ANON_NODE);
 
         // Instantiate a dependy-less red node only once for anonymous queries.
         let red_node_index = current.alloc_node(
@@ -406,7 +407,7 @@ impl<D: Deps> DepGraphData<D> {
                 // going to be (i.e. equal to the precomputed
                 // `SINGLETON_DEPENDENCYLESS_ANON_NODE`). As a consequence we can skip creating
                 // a `StableHasher` and sending the node through interning.
-                DepNodeIndex::SINGLETON_DEPENDENCYLESS_ANON_NODE
+                DepNodeIndex::SINGLETON_ZERO_DEPS_ANON_NODE
             }
             1 => {
                 // When there is only one dependency, don't bother creating a node.
@@ -909,7 +910,7 @@ impl<D: Deps> DepGraphData<D> {
                 self.try_mark_previous_green(qcx, parent_dep_node_index, dep_dep_node, frame);
 
             if node_index.is_some() {
-                debug!("managed to MARK dependency {dep_dep_node:?} as green",);
+                debug!("managed to MARK dependency {dep_dep_node:?} as green");
                 return Some(());
             }
         }
@@ -930,7 +931,7 @@ impl<D: Deps> DepGraphData<D> {
                 return Some(());
             }
             Some(DepNodeColor::Red) => {
-                debug!("dependency {dep_dep_node:?} was red after forcing",);
+                debug!("dependency {dep_dep_node:?} was red after forcing");
                 return None;
             }
             None => {}
@@ -950,7 +951,7 @@ impl<D: Deps> DepGraphData<D> {
         // invalid state will not be persisted to the
         // incremental compilation cache because of
         // compilation errors being present.
-        debug!("dependency {dep_dep_node:?} resulted in compilation error",);
+        debug!("dependency {dep_dep_node:?} resulted in compilation error");
         return None;
     }
 
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 4eeb6078d14..3a80835afad 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -111,6 +111,9 @@ pub trait Deps {
     /// We use this to create a side effect node.
     const DEP_KIND_SIDE_EFFECT: DepKind;
 
+    /// We use this to create the anon node with zero dependencies.
+    const DEP_KIND_ANON_ZERO_DEPS: DepKind;
+
     /// This is the highest value a `DepKind` can have. It's used during encoding to
     /// pack information into the unused bits.
     const DEP_KIND_MAX: u16;
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml
index f4771f1af2c..9ea9c58cfd1 100644
--- a/compiler/rustc_resolve/Cargo.toml
+++ b/compiler/rustc_resolve/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 bitflags = "2.4.1"
+itertools = "0.12"
 pulldown-cmark = { version = "0.11", features = ["html"], default-features = false }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 97fbf7e378a..4368f7882ff 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -10,8 +10,8 @@ use std::sync::Arc;
 
 use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
 use rustc_ast::{
-    self as ast, AssocItem, AssocItemKind, Block, ForeignItem, ForeignItemKind, Impl, Item,
-    ItemKind, MetaItemKind, NodeId, StmtKind,
+    self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
+    ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StaticItem, StmtKind, TyAlias,
 };
 use rustc_attr_parsing as attr;
 use rustc_expand::base::ResolverExpand;
@@ -735,7 +735,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         let parent_scope = &self.parent_scope;
         let parent = parent_scope.module;
         let expansion = parent_scope.expansion;
-        let ident = item.ident;
         let sp = item.span;
         let vis = self.resolve_visibility(&item.vis);
         let feed = self.r.feed(item.id);
@@ -762,17 +761,18 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 );
             }
 
-            ItemKind::ExternCrate(orig_name) => {
+            ItemKind::ExternCrate(orig_name, ident) => {
                 self.build_reduced_graph_for_extern_crate(
                     orig_name,
                     item,
+                    ident,
                     local_def_id,
                     vis,
                     parent,
                 );
             }
 
-            ItemKind::Mod(.., ref mod_kind) => {
+            ItemKind::Mod(_, ident, ref mod_kind) => {
                 let module = self.r.new_module(
                     Some(parent),
                     ModuleKind::Def(def_kind, def_id, Some(ident.name)),
@@ -792,10 +792,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             }
 
             // These items live in the value namespace.
-            ItemKind::Const(..) | ItemKind::Delegation(..) | ItemKind::Static(..) => {
+            ItemKind::Const(box ConstItem { ident, .. })
+            | ItemKind::Delegation(box Delegation { ident, .. })
+            | ItemKind::Static(box StaticItem { ident, .. }) => {
                 self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
             }
-            ItemKind::Fn(..) => {
+            ItemKind::Fn(box Fn { ident, .. }) => {
                 self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
 
                 // Functions introducing procedural macros reserve a slot
@@ -804,11 +806,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             }
 
             // These items live in the type namespace.
-            ItemKind::TyAlias(..) | ItemKind::TraitAlias(..) => {
+            ItemKind::TyAlias(box TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => {
                 self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
-            ItemKind::Enum(_, _) | ItemKind::Trait(..) => {
+            ItemKind::Enum(ident, _, _) | ItemKind::Trait(box ast::Trait { ident, .. }) => {
                 let module = self.r.new_module(
                     Some(parent),
                     ModuleKind::Def(def_kind, def_id, Some(ident.name)),
@@ -821,7 +823,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             }
 
             // These items live in both the type and value namespaces.
-            ItemKind::Struct(ref vdata, _) => {
+            ItemKind::Struct(ident, ref vdata, _) => {
                 self.build_reduced_graph_for_struct_variant(
                     vdata.fields(),
                     ident,
@@ -872,7 +874,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 }
             }
 
-            ItemKind::Union(ref vdata, _) => {
+            ItemKind::Union(ident, ref vdata, _) => {
                 self.build_reduced_graph_for_struct_variant(
                     vdata.fields(),
                     ident,
@@ -899,11 +901,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         &mut self,
         orig_name: Option<Symbol>,
         item: &Item,
+        ident: Ident,
         local_def_id: LocalDefId,
         vis: ty::Visibility,
         parent: Module<'ra>,
     ) {
-        let ident = item.ident;
         let sp = item.span;
         let parent_scope = self.parent_scope;
         let expansion = parent_scope.expansion;
@@ -987,7 +989,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
     }
 
     /// Constructs the reduced graph for one foreign item.
-    fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) {
+    fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, ident: Ident) {
         let feed = self.r.feed(item.id);
         let local_def_id = feed.key();
         let def_id = local_def_id.to_def_id();
@@ -1000,7 +1002,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         let parent = self.parent_scope.module;
         let expansion = self.parent_scope.expansion;
         let vis = self.resolve_visibility(&item.vis);
-        self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion));
+        self.r.define(parent, ident, ns, (self.res(def_id), vis, item.span, expansion));
         self.r.feed_visibility(feed, vis);
     }
 
@@ -1043,7 +1045,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                         span: item.span,
                     });
                 }
-                if let ItemKind::ExternCrate(Some(orig_name)) = item.kind
+                if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
                     && orig_name == kw::SelfLower
                 {
                     self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
@@ -1177,11 +1179,15 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
     }
 
-    fn proc_macro_stub(&self, item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
+    fn proc_macro_stub(
+        &self,
+        item: &ast::Item,
+        fn_ident: Ident,
+    ) -> Option<(MacroKind, Ident, Span)> {
         if ast::attr::contains_name(&item.attrs, sym::proc_macro) {
-            return Some((MacroKind::Bang, item.ident, item.span));
+            return Some((MacroKind::Bang, fn_ident, item.span));
         } else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
-            return Some((MacroKind::Attr, item.ident, item.span));
+            return Some((MacroKind::Attr, fn_ident, item.span));
         } else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
             && let Some(meta_item_inner) =
                 attr.meta_item_list().and_then(|list| list.get(0).cloned())
@@ -1214,17 +1220,21 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         let feed = self.r.feed(item.id);
         let def_id = feed.key();
         let (res, ident, span, macro_rules) = match &item.kind {
-            ItemKind::MacroDef(def) => (self.res(def_id), item.ident, item.span, def.macro_rules),
-            ItemKind::Fn(..) => match self.proc_macro_stub(item) {
-                Some((macro_kind, ident, span)) => {
-                    let res = Res::Def(DefKind::Macro(macro_kind), def_id.to_def_id());
-                    let macro_data = MacroData::new(self.r.dummy_ext(macro_kind));
-                    self.r.macro_map.insert(def_id.to_def_id(), macro_data);
-                    self.r.proc_macro_stubs.insert(def_id);
-                    (res, ident, span, false)
+            ItemKind::MacroDef(ident, def) => {
+                (self.res(def_id), *ident, item.span, def.macro_rules)
+            }
+            ItemKind::Fn(box ast::Fn { ident: fn_ident, .. }) => {
+                match self.proc_macro_stub(item, *fn_ident) {
+                    Some((macro_kind, ident, span)) => {
+                        let res = Res::Def(DefKind::Macro(macro_kind), def_id.to_def_id());
+                        let macro_data = MacroData::new(self.r.dummy_ext(macro_kind));
+                        self.r.macro_map.insert(def_id.to_def_id(), macro_data);
+                        self.r.proc_macro_stubs.insert(def_id);
+                        (res, ident, span, false)
+                    }
+                    None => return parent_scope.macro_rules,
                 }
-                None => return parent_scope.macro_rules,
-            },
+            }
             _ => unreachable!(),
         };
 
@@ -1327,8 +1337,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                         // Visit attributes after items for backward compatibility.
                         // This way they can use `macro_rules` defined later.
                         self.visit_vis(&item.vis);
-                        self.visit_ident(&item.ident);
-                        item.kind.walk(item.span, item.id, &item.ident, &item.vis, (), self);
+                        item.kind.walk(item.span, item.id, &item.vis, (), self);
                         visit::walk_list!(self, visit_attribute, &item.attrs);
                     }
                     _ => visit::walk_item(self, item),
@@ -1353,12 +1362,17 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
     }
 
     fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
-        if let ForeignItemKind::MacCall(_) = foreign_item.kind {
-            self.visit_invoc_in_module(foreign_item.id);
-            return;
-        }
+        let ident = match foreign_item.kind {
+            ForeignItemKind::Static(box StaticItem { ident, .. })
+            | ForeignItemKind::Fn(box Fn { ident, .. })
+            | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => ident,
+            ForeignItemKind::MacCall(_) => {
+                self.visit_invoc_in_module(foreign_item.id);
+                return;
+            }
+        };
 
-        self.build_reduced_graph_for_foreign_item(foreign_item);
+        self.build_reduced_graph_for_foreign_item(foreign_item, ident);
         visit::walk_item(self, foreign_item);
     }
 
@@ -1372,26 +1386,35 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
     }
 
     fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
-        if let AssocItemKind::MacCall(_) = item.kind {
-            match ctxt {
-                AssocCtxt::Trait => {
-                    self.visit_invoc_in_module(item.id);
-                }
-                AssocCtxt::Impl { .. } => {
-                    let invoc_id = item.id.placeholder_to_expn_id();
-                    if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
-                        self.r
-                            .impl_unexpanded_invocations
-                            .entry(self.r.invocation_parent(invoc_id))
-                            .or_default()
-                            .insert(invoc_id);
+        let (ident, ns) = match item.kind {
+            AssocItemKind::Const(box ConstItem { ident, .. })
+            | AssocItemKind::Fn(box Fn { ident, .. })
+            | AssocItemKind::Delegation(box Delegation { ident, .. }) => (ident, ValueNS),
+
+            AssocItemKind::Type(box TyAlias { ident, .. }) => (ident, TypeNS),
+
+            AssocItemKind::MacCall(_) => {
+                match ctxt {
+                    AssocCtxt::Trait => {
+                        self.visit_invoc_in_module(item.id);
+                    }
+                    AssocCtxt::Impl { .. } => {
+                        let invoc_id = item.id.placeholder_to_expn_id();
+                        if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
+                            self.r
+                                .impl_unexpanded_invocations
+                                .entry(self.r.invocation_parent(invoc_id))
+                                .or_default()
+                                .insert(invoc_id);
+                        }
+                        self.visit_invoc(item.id);
                     }
-                    self.visit_invoc(item.id);
                 }
+                return;
             }
-            return;
-        }
 
+            AssocItemKind::DelegationMac(..) => bug!(),
+        };
         let vis = self.resolve_visibility(&item.vis);
         let feed = self.r.feed(item.id);
         let local_def_id = feed.key();
@@ -1406,20 +1429,13 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             self.r.feed_visibility(feed, vis);
         }
 
-        let ns = match item.kind {
-            AssocItemKind::Const(..) | AssocItemKind::Delegation(..) | AssocItemKind::Fn(..) => {
-                ValueNS
-            }
-            AssocItemKind::Type(..) => TypeNS,
-            AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => bug!(), // handled above
-        };
         if ctxt == AssocCtxt::Trait {
             let parent = self.parent_scope.module;
             let expansion = self.parent_scope.expansion;
-            self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion));
+            self.r.define(parent, ident, ns, (self.res(def_id), vis, item.span, expansion));
         } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) {
             let impl_def_id = self.r.tcx.local_parent(local_def_id);
-            let key = BindingKey::new(item.ident.normalize_to_macros_2_0(), ns);
+            let key = BindingKey::new(ident.normalize_to_macros_2_0(), ns);
             self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
         }
 
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index 51ff4aa834b..e97233e97ce 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -219,14 +219,14 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
             // because this means that they were generated in some fashion by the
             // compiler and we don't need to consider them.
             ast::ItemKind::Use(..) if item.span.is_dummy() => return,
-            ast::ItemKind::ExternCrate(orig_name) => {
+            ast::ItemKind::ExternCrate(orig_name, ident) => {
                 self.extern_crate_items.push(ExternCrateToLint {
                     id: item.id,
                     span: item.span,
                     vis_span: item.vis.span,
                     span_with_attributes: item.span_with_attributes(),
                     has_attrs: !item.attrs.is_empty(),
-                    ident: item.ident,
+                    ident,
                     renames: orig_name.is_some(),
                 });
             }
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 6f48a75d617..13dfb59f27f 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -122,7 +122,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
             },
             ItemKind::Const(..) => DefKind::Const,
             ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn,
-            ItemKind::MacroDef(def) => {
+            ItemKind::MacroDef(ident, def) => {
                 let edition = i.span.edition();
 
                 // FIXME(jdonszelmann) make one of these in the resolver?
@@ -141,7 +141,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
                 );
 
                 let macro_data =
-                    self.resolver.compile_macro(def, i.ident, &attrs, i.span, i.id, edition);
+                    self.resolver.compile_macro(def, *ident, &attrs, i.span, i.id, edition);
                 let macro_kind = macro_data.ext.macro_kind();
                 opt_macro_data = Some(macro_data);
                 DefKind::Macro(macro_kind)
@@ -152,7 +152,8 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
                 return self.visit_macro_invoc(i.id);
             }
         };
-        let def_id = self.create_def(i.id, Some(i.ident.name), def_kind, i.span);
+        let def_id =
+            self.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span);
 
         if let Some(macro_data) = opt_macro_data {
             self.resolver.macro_map.insert(def_id.to_def_id(), macro_data);
@@ -161,7 +162,8 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
         self.with_parent(def_id, |this| {
             this.with_impl_trait(ImplTraitContext::Existential, |this| {
                 match i.kind {
-                    ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
+                    ItemKind::Struct(_, ref struct_def, _)
+                    | ItemKind::Union(_, ref struct_def, _) => {
                         // If this is a unit or tuple-like struct, register the constructor.
                         if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) {
                             this.create_def(
@@ -183,10 +185,12 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
         match fn_kind {
             FnKind::Fn(
                 _ctxt,
-                _ident,
                 _vis,
-                Fn { sig: FnSig { header, decl, span: _ }, generics, contract, body, .. },
+                Fn {
+                    sig: FnSig { header, decl, span: _ }, ident, generics, contract, body, ..
+                },
             ) if let Some(coroutine_kind) = header.coroutine_kind => {
+                self.visit_ident(ident);
                 self.visit_fn_header(header);
                 self.visit_generics(generics);
                 if let Some(contract) = contract {
@@ -234,8 +238,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
     }
 
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
-        let def_kind = match fi.kind {
+        let (ident, def_kind) = match fi.kind {
             ForeignItemKind::Static(box StaticItem {
+                ident,
                 ty: _,
                 mutability,
                 expr: _,
@@ -247,14 +252,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
                     ast::Safety::Safe(_) => hir::Safety::Safe,
                 };
 
-                DefKind::Static { safety, mutability, nested: false }
+                (ident, DefKind::Static { safety, mutability, nested: false })
             }
-            ForeignItemKind::Fn(_) => DefKind::Fn,
-            ForeignItemKind::TyAlias(_) => DefKind::ForeignTy,
+            ForeignItemKind::Fn(box Fn { ident, .. }) => (ident, DefKind::Fn),
+            ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => (ident, DefKind::ForeignTy),
             ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id),
         };
 
-        let def = self.create_def(fi.id, Some(fi.ident.name), def_kind, fi.span);
+        let def = self.create_def(fi.id, Some(ident.name), def_kind, fi.span);
 
         self.with_parent(def, |this| visit::walk_item(this, fi));
     }
@@ -318,16 +323,17 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
     }
 
     fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) {
-        let def_kind = match &i.kind {
-            AssocItemKind::Fn(..) | AssocItemKind::Delegation(..) => DefKind::AssocFn,
-            AssocItemKind::Const(..) => DefKind::AssocConst,
-            AssocItemKind::Type(..) => DefKind::AssocTy,
+        let (ident, def_kind) = match &i.kind {
+            AssocItemKind::Fn(box Fn { ident, .. })
+            | AssocItemKind::Delegation(box Delegation { ident, .. }) => (*ident, DefKind::AssocFn),
+            AssocItemKind::Const(box ConstItem { ident, .. }) => (*ident, DefKind::AssocConst),
+            AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, DefKind::AssocTy),
             AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
                 return self.visit_macro_invoc(i.id);
             }
         };
 
-        let def = self.create_def(i.id, Some(i.ident.name), def_kind, i.span);
+        let def = self.create_def(i.id, Some(ident.name), def_kind, i.span);
         self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt));
     }
 
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 63ea8c4ced1..6dc854758da 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1091,7 +1091,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     ));
                 }
                 Scope::BuiltinAttrs => {
-                    let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(kw::Empty));
+                    let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(sym::dummy));
                     if filter_fn(res) {
                         suggestions.extend(
                             BUILTIN_ATTRIBUTES
@@ -1325,11 +1325,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             })
         }
 
-        // If only some candidates are accessible, take just them
-        if !candidates.iter().all(|v: &ImportSuggestion| !v.accessible) {
-            candidates.retain(|x| x.accessible)
-        }
-
         candidates
     }
 
@@ -1793,7 +1788,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 &import_suggestions,
                 Instead::Yes,
                 FoundUse::Yes,
-                DiagMode::Import { append: single_nested },
+                DiagMode::Import { append: single_nested, unresolved_import: false },
                 vec![],
                 "",
             );
@@ -2750,6 +2745,8 @@ pub(crate) enum DiagMode {
     Pattern,
     /// The binding is part of a use statement
     Import {
+        /// `true` means diagnostics is for unresolved import
+        unresolved_import: bool,
         /// `true` mean add the tips afterward for case `use a::{b,c}`,
         /// rather than replacing within.
         append: bool,
@@ -2800,6 +2797,7 @@ fn show_candidates(
         return false;
     }
 
+    let mut showed = false;
     let mut accessible_path_strings: Vec<PathString<'_>> = Vec::new();
     let mut inaccessible_path_strings: Vec<PathString<'_>> = Vec::new();
 
@@ -2958,8 +2956,11 @@ fn show_candidates(
             append_candidates(&mut msg, accessible_path_strings);
             err.help(msg);
         }
-        true
-    } else if !(inaccessible_path_strings.is_empty() || matches!(mode, DiagMode::Import { .. })) {
+        showed = true;
+    }
+    if !inaccessible_path_strings.is_empty()
+        && (!matches!(mode, DiagMode::Import { unresolved_import: false, .. }))
+    {
         let prefix =
             if let DiagMode::Pattern = mode { "you might have meant to match on " } else { "" };
         if let [(name, descr, source_span, note, _)] = &inaccessible_path_strings[..] {
@@ -3022,10 +3023,9 @@ fn show_candidates(
 
             err.span_note(multi_span, msg);
         }
-        true
-    } else {
-        false
+        showed = true;
     }
+    showed
 }
 
 #[derive(Debug)]
@@ -3063,7 +3063,7 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
 
     fn visit_item(&mut self, item: &'tcx ast::Item) {
         if self.target_module == item.id {
-            if let ItemKind::Mod(_, ModKind::Loaded(items, _inline, mod_spans, _)) = &item.kind {
+            if let ItemKind::Mod(_, _, ModKind::Loaded(items, _inline, mod_spans, _)) = &item.kind {
                 let inject = mod_spans.inject_use_span;
                 if is_span_suitable_for_use_injection(inject) {
                     self.first_legal_span = Some(inject);
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index 6ef4aa40725..a5ca4565d7b 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -252,7 +252,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx>
                 self.current_private_vis = prev_private_vis;
             }
 
-            ast::ItemKind::Enum(EnumDef { ref variants }, _) => {
+            ast::ItemKind::Enum(_, EnumDef { ref variants }, _) => {
                 self.set_bindings_effective_visibilities(def_id);
                 for variant in variants {
                     let variant_def_id = self.r.local_def_id(variant.id);
@@ -262,7 +262,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx>
                 }
             }
 
-            ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
+            ast::ItemKind::Struct(_, ref def, _) | ast::ItemKind::Union(_, ref def, _) => {
                 for field in def.fields() {
                     self.update_field(self.r.local_def_id(field.id), def_id);
                 }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 454460e10dc..0b3633a452c 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -734,7 +734,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         &mut diag,
                         Some(err.span),
                         candidates,
-                        DiagMode::Import { append: false },
+                        DiagMode::Import { append: false, unresolved_import: true },
                         (source != target)
                             .then(|| format!(" as {target}"))
                             .as_deref()
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 533e216ddb2..20e19caf909 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1025,9 +1025,10 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
         match fn_kind {
             // Bail if the function is foreign, and thus cannot validly have
             // a body, or if there's no body for some other reason.
-            FnKind::Fn(FnCtxt::Foreign, _, _, Fn { sig, generics, .. })
-            | FnKind::Fn(_, _, _, Fn { sig, generics, body: None, .. }) => {
+            FnKind::Fn(FnCtxt::Foreign, _, Fn { sig, ident, generics, .. })
+            | FnKind::Fn(_, _, Fn { sig, ident, generics, body: None, .. }) => {
                 self.visit_fn_header(&sig.header);
+                self.visit_ident(ident);
                 self.visit_generics(generics);
                 self.with_lifetime_rib(
                     LifetimeRibKind::AnonymousCreateParameter {
@@ -1058,7 +1059,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
             // Create a label rib for the function.
             this.with_label_rib(RibKind::FnOrCoroutine, |this| {
                 match fn_kind {
-                    FnKind::Fn(_, _, _, Fn { sig, generics, contract, body, .. }) => {
+                    FnKind::Fn(_, _, Fn { sig, generics, contract, body, .. }) => {
                         this.visit_generics(generics);
 
                         let declaration = &sig.decl;
@@ -1833,7 +1834,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 }
                 LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {
                     let mut lifetimes_in_scope = vec![];
-                    for rib in &self.lifetime_ribs[..i] {
+                    for rib in self.lifetime_ribs[..i].iter().rev() {
                         lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));
                         // Consider any anonymous lifetimes, too
                         if let LifetimeRibKind::AnonymousCreateParameter { binder, .. } = rib.kind
@@ -1841,6 +1842,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         {
                             lifetimes_in_scope.extend(extra.iter().map(|(ident, _, _)| ident.span));
                         }
+                        if let LifetimeRibKind::Item = rib.kind {
+                            break;
+                        }
                     }
                     if lifetimes_in_scope.is_empty() {
                         self.record_lifetime_res(
@@ -2629,8 +2633,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
         }
 
-        let name = item.ident.name;
-        debug!("(resolving item) resolving {} ({:?})", name, item.kind);
+        debug!("(resolving item) resolving {:?} ({:?})", item.kind.ident(), item.kind);
 
         let def_kind = self.r.local_def_kind(item.id);
         match item.kind {
@@ -2661,9 +2664,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 self.resolve_define_opaques(define_opaque);
             }
 
-            ItemKind::Enum(_, ref generics)
-            | ItemKind::Struct(_, ref generics)
-            | ItemKind::Union(_, ref generics) => {
+            ItemKind::Enum(_, _, ref generics)
+            | ItemKind::Struct(_, _, ref generics)
+            | ItemKind::Union(_, _, ref generics) => {
                 self.resolve_adt(item, generics);
             }
 
@@ -2707,7 +2710,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 );
             }
 
-            ItemKind::TraitAlias(ref generics, ref bounds) => {
+            ItemKind::TraitAlias(_, ref generics, ref bounds) => {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
@@ -2745,7 +2748,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             }
 
             ItemKind::Static(box ast::StaticItem {
-                ref ty, ref expr, ref define_opaque, ..
+                ident,
+                ref ty,
+                ref expr,
+                ref define_opaque,
+                ..
             }) => {
                 self.with_static_rib(def_kind, |this| {
                     this.with_lifetime_rib(
@@ -2759,13 +2766,14 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     if let Some(expr) = expr {
                         // We already forbid generic params because of the above item rib,
                         // so it doesn't matter whether this is a trivial constant.
-                        this.resolve_const_body(expr, Some((item.ident, ConstantItemKind::Static)));
+                        this.resolve_const_body(expr, Some((ident, ConstantItemKind::Static)));
                     }
                 });
                 self.resolve_define_opaques(define_opaque);
             }
 
             ItemKind::Const(box ast::ConstItem {
+                ident,
                 ref generics,
                 ref ty,
                 ref expr,
@@ -2798,10 +2806,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         );
 
                         if let Some(expr) = expr {
-                            this.resolve_const_body(
-                                expr,
-                                Some((item.ident, ConstantItemKind::Const)),
-                            );
+                            this.resolve_const_body(expr, Some((ident, ConstantItemKind::Const)));
                         }
                     },
                 );
@@ -2818,7 +2823,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 self.future_proof_import(use_tree);
             }
 
-            ItemKind::MacroDef(ref macro_def) => {
+            ItemKind::MacroDef(_, ref macro_def) => {
                 // Maintain macro_rules scopes in the same way as during early resolution
                 // for diagnostics and doc links.
                 if macro_def.macro_rules {
@@ -3316,7 +3321,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
         match &item.kind {
             AssocItemKind::Const(box ast::ConstItem {
-                generics, ty, expr, define_opaque, ..
+                ident,
+                generics,
+                ty,
+                expr,
+                define_opaque,
+                ..
             }) => {
                 debug!("resolve_implementation AssocItemKind::Const");
                 self.with_generic_param_rib(
@@ -3347,7 +3357,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                                         // exists in trait
                                         this.check_trait_item(
                                             item.id,
-                                            item.ident,
+                                            *ident,
                                             &item.kind,
                                             ValueNS,
                                             item.span,
@@ -3373,7 +3383,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 );
                 self.resolve_define_opaques(define_opaque);
             }
-            AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
+            AssocItemKind::Fn(box Fn { ident, generics, define_opaque, .. }) => {
                 debug!("resolve_implementation AssocItemKind::Fn");
                 // We also need a new scope for the impl item type parameters.
                 self.with_generic_param_rib(
@@ -3389,7 +3399,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         // exists in trait
                         this.check_trait_item(
                             item.id,
-                            item.ident,
+                            *ident,
                             &item.kind,
                             ValueNS,
                             item.span,
@@ -3403,7 +3413,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
 
                 self.resolve_define_opaques(define_opaque);
             }
-            AssocItemKind::Type(box TyAlias { generics, .. }) => {
+            AssocItemKind::Type(box TyAlias { ident, generics, .. }) => {
                 self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
                 debug!("resolve_implementation AssocItemKind::Type");
                 // We also need a new scope for the impl item type parameters.
@@ -3421,7 +3431,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                             // exists in trait
                             this.check_trait_item(
                                 item.id,
-                                item.ident,
+                                *ident,
                                 &item.kind,
                                 TypeNS,
                                 item.span,
@@ -3448,7 +3458,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     |this| {
                         this.check_trait_item(
                             item.id,
-                            item.ident,
+                            delegation.ident,
                             &item.kind,
                             ValueNS,
                             item.span,
@@ -4334,7 +4344,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 if let Some(items) = self.diag_metadata.current_trait_assoc_items
                     && let [Segment { ident, .. }] = path
                     && items.iter().any(|item| {
-                        item.ident == *ident && matches!(item.kind, AssocItemKind::Type(_))
+                        if let AssocItemKind::Type(alias) = &item.kind
+                            && alias.ident == *ident
+                        {
+                            true
+                        } else {
+                            false
+                        }
                     })
                 {
                     let mut diag = self.r.tcx.dcx().struct_allow("");
@@ -5156,12 +5172,12 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
             ItemKind::TyAlias(box TyAlias { generics, .. })
             | ItemKind::Const(box ConstItem { generics, .. })
             | ItemKind::Fn(box Fn { generics, .. })
-            | ItemKind::Enum(_, generics)
-            | ItemKind::Struct(_, generics)
-            | ItemKind::Union(_, generics)
+            | ItemKind::Enum(_, _, generics)
+            | ItemKind::Struct(_, _, generics)
+            | ItemKind::Union(_, _, generics)
             | ItemKind::Impl(box Impl { generics, .. })
             | ItemKind::Trait(box Trait { generics, .. })
-            | ItemKind::TraitAlias(generics, _) => {
+            | ItemKind::TraitAlias(_, generics, _) => {
                 if let ItemKind::Fn(box Fn { sig, .. }) = &item.kind {
                     self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs);
                 }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index e40f84e7e59..b62bc6c45e0 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -224,12 +224,13 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 let suggestion = if self.current_trait_ref.is_none()
                     && let Some((fn_kind, _)) = self.diag_metadata.current_function
                     && let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt()
-                    && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = fn_kind
+                    && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = fn_kind
                     && let Some(items) = self.diag_metadata.current_impl_items
                     && let Some(item) = items.iter().find(|i| {
-                        i.ident.name == item_str.name
+                        i.kind.ident().is_some_and(|ident| {
                             // Don't suggest if the item is in Fn signature arguments (#112590).
-                            && !sig.span.contains(item_span)
+                            ident.name == item_str.name && !sig.span.contains(item_span)
+                        })
                     }) {
                     let sp = item_span.shrink_to_lo();
 
@@ -268,14 +269,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                             // you can't call `fn foo(&self)` from `fn bar()` (#115992).
                             // We also want to mention that the method exists.
                             span_label = Some((
-                                item.ident.span,
+                                fn_.ident.span,
                                 "a method by that name is available on `Self` here",
                             ));
                             None
                         }
                         AssocItemKind::Fn(fn_) if !fn_.sig.decl.has_self() && !is_call => {
                             span_label = Some((
-                                item.ident.span,
+                                fn_.ident.span,
                                 "an associated function by that name is available on `Self` here",
                             ));
                             None
@@ -604,7 +605,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 Applicability::MaybeIncorrect,
             );
             if !self.self_value_is_available(path[0].ident.span) {
-                if let Some((FnKind::Fn(_, _, _, ast::Fn { sig, .. }), fn_span)) =
+                if let Some((FnKind::Fn(_, _, ast::Fn { sig, .. }), fn_span)) =
                     &self.diag_metadata.current_function
                 {
                     let (span, sugg) = if let Some(param) = sig.decl.inputs.get(0) {
@@ -1064,15 +1065,11 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         }
         err.code(E0411);
         err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
-        if let Some(item_kind) = self.diag_metadata.current_item {
-            if !item_kind.ident.span.is_dummy() {
+        if let Some(item) = self.diag_metadata.current_item {
+            if let Some(ident) = item.kind.ident() {
                 err.span_label(
-                    item_kind.ident.span,
-                    format!(
-                        "`Self` not allowed in {} {}",
-                        item_kind.kind.article(),
-                        item_kind.kind.descr()
-                    ),
+                    ident.span,
+                    format!("`Self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
                 );
             }
         }
@@ -1150,17 +1147,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     );
                 }
             }
-        } else if let Some(item_kind) = self.diag_metadata.current_item {
-            if matches!(item_kind.kind, ItemKind::Delegation(..)) {
-                err.span_label(item_kind.span, format!("delegation supports {self_from_macro}"));
+        } else if let Some(item) = self.diag_metadata.current_item {
+            if matches!(item.kind, ItemKind::Delegation(..)) {
+                err.span_label(item.span, format!("delegation supports {self_from_macro}"));
             } else {
+                let span = if let Some(ident) = item.kind.ident() { ident.span } else { item.span };
                 err.span_label(
-                    item_kind.ident.span,
-                    format!(
-                        "`self` not allowed in {} {}",
-                        item_kind.kind.article(),
-                        item_kind.kind.descr()
-                    ),
+                    span,
+                    format!("`self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
                 );
             }
         }
@@ -2196,7 +2190,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
 
         if let Some(items) = self.diag_metadata.current_trait_assoc_items {
             for assoc_item in items {
-                if assoc_item.ident == ident {
+                if let Some(assoc_ident) = assoc_item.kind.ident()
+                    && assoc_ident == ident
+                {
                     return Some(match &assoc_item.kind {
                         ast::AssocItemKind::Const(..) => AssocSuggestion::AssocConst,
                         ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) if sig.decl.has_self() => {
@@ -2735,7 +2731,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             return None;
         }
         match (self.diag_metadata.current_item, single_uppercase_char, self.diag_metadata.currently_processing_generic_args) {
-            (Some(Item { kind: ItemKind::Fn(..), ident, .. }), _, _) if ident.name == sym::main => {
+            (Some(Item { kind: ItemKind::Fn(fn_), .. }), _, _) if fn_.ident.name == sym::main => {
                 // Ignore `fn main()` as we don't want to suggest `fn main<T>()`
             }
             (
@@ -3400,7 +3396,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     {
                         let pre = if lt.kind == MissingLifetimeKind::Ampersand
                             && let Some((kind, _span)) = self.diag_metadata.current_function
-                            && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind
+                            && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
                             && !sig.decl.inputs.is_empty()
                             && let sugg = sig
                                 .decl
@@ -3441,7 +3437,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                         } else if (lt.kind == MissingLifetimeKind::Ampersand
                             || lt.kind == MissingLifetimeKind::Underscore)
                             && let Some((kind, _span)) = self.diag_metadata.current_function
-                            && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind
+                            && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
                             && let ast::FnRetTy::Ty(ret_ty) = &sig.decl.output
                             && !sig.decl.inputs.is_empty()
                             && let arg_refs = sig
@@ -3501,7 +3497,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                         let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand;
                         let mut sugg = vec![(lt.span, String::new())];
                         if let Some((kind, _span)) = self.diag_metadata.current_function
-                            && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind
+                            && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
                             && let ast::FnRetTy::Ty(ty) = &sig.decl.output
                         {
                             let mut lt_finder =
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 612e091770f..3ac66840d87 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -88,6 +88,8 @@ mod late;
 mod macros;
 pub mod rustdoc;
 
+pub use macros::registered_tools_ast;
+
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index d0ffef798cf..9d6ae0aa9d1 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -10,7 +10,7 @@ use rustc_ast::{self as ast, Crate, NodeId, attr};
 use rustc_ast_pretty::pprust;
 use rustc_attr_parsing::{AttributeKind, StabilityLevel, find_attr};
 use rustc_data_structures::intern::Interned;
-use rustc_errors::{Applicability, StashKey};
+use rustc_errors::{Applicability, DiagCtxtHandle, StashKey};
 use rustc_expand::base::{
     DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind,
 };
@@ -124,14 +124,21 @@ fn fast_print_path(path: &ast::Path) -> Symbol {
 }
 
 pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
-    let mut registered_tools = RegisteredTools::default();
     let (_, pre_configured_attrs) = &*tcx.crate_for_resolver(()).borrow();
+    registered_tools_ast(tcx.dcx(), pre_configured_attrs)
+}
+
+pub fn registered_tools_ast(
+    dcx: DiagCtxtHandle<'_>,
+    pre_configured_attrs: &[ast::Attribute],
+) -> RegisteredTools {
+    let mut registered_tools = RegisteredTools::default();
     for attr in attr::filter_by_name(pre_configured_attrs, sym::register_tool) {
         for meta_item_inner in attr.meta_item_list().unwrap_or_default() {
             match meta_item_inner.ident() {
                 Some(ident) => {
                     if let Some(old_ident) = registered_tools.replace(ident) {
-                        tcx.dcx().emit_err(errors::ToolWasAlreadyRegistered {
+                        dcx.emit_err(errors::ToolWasAlreadyRegistered {
                             span: ident.span,
                             tool: ident,
                             old_ident_span: old_ident.span,
@@ -139,7 +146,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
                     }
                 }
                 None => {
-                    tcx.dcx().emit_err(errors::ToolOnlyAcceptsIdentifiers {
+                    dcx.emit_err(errors::ToolOnlyAcceptsIdentifiers {
                         span: meta_item_inner.span(),
                         tool: sym::register_tool,
                     });
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 52aaab77ebe..a32fe699016 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -1,13 +1,15 @@
 use std::mem;
 use std::ops::Range;
 
+use itertools::Itertools;
 use pulldown_cmark::{
     BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, Options, Parser, Tag,
 };
 use rustc_ast as ast;
 use rustc_ast::attr::AttributeExt;
 use rustc_ast::util::comments::beautify_doc_string;
-use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::unord::UnordSet;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::DefId;
 use rustc_span::{DUMMY_SP, InnerSpan, Span, Symbol, kw, sym};
@@ -422,7 +424,7 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
     );
     let mut links = Vec::new();
 
-    let mut refids = FxHashSet::default();
+    let mut refids = UnordSet::default();
 
     while let Some(event) = event_iter.next() {
         match event {
@@ -454,7 +456,7 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
         }
     }
 
-    for (label, refdef) in event_iter.reference_definitions().iter() {
+    for (label, refdef) in event_iter.reference_definitions().iter().sorted_by_key(|x| x.0) {
         if !refids.contains(label) {
             links.push(preprocess_link(&refdef.dest));
         }
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index e088417d72e..d56ca9c2453 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -716,6 +716,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
             hir::definitions::DefPathData::Ctor => "c",
             hir::definitions::DefPathData::AnonConst => "k",
             hir::definitions::DefPathData::OpaqueTy => "i",
+            hir::definitions::DefPathData::SyntheticCoroutineBody => "s",
             hir::definitions::DefPathData::CrateRoot
             | hir::definitions::DefPathData::Use
             | hir::definitions::DefPathData::GlobalAsm
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 74b8087e077..528c52eace7 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -1,3 +1,9 @@
+session_apple_deployment_target_invalid =
+    failed to parse deployment target specified in {$env_var}: {$error}
+
+session_apple_deployment_target_too_low =
+    deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
+
 session_binary_float_literal_not_supported = binary float literal is not supported
 session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only supported on aarch64
 
@@ -94,6 +100,8 @@ session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Cli
 
 session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
 
+session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`
+
 session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort`
 
 session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index ed336cc5596..56b3fe2ab4c 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -50,6 +50,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
     ("check-cfg", PrintKind::CheckCfg),
     ("code-models", PrintKind::CodeModels),
     ("crate-name", PrintKind::CrateName),
+    ("crate-root-lint-levels", PrintKind::CrateRootLintLevels),
     ("deployment-target", PrintKind::DeploymentTarget),
     ("file-names", PrintKind::FileNames),
     ("host-tuple", PrintKind::HostTuple),
@@ -236,10 +237,12 @@ pub enum AutoDiff {
     PrintPerf,
     /// Print intermediate IR generation steps
     PrintSteps,
-    /// Print the whole module, before running opts.
+    /// Print the module, before running autodiff.
     PrintModBefore,
-    /// Print the module after Enzyme differentiated everything.
+    /// Print the module after running autodiff.
     PrintModAfter,
+    /// Print the module after running autodiff and optimizations.
+    PrintModFinal,
 
     /// Enzyme's loose type debug helper (can cause incorrect gradients!!)
     /// Usable in cases where Enzyme errors with `can not deduce type of X`.
@@ -881,6 +884,7 @@ pub enum PrintKind {
     CheckCfg,
     CodeModels,
     CrateName,
+    CrateRootLintLevels,
     DeploymentTarget,
     FileNames,
     HostTuple,
@@ -1423,10 +1427,12 @@ pub fn build_target_config(
             }
             target
         }
-        Err(e) => early_dcx.early_fatal(format!(
-            "Error loading target specification: {e}. \
-                     Run `rustc --print target-list` for a list of built-in targets"
-        )),
+        Err(e) => {
+            let mut err =
+                early_dcx.early_struct_fatal(format!("error loading target specification: {e}"));
+            err.help("run `rustc --print target-list` for a list of built-in targets");
+            err.emit();
+        }
     }
 }
 
@@ -1698,7 +1704,7 @@ pub fn get_cmd_lint_options(
     let mut lint_opts_with_position = vec![];
     let mut describe_lints = false;
 
-    for level in [lint::Allow, lint::Warn, lint::ForceWarn(None), lint::Deny, lint::Forbid] {
+    for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
         for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
             if lint_name == "help" {
                 describe_lints = true;
@@ -2067,6 +2073,7 @@ fn check_print_request_stability(
     match print_kind {
         PrintKind::AllTargetSpecsJson
         | PrintKind::CheckCfg
+        | PrintKind::CrateRootLintLevels
         | PrintKind::SupportedCrateTypes
         | PrintKind::TargetSpecJson
             if !unstable_opts.unstable_options =>
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 71d8dbe44fe..bf95014843d 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -1,4 +1,4 @@
-use std::num::NonZero;
+use std::num::{NonZero, ParseIntError};
 
 use rustc_ast::token;
 use rustc_ast::util::literal::LitError;
@@ -14,6 +14,14 @@ use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTuple};
 use crate::config::CrateType;
 use crate::parse::ParseSess;
 
+#[derive(Diagnostic)]
+pub(crate) enum AppleDeploymentTarget {
+    #[diag(session_apple_deployment_target_invalid)]
+    Invalid { env_var: &'static str, error: ParseIntError },
+    #[diag(session_apple_deployment_target_too_low)]
+    TooLow { env_var: &'static str, version: String, os_min: String },
+}
+
 pub(crate) struct FeatureGateError {
     pub(crate) span: MultiSpan,
     pub(crate) explain: DiagMessage,
@@ -148,6 +156,10 @@ pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi;
 pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi;
 
 #[derive(Diagnostic)]
+#[diag(session_sanitizer_kcfi_arity_requires_kcfi)]
+pub(crate) struct SanitizerKcfiArityRequiresKcfi;
+
+#[derive(Diagnostic)]
 #[diag(session_sanitizer_kcfi_requires_panic_abort)]
 pub(crate) struct SanitizerKcfiRequiresPanicAbort;
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 4cc666b3e37..c70f1500d39 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -711,7 +711,7 @@ mod desc {
     pub(crate) const parse_list: &str = "a space-separated list of strings";
     pub(crate) const parse_list_with_polarity: &str =
         "a comma-separated list of strings, with elements beginning with + or -";
-    pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `LooseTypes`, `Inline`";
+    pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `PrintModFinal`, `LooseTypes`, `Inline`";
     pub(crate) const parse_comma_list: &str = "a comma-separated list of strings";
     pub(crate) const parse_opt_comma_list: &str = parse_comma_list;
     pub(crate) const parse_number: &str = "a number";
@@ -1359,6 +1359,7 @@ pub mod parse {
                 "PrintSteps" => AutoDiff::PrintSteps,
                 "PrintModBefore" => AutoDiff::PrintModBefore,
                 "PrintModAfter" => AutoDiff::PrintModAfter,
+                "PrintModFinal" => AutoDiff::PrintModFinal,
                 "LooseTypes" => AutoDiff::LooseTypes,
                 "Inline" => AutoDiff::Inline,
                 _ => {
@@ -2093,6 +2094,7 @@ options! {
         `=PrintSteps`
         `=PrintModBefore`
         `=PrintModAfter`
+        `=PrintModFinal`
         `=LooseTypes`
         `=Inline`
         Multiple options can be combined with commas."),
@@ -2175,6 +2177,8 @@ options! {
         them only if an error has not been emitted"),
     ehcont_guard: bool = (false, parse_bool, [TRACKED],
         "generate Windows EHCont Guard tables"),
+    embed_metadata: bool = (true, parse_bool, [TRACKED],
+        "embed metadata in rlibs and dylibs (default: yes)"),
     embed_source: bool = (false, parse_bool, [TRACKED],
         "embed source text in DWARF debug sections (default: no)"),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
@@ -2185,6 +2189,8 @@ options! {
         "Use WebAssembly error handling for wasm32-unknown-emscripten"),
     enforce_type_length_limit: bool = (false, parse_bool, [TRACKED],
         "enforce the type length limit when monomorphizing instances in codegen"),
+    experimental_default_bounds: bool = (false, parse_bool, [TRACKED],
+        "enable default bounds for experimental group of auto traits"),
     export_executable_symbols: bool = (false, parse_bool, [TRACKED],
         "export symbols from executables, as if they were dynamic libraries"),
     external_clangrt: bool = (false, parse_bool, [UNTRACKED],
@@ -2439,6 +2445,8 @@ written to standard error output)"),
         "enable normalizing integer types (default: no)"),
     sanitizer_dataflow_abilist: Vec<String> = (Vec::new(), parse_comma_list, [TRACKED],
         "additional ABI list files that control how shadow parameters are passed (comma separated)"),
+    sanitizer_kcfi_arity: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "enable KCFI arity indicator (default: no)"),
     sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED],
         "enable origins tracking in MemorySanitizer"),
     sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
@@ -2551,6 +2559,9 @@ written to standard error output)"),
         "in diagnostics, use heuristics to shorten paths referring to items"),
     tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
         "select processor to schedule for (`rustc --print target-cpus` for details)"),
+    #[rustc_lint_opt_deny_field_access("use `TyCtxt::use_typing_mode_borrowck` instead of this field")]
+    typing_mode_borrowck: bool = (false, parse_bool, [TRACKED],
+        "enable `TypingMode::Borrowck`, changing the way opaque types are handled during MIR borrowck"),
     #[rustc_lint_opt_deny_field_access("use `Session::ub_checks` instead of this field")]
     ub_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "emit runtime checks for Undefined Behavior (default: -Cdebug-assertions)"),
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index a87b1961a99..fb4a437a487 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -29,7 +29,7 @@ use rustc_target::asm::InlineAsmArch;
 use rustc_target::spec::{
     CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
     SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target,
-    TargetTuple, TlsModel,
+    TargetTuple, TlsModel, apple,
 };
 
 use crate::code_stats::CodeStats;
@@ -381,6 +381,10 @@ impl Session {
         self.opts.unstable_opts.sanitizer_cfi_normalize_integers == Some(true)
     }
 
+    pub fn is_sanitizer_kcfi_arity_enabled(&self) -> bool {
+        self.opts.unstable_opts.sanitizer_kcfi_arity == Some(true)
+    }
+
     pub fn is_sanitizer_kcfi_enabled(&self) -> bool {
         self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI)
     }
@@ -891,6 +895,45 @@ impl Session {
             FileNameDisplayPreference::Local
         }
     }
+
+    /// Get the deployment target on Apple platforms based on the standard environment variables,
+    /// or fall back to the minimum version supported by `rustc`.
+    ///
+    /// This should be guarded behind `if sess.target.is_like_darwin`.
+    pub fn apple_deployment_target(&self) -> apple::OSVersion {
+        let min = apple::OSVersion::minimum_deployment_target(&self.target);
+        let env_var = apple::deployment_target_env_var(&self.target.os);
+
+        // FIXME(madsmtm): Track changes to this.
+        if let Ok(deployment_target) = env::var(env_var) {
+            match apple::OSVersion::from_str(&deployment_target) {
+                Ok(version) => {
+                    let os_min = apple::OSVersion::os_minimum_deployment_target(&self.target.os);
+                    // It is common that the deployment target is set a bit too low, for example on
+                    // macOS Aarch64 to also target older x86_64. So we only want to warn when variable
+                    // is lower than the minimum OS supported by rustc, not when the variable is lower
+                    // than the minimum for a specific target.
+                    if version < os_min {
+                        self.dcx().emit_warn(errors::AppleDeploymentTarget::TooLow {
+                            env_var,
+                            version: version.fmt_pretty().to_string(),
+                            os_min: os_min.fmt_pretty().to_string(),
+                        });
+                    }
+
+                    // Raise the deployment target to the minimum supported.
+                    version.max(min)
+                }
+                Err(error) => {
+                    self.dcx().emit_err(errors::AppleDeploymentTarget::Invalid { env_var, error });
+                    min
+                }
+            }
+        } else {
+            // If no deployment target variable is set, default to the minimum found above.
+            min
+        }
+    }
 }
 
 // JUSTIFICATION: part of session construction
@@ -1211,6 +1254,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
         }
     }
 
+    // KCFI arity indicator requires KCFI.
+    if sess.is_sanitizer_kcfi_arity_enabled() && !sess.is_sanitizer_kcfi_enabled() {
+        sess.dcx().emit_err(errors::SanitizerKcfiArityRequiresKcfi);
+    }
+
     // LLVM CFI pointer generalization requires CFI or KCFI.
     if sess.is_sanitizer_cfi_generalize_pointers_enabled() {
         if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) {
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index fcede379b89..2243e831b66 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -149,14 +149,15 @@ pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
                 arg[a.len()..].to_string()
             };
             let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
-            if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) {
+            if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.contains(&option) {
                 excluded_cargo_defaults = true;
             } else {
                 result.push(a.to_string());
-                match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
-                    Some(s) => result.push(format!("{s}=[REDACTED]")),
-                    None => result.push(content),
-                }
+                result.push(if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&option) {
+                    format!("{option}=[REDACTED]")
+                } else {
+                    content
+                });
             }
         }
     }
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index b2149a03a8e..fc9f411ac3c 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -14,6 +14,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 scoped-tls = "1.0"
-stable_mir = {path = "../stable_mir" }
+serde = { version = "1.0.125", features = [ "derive" ] }
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index eaba14bbf30..5d465bca4ee 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -22,3 +22,5 @@ pub mod rustc_internal;
 
 // Make this module private for now since external users should not call these directly.
 mod rustc_smir;
+
+pub mod stable_mir;
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index bb2b2dea2f3..36b68cc1398 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -21,6 +21,7 @@ use stable_mir::{CrateItem, CrateNum, DefId};
 
 use super::RustcInternal;
 use crate::rustc_smir::Tables;
+use crate::stable_mir;
 
 impl RustcInternal for CrateItem {
     type T<'tcx> = rustc_span::def_id::DefId;
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index ad38ea228bf..a546a44c870 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -22,6 +22,7 @@ use stable_mir::ty::IndexedVal;
 
 use crate::rustc_smir::context::TablesWrapper;
 use crate::rustc_smir::{Stable, Tables};
+use crate::stable_mir;
 
 mod internal;
 pub mod pretty;
@@ -147,6 +148,14 @@ impl<'tcx> Tables<'tcx> {
         stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did))
     }
 
+    pub fn assoc_def(&mut self, did: DefId) -> stable_mir::ty::AssocDef {
+        stable_mir::ty::AssocDef(self.create_def_id(did))
+    }
+
+    pub fn opaque_def(&mut self, did: DefId) -> stable_mir::ty::OpaqueDef {
+        stable_mir::ty::OpaqueDef(self.create_def_id(did))
+    }
+
     pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
         stable_mir::ty::Prov(self.create_alloc_id(aid))
     }
diff --git a/compiler/rustc_smir/src/rustc_internal/pretty.rs b/compiler/rustc_smir/src/rustc_internal/pretty.rs
index b752ad71ecc..0710c18746a 100644
--- a/compiler/rustc_smir/src/rustc_internal/pretty.rs
+++ b/compiler/rustc_smir/src/rustc_internal/pretty.rs
@@ -3,6 +3,7 @@ use std::io;
 use rustc_middle::ty::TyCtxt;
 
 use super::run;
+use crate::stable_mir;
 
 pub fn write_smir_pretty<'tcx, W: io::Write>(tcx: TyCtxt<'tcx>, w: &mut W) -> io::Result<()> {
     writeln!(
diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs
index 52c5b425c14..9cb89634c52 100644
--- a/compiler/rustc_smir/src/rustc_smir/alloc.rs
+++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs
@@ -6,6 +6,7 @@ use stable_mir::mir::Mutability;
 use stable_mir::ty::{Allocation, ProvenanceMap};
 
 use crate::rustc_smir::{Stable, Tables};
+use crate::stable_mir;
 
 /// Creates new empty `Allocation` from given `Align`.
 fn new_empty_allocation(align: Align) -> Allocation {
@@ -27,7 +28,7 @@ pub(crate) fn new_allocation<'tcx>(
     tables: &mut Tables<'tcx>,
 ) -> Allocation {
     try_new_allocation(ty, const_value, tables)
-        .expect(&format!("Failed to convert: {const_value:?} to {ty:?}"))
+        .unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}"))
 }
 
 #[allow(rustc::usage_of_qualified_ty)]
@@ -36,39 +37,30 @@ pub(crate) fn try_new_allocation<'tcx>(
     const_value: ConstValue<'tcx>,
     tables: &mut Tables<'tcx>,
 ) -> Result<Allocation, Error> {
+    let layout = tables
+        .tcx
+        .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
+        .map_err(|e| e.stable(tables))?;
     Ok(match const_value {
         ConstValue::Scalar(scalar) => {
             let size = scalar.size();
-            let align = tables
-                .tcx
-                .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
-                .map_err(|e| e.stable(tables))?
-                .align;
-            let mut allocation =
-                rustc_middle::mir::interpret::Allocation::new(size, align.abi, AllocInit::Uninit);
+            let mut allocation = rustc_middle::mir::interpret::Allocation::new(
+                size,
+                layout.align.abi,
+                AllocInit::Uninit,
+            );
             allocation
                 .write_scalar(&tables.tcx, alloc_range(Size::ZERO, size), scalar)
                 .map_err(|e| e.stable(tables))?;
             allocation.stable(tables)
         }
-        ConstValue::ZeroSized => {
-            let align = tables
-                .tcx
-                .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
-                .map_err(|e| e.stable(tables))?
-                .align;
-            new_empty_allocation(align.abi)
-        }
+        ConstValue::ZeroSized => new_empty_allocation(layout.align.abi),
         ConstValue::Slice { data, meta } => {
             let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data);
             let ptr = Pointer::new(alloc_id.into(), Size::ZERO);
             let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
             let scalar_meta =
                 rustc_middle::mir::interpret::Scalar::from_target_usize(meta, &tables.tcx);
-            let layout = tables
-                .tcx
-                .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
-                .map_err(|e| e.stable(tables))?;
             let mut allocation = rustc_middle::mir::interpret::Allocation::new(
                 layout.size,
                 layout.align.abi,
@@ -92,12 +84,7 @@ pub(crate) fn try_new_allocation<'tcx>(
         }
         ConstValue::Indirect { alloc_id, offset } => {
             let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory();
-            let ty_size = tables
-                .tcx
-                .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
-                .map_err(|e| e.stable(tables))?
-                .size;
-            allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
+            allocation_filter(&alloc.0, alloc_range(offset, layout.size), tables)
         }
     })
 }
diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs
index 2eb0cea0e85..64763b71d30 100644
--- a/compiler/rustc_smir/src/rustc_smir/builder.rs
+++ b/compiler/rustc_smir/src/rustc_smir/builder.rs
@@ -10,6 +10,7 @@ use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::ty::{self, TyCtxt};
 
 use crate::rustc_smir::{Stable, Tables};
+use crate::stable_mir;
 
 /// Builds a monomorphic body for a given instance.
 pub(crate) struct BodyBuilder<'tcx> {
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index aa1921fc8e7..240f6f7fe45 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -35,6 +35,7 @@ use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, I
 use crate::rustc_internal::RustcInternal;
 use crate::rustc_smir::builder::BodyBuilder;
 use crate::rustc_smir::{Stable, Tables, alloc, filter_def_ids, new_item_kind, smir_crate};
+use crate::stable_mir;
 
 impl<'tcx> Context for TablesWrapper<'tcx> {
     fn target_info(&self) -> MachineInfo {
@@ -822,6 +823,21 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         let ty = un_op.internal(&mut *tables, tcx).ty(tcx, arg_internal);
         ty.stable(&mut *tables)
     }
+
+    fn associated_items(&self, def_id: stable_mir::DefId) -> stable_mir::AssocItems {
+        let mut tables = self.0.borrow_mut();
+        let tcx = tables.tcx;
+        let def_id = tables[def_id];
+        let assoc_items = if tcx.is_trait_alias(def_id) {
+            Vec::new()
+        } else {
+            tcx.associated_item_def_ids(def_id)
+                .iter()
+                .map(|did| tcx.associated_item(*did).stable(&mut *tables))
+                .collect()
+        };
+        assoc_items
+    }
 }
 
 pub(crate) struct TablesWrapper<'tcx>(pub RefCell<Tables<'tcx>>);
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
index 62cbab9b723..7ccc785a400 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
@@ -14,6 +14,7 @@ use stable_mir::target::MachineSize as Size;
 use stable_mir::ty::{Align, IndexedVal, VariantIdx};
 
 use crate::rustc_smir::{Stable, Tables};
+use crate::stable_mir;
 
 impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
     type T = VariantIdx;
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/error.rs b/compiler/rustc_smir/src/rustc_smir/convert/error.rs
index 82ecfa630dd..2cde5542483 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/error.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/error.rs
@@ -6,6 +6,7 @@ use rustc_middle::mir::interpret::AllocError;
 use rustc_middle::ty::layout::LayoutError;
 
 use crate::rustc_smir::{Stable, Tables};
+use crate::stable_mir;
 
 impl<'tcx> Stable<'tcx> for LayoutError<'tcx> {
     type T = stable_mir::Error;
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index bdd6e16a7c1..61b769bce08 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -9,6 +9,7 @@ use stable_mir::ty::{Allocation, ConstantKind, MirConst};
 use stable_mir::{Error, opaque};
 
 use crate::rustc_smir::{Stable, Tables, alloc};
+use crate::stable_mir;
 
 impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
     type T = stable_mir::mir::Body;
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
index a3da563af50..3494de62d83 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
@@ -3,6 +3,7 @@
 use rustc_abi::FieldIdx;
 
 use crate::rustc_smir::{Stable, Tables};
+use crate::stable_mir;
 
 mod abi;
 mod error;
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index aa0eac628dd..1ba25aa0e97 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -7,6 +7,7 @@ use stable_mir::ty::{
 };
 
 use crate::rustc_smir::{Stable, Tables, alloc};
+use crate::stable_mir;
 
 impl<'tcx> Stable<'tcx> for ty::AliasTyKind {
     type T = stable_mir::ty::AliasKind;
@@ -890,3 +891,63 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule {
         }
     }
 }
+
+impl<'tcx> Stable<'tcx> for ty::AssocKind {
+    type T = stable_mir::ty::AssocKind;
+
+    fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
+        use stable_mir::ty::AssocKind;
+        match self {
+            ty::AssocKind::Const => AssocKind::Const,
+            ty::AssocKind::Fn => AssocKind::Fn,
+            ty::AssocKind::Type => AssocKind::Type,
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::AssocItemContainer {
+    type T = stable_mir::ty::AssocItemContainer;
+
+    fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
+        use stable_mir::ty::AssocItemContainer;
+        match self {
+            ty::AssocItemContainer::Trait => AssocItemContainer::Trait,
+            ty::AssocItemContainer::Impl => AssocItemContainer::Impl,
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::AssocItem {
+    type T = stable_mir::ty::AssocItem;
+
+    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
+        stable_mir::ty::AssocItem {
+            def_id: tables.assoc_def(self.def_id),
+            name: self.name.to_string(),
+            kind: self.kind.stable(tables),
+            container: self.container.stable(tables),
+            trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)),
+            fn_has_self_parameter: self.fn_has_self_parameter,
+            opt_rpitit_info: self.opt_rpitit_info.map(|rpitit| rpitit.stable(tables)),
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData {
+    type T = stable_mir::ty::ImplTraitInTraitData;
+
+    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
+        use stable_mir::ty::ImplTraitInTraitData;
+        match self {
+            ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => {
+                ImplTraitInTraitData::Trait {
+                    fn_def_id: tables.fn_def(*fn_def_id),
+                    opaque_def_id: tables.opaque_def(*opaque_def_id),
+                }
+            }
+            ty::ImplTraitInTraitData::Impl { fn_def_id } => {
+                ImplTraitInTraitData::Impl { fn_def_id: tables.fn_def(*fn_def_id) }
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index c5d33f090a0..dea8f54a670 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -21,6 +21,7 @@ use stable_mir::{CtorKind, ItemKind};
 use tracing::debug;
 
 use crate::rustc_internal::IndexMap;
+use crate::stable_mir;
 
 mod alloc;
 mod builder;
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/rustc_smir/src/stable_mir/abi.rs
index 091f3e1a95e..3842cb7e653 100644
--- a/compiler/stable_mir/src/abi.rs
+++ b/compiler/rustc_smir/src/stable_mir/abi.rs
@@ -3,12 +3,13 @@ use std::num::NonZero;
 use std::ops::RangeInclusive;
 
 use serde::Serialize;
+use stable_mir::compiler_interface::with;
+use stable_mir::mir::FieldIdx;
+use stable_mir::target::{MachineInfo, MachineSize as Size};
+use stable_mir::ty::{Align, IndexedVal, Ty, VariantIdx};
+use stable_mir::{Error, Opaque, error};
 
-use crate::compiler_interface::with;
-use crate::mir::FieldIdx;
-use crate::target::{MachineInfo, MachineSize as Size};
-use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
-use crate::{Error, Opaque, error};
+use crate::stable_mir;
 
 /// A function ABI definition.
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
@@ -149,7 +150,7 @@ pub enum FieldsShape {
     Arbitrary {
         /// Offsets for the first byte of each field,
         /// ordered to match the source definition order.
-        /// I.e.: It follows the same order as [crate::ty::VariantDef::fields()].
+        /// I.e.: It follows the same order as [super::ty::VariantDef::fields()].
         /// This vector does not go in increasing order.
         offsets: Vec<Size>,
     },
diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs
index e82c957c34e..33d950bb951 100644
--- a/compiler/stable_mir/src/compiler_interface.rs
+++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs
@@ -5,23 +5,25 @@
 
 use std::cell::Cell;
 
-use crate::abi::{FnAbi, Layout, LayoutShape};
-use crate::crate_def::Attribute;
-use crate::mir::alloc::{AllocId, GlobalAlloc};
-use crate::mir::mono::{Instance, InstanceDef, StaticDef};
-use crate::mir::{BinOp, Body, Place, UnOp};
-use crate::target::MachineInfo;
-use crate::ty::{
+use stable_mir::abi::{FnAbi, Layout, LayoutShape};
+use stable_mir::crate_def::Attribute;
+use stable_mir::mir::alloc::{AllocId, GlobalAlloc};
+use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef};
+use stable_mir::mir::{BinOp, Body, Place, UnOp};
+use stable_mir::target::MachineInfo;
+use stable_mir::ty::{
     AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
     ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
     ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl,
     TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
 };
-use crate::{
-    Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind,
-    Symbol, TraitDecls, mir,
+use stable_mir::{
+    AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls,
+    ItemKind, Symbol, TraitDecls, mir,
 };
 
+use crate::stable_mir;
+
 /// This trait defines the interface between stable_mir and the Rust compiler.
 /// Do not use this directly.
 pub trait Context {
@@ -251,6 +253,9 @@ pub trait Context {
 
     /// Get the resulting type of unary operation.
     fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty;
+
+    /// Get all associated items of a definition.
+    fn associated_items(&self, def_id: DefId) -> AssocItems;
 }
 
 // A thread local variable that stores a pointer to the tables mapping between TyCtxt
diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/rustc_smir/src/stable_mir/crate_def.rs
index 2577c281ca4..64f7ef9b314 100644
--- a/compiler/stable_mir/src/crate_def.rs
+++ b/compiler/rustc_smir/src/stable_mir/crate_def.rs
@@ -2,9 +2,10 @@
 //! such as, a function, a trait, an enum, and any other definitions.
 
 use serde::Serialize;
+use stable_mir::ty::{GenericArgs, Span, Ty};
+use stable_mir::{AssocItems, Crate, Symbol, with};
 
-use crate::ty::{GenericArgs, Span, Ty};
-use crate::{Crate, Symbol, with};
+use crate::stable_mir;
 
 /// A unique identification number for each item accessible for the current compilation unit.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
@@ -103,6 +104,14 @@ pub trait CrateDefType: CrateDef {
     }
 }
 
+/// A trait for retrieving all items from a definition within a crate.
+pub trait CrateDefItems: CrateDef {
+    /// Retrieve all associated items from a definition.
+    fn associated_items(&self) -> AssocItems {
+        with(|cx| cx.associated_items(self.def_id()))
+    }
+}
+
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Attribute {
     value: String,
@@ -158,3 +167,9 @@ macro_rules! crate_def_with_ty {
         impl CrateDefType for $name {}
     };
 }
+
+macro_rules! impl_crate_def_items {
+    ( $name:ident $(;)? ) => {
+        impl CrateDefItems for $name {}
+    };
+}
diff --git a/compiler/stable_mir/src/error.rs b/compiler/rustc_smir/src/stable_mir/error.rs
index 050752e41eb..050752e41eb 100644
--- a/compiler/stable_mir/src/error.rs
+++ b/compiler/rustc_smir/src/stable_mir/error.rs
diff --git a/compiler/stable_mir/src/mir.rs b/compiler/rustc_smir/src/stable_mir/mir.rs
index 413b5152bb3..413b5152bb3 100644
--- a/compiler/stable_mir/src/mir.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir.rs
diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/mir/alloc.rs
index 023807b76ae..782f52888b7 100644
--- a/compiler/stable_mir/src/mir/alloc.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/alloc.rs
@@ -3,11 +3,12 @@
 use std::io::Read;
 
 use serde::Serialize;
+use stable_mir::mir::mono::{Instance, StaticDef};
+use stable_mir::target::{Endian, MachineInfo};
+use stable_mir::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
+use stable_mir::{Error, with};
 
-use crate::mir::mono::{Instance, StaticDef};
-use crate::target::{Endian, MachineInfo};
-use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
-use crate::{Error, with};
+use crate::stable_mir;
 
 /// An allocation in the SMIR global memory can be either a function pointer,
 /// a static, or a "real" allocation with some data in it.
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index b1bf7bce828..b2360545424 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -1,14 +1,15 @@
 use std::io;
 
 use serde::Serialize;
-
-use crate::compiler_interface::with;
-use crate::mir::pretty::function_body;
-use crate::ty::{
+use stable_mir::compiler_interface::with;
+use stable_mir::mir::pretty::function_body;
+use stable_mir::ty::{
     AdtDef, ClosureDef, CoroutineClosureDef, CoroutineDef, GenericArgs, MirConst, Movability,
     Region, RigidTy, Ty, TyConst, TyKind, VariantIdx,
 };
-use crate::{Error, Opaque, Span, Symbol};
+use stable_mir::{Error, Opaque, Span, Symbol};
+
+use crate::stable_mir;
 
 /// The SMIR representation of a single function.
 #[derive(Clone, Debug, Serialize)]
@@ -565,7 +566,7 @@ pub enum Rvalue {
     ///
     /// **Needs clarification**: Are there weird additional semantics here related to the runtime
     /// nature of this operation?
-    ThreadLocalRef(crate::CrateItem),
+    ThreadLocalRef(stable_mir::CrateItem),
 
     /// Computes a value as described by the operation.
     NullaryOp(NullOp, Ty),
@@ -1057,8 +1058,7 @@ impl Place {
     /// In order to retrieve the correct type, the `locals` argument must match the list of all
     /// locals from the function body where this place originates from.
     pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
-        let start_ty = locals[self.local].ty;
-        self.projection.iter().fold(Ok(start_ty), |place_ty, elem| elem.ty(place_ty?))
+        self.projection.iter().try_fold(locals[self.local].ty, |place_ty, elem| elem.ty(place_ty))
     }
 }
 
diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/rustc_smir/src/stable_mir/mir/mono.rs
index 22507a49411..0c3e4fb7c90 100644
--- a/compiler/stable_mir/src/mir/mono.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/mono.rs
@@ -2,12 +2,13 @@ use std::fmt::{Debug, Formatter};
 use std::io;
 
 use serde::Serialize;
+use stable_mir::abi::FnAbi;
+use stable_mir::crate_def::CrateDef;
+use stable_mir::mir::Body;
+use stable_mir::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
+use stable_mir::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with};
 
-use crate::abi::FnAbi;
-use crate::crate_def::CrateDef;
-use crate::mir::Body;
-use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
-use crate::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with};
+use crate::stable_mir;
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
 pub enum MonoItem {
@@ -117,11 +118,11 @@ impl Instance {
     }
 
     /// Resolve an instance starting from a function definition and generic arguments.
-    pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
+    pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
         with(|context| {
-            context.resolve_instance(def, args).ok_or_else(|| {
-                crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
-            })
+            context
+                .resolve_instance(def, args)
+                .ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
         })
     }
 
@@ -131,11 +132,11 @@ impl Instance {
     }
 
     /// Resolve an instance for a given function pointer.
-    pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
+    pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
         with(|context| {
-            context.resolve_for_fn_ptr(def, args).ok_or_else(|| {
-                crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
-            })
+            context
+                .resolve_for_fn_ptr(def, args)
+                .ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
         })
     }
 
@@ -144,11 +145,11 @@ impl Instance {
         def: ClosureDef,
         args: &GenericArgs,
         kind: ClosureKind,
-    ) -> Result<Instance, crate::Error> {
+    ) -> Result<Instance, Error> {
         with(|context| {
-            context.resolve_closure(def, args, kind).ok_or_else(|| {
-                crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
-            })
+            context
+                .resolve_closure(def, args, kind)
+                .ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
         })
     }
 
@@ -195,7 +196,7 @@ impl Debug for Instance {
 /// Try to convert a crate item into an instance.
 /// The item cannot be generic in order to be converted into an instance.
 impl TryFrom<CrateItem> for Instance {
-    type Error = crate::Error;
+    type Error = stable_mir::Error;
 
     fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
         with(|context| {
@@ -212,7 +213,7 @@ impl TryFrom<CrateItem> for Instance {
 /// Try to convert an instance into a crate item.
 /// Only user defined instances can be converted.
 impl TryFrom<Instance> for CrateItem {
-    type Error = crate::Error;
+    type Error = stable_mir::Error;
 
     fn try_from(value: Instance) -> Result<Self, Self::Error> {
         with(|context| {
@@ -259,7 +260,7 @@ crate_def! {
 }
 
 impl TryFrom<CrateItem> for StaticDef {
-    type Error = crate::Error;
+    type Error = stable_mir::Error;
 
     fn try_from(value: CrateItem) -> Result<Self, Self::Error> {
         if matches!(value.kind(), ItemKind::Static) {
@@ -271,7 +272,7 @@ impl TryFrom<CrateItem> for StaticDef {
 }
 
 impl TryFrom<Instance> for StaticDef {
-    type Error = crate::Error;
+    type Error = stable_mir::Error;
 
     fn try_from(value: Instance) -> Result<Self, Self::Error> {
         StaticDef::try_from(CrateItem::try_from(value)?)
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs
index 8278afb7a2f..439ebe978e5 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs
@@ -4,13 +4,14 @@ use std::io::Write;
 use std::{fmt, io, iter};
 
 use fmt::{Display, Formatter};
-
-use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
-use crate::mir::{
+use stable_mir::mir::{
     Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
 };
-use crate::ty::{AdtKind, IndexedVal, MirConst, Ty, TyConst};
-use crate::{Body, CrateDef, Mutability, with};
+use stable_mir::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst};
+use stable_mir::{Body, CrateDef, Mutability, with};
+
+use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
+use crate::stable_mir;
 
 impl Display for Ty {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -18,6 +19,16 @@ impl Display for Ty {
     }
 }
 
+impl Display for AssocKind {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        match self {
+            AssocKind::Fn => write!(f, "method"),
+            AssocKind::Const => write!(f, "associated const"),
+            AssocKind::Type => write!(f, "associated type"),
+        }
+    }
+}
+
 impl Debug for Place {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         with(|ctx| write!(f, "{}", ctx.place_pretty(self)))
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/rustc_smir/src/stable_mir/mir/visit.rs
index 09447e70dfb..786693ea98d 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/visit.rs
@@ -35,9 +35,11 @@
 //! The only place that `_` is acceptable is to match a field (or
 //! variant argument) that does not require visiting.
 
-use crate::mir::*;
-use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst};
-use crate::{Error, Opaque, Span};
+use stable_mir::mir::*;
+use stable_mir::ty::{GenericArgs, MirConst, Region, Ty, TyConst};
+use stable_mir::{Error, Opaque, Span};
+
+use crate::stable_mir;
 
 macro_rules! make_mir_visitor {
     ($visitor_trait_name:ident, $($mutability:ident)?) => {
@@ -563,7 +565,7 @@ pub struct PlaceRef<'a> {
 impl PlaceRef<'_> {
     /// Get the type of this place.
     pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
-        self.projection.iter().fold(Ok(locals[self.local].ty), |place_ty, elem| elem.ty(place_ty?))
+        self.projection.iter().try_fold(locals[self.local].ty, |place_ty, elem| elem.ty(place_ty))
     }
 }
 
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
new file mode 100644
index 00000000000..c59758d4ad3
--- /dev/null
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -0,0 +1,239 @@
+//! Module that is temporarily parasitic on the `rustc_smir` crate,
+//!
+//! This module is designed to resolve circular dependency that would happen
+//! if we gradually invert the dependency order between `rustc_smir` and `stable_mir`.
+//!
+//! Once refactoring is complete, we will migrate it back to the `stable_mir` crate.
+
+//! The WIP stable interface to rustc internals.
+//!
+//! For more information see <https://github.com/rust-lang/project-stable-mir>
+//!
+//! # Note
+//!
+//! This API is still completely unstable and subject to change.
+
+// #![doc(
+//     html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
+//     test(attr(allow(unused_variables), deny(warnings)))
+// )]
+//!
+//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to
+//! interact with the compiler.
+//!
+//! The goal is to eventually be published on
+//! [crates.io](https://crates.io).
+
+use std::fmt::Debug;
+use std::{fmt, io};
+
+use serde::Serialize;
+use stable_mir::compiler_interface::with;
+pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId};
+pub use stable_mir::error::*;
+use stable_mir::mir::mono::StaticDef;
+use stable_mir::mir::{Body, Mutability};
+use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
+
+use crate::stable_mir;
+
+pub mod abi;
+#[macro_use]
+pub mod crate_def;
+pub mod compiler_interface;
+#[macro_use]
+pub mod error;
+pub mod mir;
+pub mod target;
+pub mod ty;
+pub mod visitor;
+
+/// Use String for now but we should replace it.
+pub type Symbol = String;
+
+/// The number that identifies a crate.
+pub type CrateNum = usize;
+
+impl Debug for DefId {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("DefId").field("id", &self.0).field("name", &self.name()).finish()
+    }
+}
+
+impl IndexedVal for DefId {
+    fn to_val(index: usize) -> Self {
+        DefId(index)
+    }
+
+    fn to_index(&self) -> usize {
+        self.0
+    }
+}
+
+/// A list of crate items.
+pub type CrateItems = Vec<CrateItem>;
+
+/// A list of trait decls.
+pub type TraitDecls = Vec<TraitDef>;
+
+/// A list of impl trait decls.
+pub type ImplTraitDecls = Vec<ImplDef>;
+
+/// A list of associated items.
+pub type AssocItems = Vec<AssocItem>;
+
+/// Holds information about a crate.
+#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
+pub struct Crate {
+    pub id: CrateNum,
+    pub name: Symbol,
+    pub is_local: bool,
+}
+
+impl Crate {
+    /// The list of foreign modules in this crate.
+    pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> {
+        with(|cx| cx.foreign_modules(self.id))
+    }
+
+    /// The list of traits declared in this crate.
+    pub fn trait_decls(&self) -> TraitDecls {
+        with(|cx| cx.trait_decls(self.id))
+    }
+
+    /// The list of trait implementations in this crate.
+    pub fn trait_impls(&self) -> ImplTraitDecls {
+        with(|cx| cx.trait_impls(self.id))
+    }
+
+    /// Return a list of function definitions from this crate independent on their visibility.
+    pub fn fn_defs(&self) -> Vec<FnDef> {
+        with(|cx| cx.crate_functions(self.id))
+    }
+
+    /// Return a list of static items defined in this crate independent on their visibility.
+    pub fn statics(&self) -> Vec<StaticDef> {
+        with(|cx| cx.crate_statics(self.id))
+    }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
+pub enum ItemKind {
+    Fn,
+    Static,
+    Const,
+    Ctor(CtorKind),
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
+pub enum CtorKind {
+    Const,
+    Fn,
+}
+
+pub type Filename = String;
+
+crate_def_with_ty! {
+    /// Holds information about an item in a crate.
+    #[derive(Serialize)]
+    pub CrateItem;
+}
+
+impl CrateItem {
+    /// This will return the body of an item or panic if it's not available.
+    pub fn expect_body(&self) -> mir::Body {
+        with(|cx| cx.mir_body(self.0))
+    }
+
+    /// Return the body of an item if available.
+    pub fn body(&self) -> Option<mir::Body> {
+        with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
+    }
+
+    /// Check if a body is available for this item.
+    pub fn has_body(&self) -> bool {
+        with(|cx| cx.has_body(self.0))
+    }
+
+    pub fn span(&self) -> Span {
+        with(|cx| cx.span_of_an_item(self.0))
+    }
+
+    pub fn kind(&self) -> ItemKind {
+        with(|cx| cx.item_kind(*self))
+    }
+
+    pub fn requires_monomorphization(&self) -> bool {
+        with(|cx| cx.requires_monomorphization(self.0))
+    }
+
+    pub fn ty(&self) -> Ty {
+        with(|cx| cx.def_ty(self.0))
+    }
+
+    pub fn is_foreign_item(&self) -> bool {
+        with(|cx| cx.is_foreign_item(self.0))
+    }
+
+    /// Emit MIR for this item body.
+    pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
+        self.body()
+            .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
+            .dump(w, &self.name())
+    }
+}
+
+/// Return the function where execution starts if the current
+/// crate defines that. This is usually `main`, but could be
+/// `start` if the crate is a no-std crate.
+pub fn entry_fn() -> Option<CrateItem> {
+    with(|cx| cx.entry_fn())
+}
+
+/// Access to the local crate.
+pub fn local_crate() -> Crate {
+    with(|cx| cx.local_crate())
+}
+
+/// Try to find a crate or crates if multiple crates exist from given name.
+pub fn find_crates(name: &str) -> Vec<Crate> {
+    with(|cx| cx.find_crates(name))
+}
+
+/// Try to find a crate with the given name.
+pub fn external_crates() -> Vec<Crate> {
+    with(|cx| cx.external_crates())
+}
+
+/// Retrieve all items in the local crate that have a MIR associated with them.
+pub fn all_local_items() -> CrateItems {
+    with(|cx| cx.all_local_items())
+}
+
+pub fn all_trait_decls() -> TraitDecls {
+    with(|cx| cx.all_trait_decls())
+}
+
+pub fn all_trait_impls() -> ImplTraitDecls {
+    with(|cx| cx.all_trait_impls())
+}
+
+/// A type that provides internal information but that can still be used for debug purpose.
+#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
+pub struct Opaque(String);
+
+impl std::fmt::Display for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl std::fmt::Debug for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+pub fn opaque<T: Debug>(value: &T) -> Opaque {
+    Opaque(format!("{value:?}"))
+}
diff --git a/compiler/stable_mir/src/target.rs b/compiler/rustc_smir/src/stable_mir/target.rs
index 32c3a2a9122..6cf1e9feb01 100644
--- a/compiler/stable_mir/src/target.rs
+++ b/compiler/rustc_smir/src/stable_mir/target.rs
@@ -1,8 +1,9 @@
 //! Provide information about the machine that this is being compiled into.
 
 use serde::Serialize;
+use stable_mir::compiler_interface::with;
 
-use crate::compiler_interface::with;
+use crate::stable_mir;
 
 /// The properties of the target machine being compiled into.
 #[derive(Clone, PartialEq, Eq, Serialize)]
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index b857a735b72..1efa2fe13c5 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -2,15 +2,16 @@ use std::fmt::{self, Debug, Display, Formatter};
 use std::ops::Range;
 
 use serde::Serialize;
+use stable_mir::abi::{FnAbi, Layout};
+use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType};
+use stable_mir::mir::alloc::{AllocId, read_target_int, read_target_uint};
+use stable_mir::mir::mono::StaticDef;
+use stable_mir::target::MachineInfo;
+use stable_mir::{Filename, Opaque};
 
 use super::mir::{Body, Mutability, Safety};
 use super::{DefId, Error, Symbol, with};
-use crate::abi::{FnAbi, Layout};
-use crate::crate_def::{CrateDef, CrateDefType};
-use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
-use crate::mir::mono::StaticDef;
-use crate::target::MachineInfo;
-use crate::{Filename, Opaque};
+use crate::stable_mir;
 
 #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
 pub struct Ty(usize);
@@ -588,7 +589,7 @@ pub enum IntTy {
 impl IntTy {
     pub fn num_bytes(self) -> usize {
         match self {
-            IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes(),
+            IntTy::Isize => MachineInfo::target_pointer_width().bytes(),
             IntTy::I8 => 1,
             IntTy::I16 => 2,
             IntTy::I32 => 4,
@@ -611,7 +612,7 @@ pub enum UintTy {
 impl UintTy {
     pub fn num_bytes(self) -> usize {
         match self {
-            UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes(),
+            UintTy::Usize => MachineInfo::target_pointer_width().bytes(),
             UintTy::U8 => 1,
             UintTy::U16 => 2,
             UintTy::U32 => 4,
@@ -910,6 +911,10 @@ crate_def! {
     pub TraitDef;
 }
 
+impl_crate_def_items! {
+    TraitDef;
+}
+
 impl TraitDef {
     pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
         with(|cx| cx.trait_decl(trait_def))
@@ -932,6 +937,10 @@ crate_def! {
     pub ImplDef;
 }
 
+impl_crate_def_items! {
+    ImplDef;
+}
+
 impl ImplDef {
     /// Retrieve information about this implementation.
     pub fn trait_impl(&self) -> ImplTrait {
@@ -1555,3 +1564,60 @@ index_impl!(Span);
 pub struct VariantIdx(usize);
 
 index_impl!(VariantIdx);
+
+crate_def! {
+    /// Hold infomation about an Opaque definition, particularly useful in `RPITIT`.
+    #[derive(Serialize)]
+    pub OpaqueDef;
+}
+
+crate_def! {
+    #[derive(Serialize)]
+    pub AssocDef;
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
+pub struct AssocItem {
+    pub def_id: AssocDef,
+    pub name: Symbol,
+    pub kind: AssocKind,
+    pub container: AssocItemContainer,
+
+    /// If this is an item in an impl of a trait then this is the `DefId` of
+    /// the associated item on the trait that this implements.
+    pub trait_item_def_id: Option<AssocDef>,
+
+    /// Whether this is a method with an explicit self
+    /// as its first parameter, allowing method calls.
+    pub fn_has_self_parameter: bool,
+
+    /// `Some` if the associated item (an associated type) comes from the
+    /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData`
+    /// provides additional information about its source.
+    pub opt_rpitit_info: Option<ImplTraitInTraitData>,
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
+pub enum AssocKind {
+    Const,
+    Fn,
+    Type,
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
+pub enum AssocItemContainer {
+    Trait,
+    Impl,
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
+pub enum ImplTraitInTraitData {
+    Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
+    Impl { fn_def_id: FnDef },
+}
+
+impl AssocItem {
+    pub fn is_impl_trait_in_trait(&self) -> bool {
+        self.opt_rpitit_info.is_some()
+    }
+}
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/rustc_smir/src/stable_mir/visitor.rs
index 8463174f9a4..31a53d1b19d 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/rustc_smir/src/stable_mir/visitor.rs
@@ -1,11 +1,13 @@
 use std::ops::ControlFlow;
 
+use stable_mir::Opaque;
+use stable_mir::ty::TyConst;
+
 use super::ty::{
     Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
     MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
 };
-use crate::Opaque;
-use crate::ty::TyConst;
+use crate::stable_mir;
 
 pub trait Visitor: Sized {
     type Break;
@@ -47,13 +49,13 @@ impl Visitable for TyConst {
     }
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         match &self.kind {
-            crate::ty::TyConstKind::Param(_) | crate::ty::TyConstKind::Bound(_, _) => {}
-            crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
-            crate::ty::TyConstKind::Value(ty, alloc) => {
+            super::ty::TyConstKind::Param(_) | super::ty::TyConstKind::Bound(_, _) => {}
+            super::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
+            super::ty::TyConstKind::Value(ty, alloc) => {
                 alloc.visit(visitor)?;
                 ty.visit(visitor)?;
             }
-            crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
+            super::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
         }
         ControlFlow::Continue(())
     }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 4390085cd04..9be16f8ce0c 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -24,9 +24,6 @@
 // because getting it wrong can lead to nested `HygieneData::with` calls that
 // trigger runtime aborts. (Fortunately these are obvious and easy to fix.)
 
-use std::cell::RefCell;
-use std::collections::hash_map::Entry;
-use std::collections::hash_set::Entry as SetEntry;
 use std::hash::Hash;
 use std::sync::Arc;
 use std::{fmt, iter, mem};
@@ -34,7 +31,7 @@ use std::{fmt, iter, mem};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher};
-use rustc_data_structures::sync::{Lock, WorkerLocal};
+use rustc_data_structures::sync::Lock;
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_hashes::Hash64;
 use rustc_index::IndexVec;
@@ -61,8 +58,8 @@ impl !PartialOrd for SyntaxContext {}
 /// The other fields are only for caching.
 type SyntaxContextKey = (SyntaxContext, ExpnId, Transparency);
 
-#[derive(Clone, Copy, PartialEq, Debug, Encodable, Decodable)]
-pub struct SyntaxContextData {
+#[derive(Clone, Copy, Debug)]
+struct SyntaxContextData {
     outer_expn: ExpnId,
     outer_transparency: Transparency,
     parent: SyntaxContext,
@@ -74,7 +71,33 @@ pub struct SyntaxContextData {
     dollar_crate_name: Symbol,
 }
 
+/// Same as `SyntaxContextData`, but `opaque(_and_semitransparent)` cannot be recursive
+/// and use `None` if they need to refer to self. Used for encoding and decoding metadata.
+#[derive(Encodable, Decodable)]
+pub struct SyntaxContextDataNonRecursive {
+    outer_expn: ExpnId,
+    outer_transparency: Transparency,
+    parent: SyntaxContext,
+    opaque: Option<SyntaxContext>,
+    opaque_and_semitransparent: Option<SyntaxContext>,
+}
+
 impl SyntaxContextData {
+    fn new(
+        (parent, outer_expn, outer_transparency): SyntaxContextKey,
+        opaque: SyntaxContext,
+        opaque_and_semitransparent: SyntaxContext,
+    ) -> SyntaxContextData {
+        SyntaxContextData {
+            outer_expn,
+            outer_transparency,
+            parent,
+            opaque,
+            opaque_and_semitransparent,
+            dollar_crate_name: kw::DollarCrate,
+        }
+    }
+
     fn root() -> SyntaxContextData {
         SyntaxContextData {
             outer_expn: ExpnId::root(),
@@ -99,6 +122,19 @@ impl SyntaxContextData {
     }
 }
 
+impl SyntaxContextDataNonRecursive {
+    fn recursive(&self, ctxt: SyntaxContext) -> SyntaxContextData {
+        SyntaxContextData {
+            outer_expn: self.outer_expn,
+            outer_transparency: self.outer_transparency,
+            parent: self.parent,
+            opaque: self.opaque.unwrap_or(ctxt),
+            opaque_and_semitransparent: self.opaque_and_semitransparent.unwrap_or(ctxt),
+            dollar_crate_name: kw::DollarCrate,
+        }
+    }
+}
+
 rustc_index::newtype_index! {
     /// A unique ID associated with a macro invocation and expansion.
     #[orderable]
@@ -543,7 +579,7 @@ impl HygieneData {
     ) -> SyntaxContext {
         assert_ne!(expn_id, ExpnId::root());
         if transparency == Transparency::Opaque {
-            return self.apply_mark_internal(ctxt, expn_id, transparency);
+            return self.alloc_ctxt(ctxt, expn_id, transparency);
         }
 
         let call_site_ctxt = self.expn_data(expn_id).call_site.ctxt();
@@ -554,7 +590,7 @@ impl HygieneData {
         };
 
         if call_site_ctxt.is_root() {
-            return self.apply_mark_internal(ctxt, expn_id, transparency);
+            return self.alloc_ctxt(ctxt, expn_id, transparency);
         }
 
         // Otherwise, `expn_id` is a macros 1.0 definition and the call site is in a
@@ -567,74 +603,73 @@ impl HygieneData {
         //
         // See the example at `test/ui/hygiene/legacy_interaction.rs`.
         for (expn_id, transparency) in self.marks(ctxt) {
-            call_site_ctxt = self.apply_mark_internal(call_site_ctxt, expn_id, transparency);
+            call_site_ctxt = self.alloc_ctxt(call_site_ctxt, expn_id, transparency);
         }
-        self.apply_mark_internal(call_site_ctxt, expn_id, transparency)
+        self.alloc_ctxt(call_site_ctxt, expn_id, transparency)
     }
 
-    fn apply_mark_internal(
+    /// Allocate a new context with the given key, or retrieve it from cache if the given key
+    /// already exists. The auxiliary fields are calculated from the key.
+    fn alloc_ctxt(
         &mut self,
-        ctxt: SyntaxContext,
+        parent: SyntaxContext,
         expn_id: ExpnId,
         transparency: Transparency,
     ) -> SyntaxContext {
-        let syntax_context_data = &mut self.syntax_context_data;
-        debug_assert!(!syntax_context_data[ctxt.0 as usize].is_decode_placeholder());
-        let mut opaque = syntax_context_data[ctxt.0 as usize].opaque;
-        let mut opaque_and_semitransparent =
-            syntax_context_data[ctxt.0 as usize].opaque_and_semitransparent;
-
-        if transparency >= Transparency::Opaque {
-            let parent = opaque;
-            opaque = *self
-                .syntax_context_map
-                .entry((parent, expn_id, transparency))
-                .or_insert_with(|| {
-                    let new_opaque = SyntaxContext::from_usize(syntax_context_data.len());
-                    syntax_context_data.push(SyntaxContextData {
-                        outer_expn: expn_id,
-                        outer_transparency: transparency,
-                        parent,
-                        opaque: new_opaque,
-                        opaque_and_semitransparent: new_opaque,
-                        dollar_crate_name: kw::DollarCrate,
-                    });
-                    new_opaque
-                });
-        }
+        debug_assert!(!self.syntax_context_data[parent.0 as usize].is_decode_placeholder());
 
-        if transparency >= Transparency::SemiTransparent {
-            let parent = opaque_and_semitransparent;
-            opaque_and_semitransparent = *self
-                .syntax_context_map
-                .entry((parent, expn_id, transparency))
-                .or_insert_with(|| {
-                    let new_opaque_and_semitransparent =
-                        SyntaxContext::from_usize(syntax_context_data.len());
-                    syntax_context_data.push(SyntaxContextData {
-                        outer_expn: expn_id,
-                        outer_transparency: transparency,
-                        parent,
-                        opaque,
-                        opaque_and_semitransparent: new_opaque_and_semitransparent,
-                        dollar_crate_name: kw::DollarCrate,
-                    });
-                    new_opaque_and_semitransparent
-                });
+        // Look into the cache first.
+        let key = (parent, expn_id, transparency);
+        if let Some(ctxt) = self.syntax_context_map.get(&key) {
+            return *ctxt;
         }
 
-        let parent = ctxt;
-        *self.syntax_context_map.entry((parent, expn_id, transparency)).or_insert_with(|| {
-            syntax_context_data.push(SyntaxContextData {
-                outer_expn: expn_id,
-                outer_transparency: transparency,
-                parent,
-                opaque,
-                opaque_and_semitransparent,
-                dollar_crate_name: kw::DollarCrate,
-            });
-            SyntaxContext::from_usize(syntax_context_data.len() - 1)
-        })
+        // Reserve a new syntax context.
+        let ctxt = SyntaxContext::from_usize(self.syntax_context_data.len());
+        self.syntax_context_data.push(SyntaxContextData::decode_placeholder());
+        self.syntax_context_map.insert(key, ctxt);
+
+        // Opaque and semi-transparent versions of the parent. Note that they may be equal to the
+        // parent itself. E.g. `parent_opaque` == `parent` if the expn chain contains only opaques,
+        // and `parent_opaque_and_semitransparent` == `parent` if the expn contains only opaques
+        // and semi-transparents.
+        let parent_opaque = self.syntax_context_data[parent.0 as usize].opaque;
+        let parent_opaque_and_semitransparent =
+            self.syntax_context_data[parent.0 as usize].opaque_and_semitransparent;
+
+        // Evaluate opaque and semi-transparent versions of the new syntax context.
+        let (opaque, opaque_and_semitransparent) = match transparency {
+            Transparency::Transparent => (parent_opaque, parent_opaque_and_semitransparent),
+            Transparency::SemiTransparent => (
+                parent_opaque,
+                // Will be the same as `ctxt` if the expn chain contains only opaques and semi-transparents.
+                self.alloc_ctxt(parent_opaque_and_semitransparent, expn_id, transparency),
+            ),
+            Transparency::Opaque => (
+                // Will be the same as `ctxt` if the expn chain contains only opaques.
+                self.alloc_ctxt(parent_opaque, expn_id, transparency),
+                // Will be the same as `ctxt` if the expn chain contains only opaques and semi-transparents.
+                self.alloc_ctxt(parent_opaque_and_semitransparent, expn_id, transparency),
+            ),
+        };
+
+        // Fill the full data, now that we have it.
+        self.syntax_context_data[ctxt.as_u32() as usize] =
+            SyntaxContextData::new(key, opaque, opaque_and_semitransparent);
+        ctxt
+    }
+
+    fn non_recursive_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContextDataNonRecursive {
+        debug_assert!(!self.syntax_context_data[ctxt.0 as usize].is_decode_placeholder());
+        let data = &self.syntax_context_data[ctxt.0 as usize];
+        SyntaxContextDataNonRecursive {
+            outer_expn: data.outer_expn,
+            outer_transparency: data.outer_transparency,
+            parent: data.parent,
+            opaque: (data.opaque != ctxt).then_some(data.opaque),
+            opaque_and_semitransparent: (data.opaque_and_semitransparent != ctxt)
+                .then_some(data.opaque_and_semitransparent),
+        }
     }
 }
 
@@ -1265,7 +1300,7 @@ impl HygieneEncodeContext {
     pub fn encode<T>(
         &self,
         encoder: &mut T,
-        mut encode_ctxt: impl FnMut(&mut T, u32, &SyntaxContextData),
+        mut encode_ctxt: impl FnMut(&mut T, u32, &SyntaxContextDataNonRecursive),
         mut encode_expn: impl FnMut(&mut T, ExpnId, &ExpnData, ExpnHash),
     ) {
         // When we serialize a `SyntaxContextData`, we may end up serializing
@@ -1314,18 +1349,12 @@ struct HygieneDecodeContextInner {
     // so that multiple occurrences of the same serialized id are decoded to the same
     // `SyntaxContext`. This only stores `SyntaxContext`s which are completely decoded.
     remapped_ctxts: Vec<Option<SyntaxContext>>,
-
-    /// Maps serialized `SyntaxContext` ids that are currently being decoded to a `SyntaxContext`.
-    decoding: FxHashMap<u32, SyntaxContext>,
 }
 
 #[derive(Default)]
 /// Additional information used to assist in decoding hygiene data
 pub struct HygieneDecodeContext {
     inner: Lock<HygieneDecodeContextInner>,
-
-    /// A set of serialized `SyntaxContext` ids that are currently being decoded on each thread.
-    local_in_progress: WorkerLocal<RefCell<FxHashSet<u32>>>,
 }
 
 /// Register an expansion which has been decoded from the on-disk-cache for the local crate.
@@ -1396,7 +1425,10 @@ pub fn decode_expn_id(
 // to track which `SyntaxContext`s we have already decoded.
 // The provided closure will be invoked to deserialize a `SyntaxContextData`
 // if we haven't already seen the id of the `SyntaxContext` we are deserializing.
-pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContextData>(
+pub fn decode_syntax_context<
+    D: Decoder,
+    F: FnOnce(&mut D, u32) -> SyntaxContextDataNonRecursive,
+>(
     d: &mut D,
     context: &HygieneDecodeContext,
     decode_data: F,
@@ -1408,112 +1440,43 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
         return SyntaxContext::root();
     }
 
-    let pending_ctxt = {
-        let mut inner = context.inner.lock();
-
-        // Reminder: `HygieneDecodeContext` is per-crate, so there are no collisions between
-        // raw ids from different crate metadatas.
-        if let Some(ctxt) = inner.remapped_ctxts.get(raw_id as usize).copied().flatten() {
-            // This has already been decoded.
-            return ctxt;
-        }
-
-        match inner.decoding.entry(raw_id) {
-            Entry::Occupied(ctxt_entry) => {
-                let pending_ctxt = *ctxt_entry.get();
-                match context.local_in_progress.borrow_mut().entry(raw_id) {
-                    // We're decoding this already on the current thread. Return here and let the
-                    // function higher up the stack finish decoding to handle recursive cases.
-                    // Hopefully having a `SyntaxContext` that refers to an incorrect data is ok
-                    // during reminder of the decoding process, it's certainly not ok after the
-                    // top level decoding function returns.
-                    SetEntry::Occupied(..) => return pending_ctxt,
-                    // Some other thread is currently decoding this.
-                    // Race with it (alternatively we could wait here).
-                    // We cannot return this value, unlike in the recursive case above, because it
-                    // may expose a `SyntaxContext` pointing to incorrect data to arbitrary code.
-                    SetEntry::Vacant(entry) => {
-                        entry.insert();
-                        pending_ctxt
-                    }
-                }
-            }
-            Entry::Vacant(entry) => {
-                // We are the first thread to start decoding. Mark the current thread as being progress.
-                context.local_in_progress.borrow_mut().insert(raw_id);
-
-                // Allocate and store SyntaxContext id *before* calling the decoder function,
-                // as the SyntaxContextData may reference itself.
-                let new_ctxt = HygieneData::with(|hygiene_data| {
-                    // Push a dummy SyntaxContextData to ensure that nobody else can get the
-                    // same ID as us. This will be overwritten after call `decode_data`.
-                    hygiene_data.syntax_context_data.push(SyntaxContextData::decode_placeholder());
-                    SyntaxContext::from_usize(hygiene_data.syntax_context_data.len() - 1)
-                });
-                entry.insert(new_ctxt);
-                new_ctxt
-            }
-        }
-    };
+    // Reminder: `HygieneDecodeContext` is per-crate, so there are no collisions between
+    // raw ids from different crate metadatas.
+    if let Some(ctxt) = context.inner.lock().remapped_ctxts.get(raw_id as usize).copied().flatten()
+    {
+        // This has already been decoded.
+        return ctxt;
+    }
 
     // Don't try to decode data while holding the lock, since we need to
     // be able to recursively decode a SyntaxContext
     let ctxt_data = decode_data(d, raw_id);
-    let ctxt_key = ctxt_data.key();
 
     let ctxt = HygieneData::with(|hygiene_data| {
-        match hygiene_data.syntax_context_map.get(&ctxt_key) {
-            // Ensure that syntax contexts are unique.
-            // If syntax contexts with the given key already exists, reuse it instead of
-            // using `pending_ctxt`.
-            // `pending_ctxt` will leave an unused hole in the vector of syntax contexts.
-            // Hopefully its value isn't stored anywhere during decoding and its dummy data
-            // is never accessed later. The `is_decode_placeholder` asserts on all
-            // accesses to syntax context data attempt to ensure it.
-            Some(&ctxt) => ctxt,
-            // This is a completely new context.
-            // Overwrite its placeholder data with our decoded data.
-            None => {
-                let ctxt_data_ref =
-                    &mut hygiene_data.syntax_context_data[pending_ctxt.as_u32() as usize];
-                let prev_ctxt_data = mem::replace(ctxt_data_ref, ctxt_data);
-                // Reset `dollar_crate_name` so that it will be updated by `update_dollar_crate_names`.
-                // We don't care what the encoding crate set this to - we want to resolve it
-                // from the perspective of the current compilation session.
-                ctxt_data_ref.dollar_crate_name = kw::DollarCrate;
-                // Make sure nothing weird happened while `decode_data` was running.
-                if !prev_ctxt_data.is_decode_placeholder() {
-                    // Another thread may have already inserted the decoded data,
-                    // but the decoded data should match.
-                    assert_eq!(prev_ctxt_data, *ctxt_data_ref);
-                }
-                hygiene_data.syntax_context_map.insert(ctxt_key, pending_ctxt);
-                pending_ctxt
-            }
-        }
+        let ctxt_key = (ctxt_data.parent, ctxt_data.outer_expn, ctxt_data.outer_transparency);
+        *hygiene_data.syntax_context_map.entry(ctxt_key).or_insert_with(|| {
+            let ctxt = SyntaxContext::from_usize(hygiene_data.syntax_context_data.len());
+            hygiene_data.syntax_context_data.push(ctxt_data.recursive(ctxt));
+            ctxt
+        })
     });
 
-    // Mark the context as completed
-    context.local_in_progress.borrow_mut().remove(&raw_id);
-
     let mut inner = context.inner.lock();
     let new_len = raw_id as usize + 1;
     if inner.remapped_ctxts.len() < new_len {
         inner.remapped_ctxts.resize(new_len, None);
     }
     inner.remapped_ctxts[raw_id as usize] = Some(ctxt);
-    inner.decoding.remove(&raw_id);
 
     ctxt
 }
 
-fn for_all_ctxts_in<F: FnMut(u32, SyntaxContext, &SyntaxContextData)>(
+fn for_all_ctxts_in<F: FnMut(u32, SyntaxContext, &SyntaxContextDataNonRecursive)>(
     ctxts: impl Iterator<Item = SyntaxContext>,
     mut f: F,
 ) {
-    let all_data: Vec<_> = HygieneData::with(|data| {
-        ctxts.map(|ctxt| (ctxt, data.syntax_context_data[ctxt.0 as usize].clone())).collect()
-    });
+    let all_data: Vec<_> =
+        HygieneData::with(|data| ctxts.map(|ctxt| (ctxt, data.non_recursive_ctxt(ctxt))).collect());
     for (ctxt, data) in all_data.into_iter() {
         f(ctxt.0, ctxt, &data);
     }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index f19d4d9f362..9e6ba2e1b9c 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -876,7 +876,7 @@ impl Span {
         self.ctxt()
             .outer_expn_data()
             .allow_internal_unstable
-            .is_some_and(|features| features.iter().any(|&f| f == feature))
+            .is_some_and(|features| features.contains(&feature))
     }
 
     /// Checks if this span arises from a compiler desugaring of kind `kind`.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 6807f96e712..31847ae3b46 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -131,7 +131,7 @@ symbols! {
         // tidy-alphabetical-end
 
         // Weak keywords, have special meaning only in specific contexts.
-        // Matching predicates: none
+        // Matching predicates: `is_weak`
         // tidy-alphabetical-start
         Auto:               "auto",
         Builtin:            "builtin",
@@ -800,6 +800,15 @@ symbols! {
         default_fn,
         default_lib_allocator,
         default_method_body_is_const,
+        // --------------------------
+        // Lang items which are used only for experiments with auto traits with default bounds.
+        // These lang items are not actually defined in core/std. Experiment is a part of
+        // `MCP: Low level components for async drop`(https://github.com/rust-lang/compiler-team/issues/727)
+        default_trait1,
+        default_trait2,
+        default_trait3,
+        default_trait4,
+        // --------------------------
         default_type_parameter_fallback,
         default_type_params,
         define_opaque,
@@ -986,6 +995,7 @@ symbols! {
         field_init_shorthand,
         file,
         file_options,
+        flags,
         float,
         float_to_int_unchecked,
         floorf128,
@@ -1377,6 +1387,7 @@ symbols! {
         movbe_target_feature,
         move_ref_pattern,
         move_size_limit,
+        movrs_target_feature,
         mul,
         mul_assign,
         mul_with_overflow,
@@ -1570,6 +1581,7 @@ symbols! {
         pointer_like,
         poll,
         poll_next,
+        position,
         post_dash_lto: "post-lto",
         postfix_match,
         powerpc_target_feature,
@@ -1585,6 +1597,7 @@ symbols! {
         precise_capturing,
         precise_capturing_in_traits,
         precise_pointer_size_matching,
+        precision,
         pref_align_of,
         prefetch_read_data,
         prefetch_read_instruction,
@@ -1771,6 +1784,7 @@ symbols! {
         rustc_deallocator,
         rustc_def_path,
         rustc_default_body_unstable,
+        rustc_delayed_bug_from_inside_query,
         rustc_deny_explicit_impl,
         rustc_deprecated_safe_2024,
         rustc_diagnostic_item,
@@ -1787,7 +1801,6 @@ symbols! {
         rustc_dump_user_args,
         rustc_dump_vtable,
         rustc_effective_visibility,
-        rustc_error,
         rustc_evaluate_where_clauses,
         rustc_expected_cgu_reuse,
         rustc_force_inline,
@@ -2036,6 +2049,7 @@ symbols! {
         sub_assign,
         sub_with_overflow,
         suggestion,
+        super_let,
         supertrait_item_shadowing,
         surface_async_drop_in_place,
         sym,
@@ -2274,6 +2288,7 @@ symbols! {
         wasm_target_feature,
         where_clause_attrs,
         while_let,
+        width,
         windows,
         windows_subsystem,
         with_negative_coherence,
@@ -2721,6 +2736,10 @@ impl Symbol {
             || self.is_unused_keyword_conditional(edition)
     }
 
+    pub fn is_weak(self) -> bool {
+        self >= kw::Auto && self <= kw::Yeet
+    }
+
     /// A keyword or reserved identifier that can be used as a path segment.
     pub fn is_path_segment_keyword(self) -> bool {
         self == kw::Super
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 88754f1f15b..2802e891807 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -28,7 +28,10 @@ pub(super) fn mangle<'tcx>(
     loop {
         let key = tcx.def_key(ty_def_id);
         match key.disambiguated_data.data {
-            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) | DefPathData::Closure => {
+            DefPathData::TypeNs(_)
+            | DefPathData::ValueNs(_)
+            | DefPathData::Closure
+            | DefPathData::SyntheticCoroutineBody => {
                 instance_ty = tcx.type_of(ty_def_id).instantiate_identity();
                 debug!(?instance_ty);
                 break;
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index d824a23279b..99d44bcd7eb 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -850,6 +850,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             DefPathData::Ctor => 'c',
             DefPathData::AnonConst => 'k',
             DefPathData::OpaqueTy => 'i',
+            DefPathData::SyntheticCoroutineBody => 's',
 
             // These should never show up as `path_append` arguments.
             DefPathData::CrateRoot
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index cdccb3e5d72..43a8d9ca119 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -78,7 +78,7 @@ pub(crate) fn target_reserves_x18(target: &Target, target_features: &FxIndexSet<
     target.os == "android"
         || target.os == "fuchsia"
         || target.env == "ohos"
-        || target.is_like_osx
+        || target.is_like_darwin
         || target.is_like_windows
         || target_features.contains(&sym::reserve_x18)
 }
diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index ff0cbddecf7..7fea10ff067 100644
--- a/compiler/rustc_target/src/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
@@ -68,7 +68,7 @@ impl ArmInlineAsmRegClass {
 
 // This uses the same logic as useR7AsFramePointer in LLVM
 fn frame_pointer_is_r7(target_features: &FxIndexSet<Symbol>, target: &Target) -> bool {
-    target.is_like_osx || (!target.is_like_windows && target_features.contains(&sym::thumb_mode))
+    target.is_like_darwin || (!target.is_like_windows && target_features.contains(&sym::thumb_mode))
 }
 
 fn frame_pointer_r11(
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index a52b2b76bc1..55e39d093e2 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -670,7 +670,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
                 }
             },
             "aarch64" | "arm64ec" => {
-                let kind = if cx.target_spec().is_like_osx {
+                let kind = if cx.target_spec().is_like_darwin {
                     aarch64::AbiKind::DarwinPCS
                 } else if cx.target_spec().is_like_windows {
                     aarch64::AbiKind::Win64
diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs
index 6f112b49400..ba3c1406211 100644
--- a/compiler/rustc_target/src/callconv/x86.rs
+++ b/compiler/rustc_target/src/callconv/x86.rs
@@ -104,7 +104,7 @@ where
             let byval_align = if arg.layout.align.abi < align_4 {
                 // (1.)
                 align_4
-            } else if t.is_like_osx && contains_vector(cx, arg.layout) {
+            } else if t.is_like_darwin && contains_vector(cx, arg.layout) {
                 // (3.)
                 align_16
             } else {
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index a8d7da5692d..df99280f571 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -12,6 +12,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
+#![feature(debug_closure_helpers)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(rustc_attrs)]
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index 66c85146c29..46fcd7d5c51 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -1,9 +1,12 @@
 use std::borrow::Cow;
 use std::env;
+use std::fmt::{Display, from_fn};
+use std::num::ParseIntError;
+use std::str::FromStr;
 
 use crate::spec::{
     BinaryFormat, Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi,
-    SplitDebuginfo, StackProbeType, StaticCow, TargetOptions, cvs,
+    SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions, cvs,
 };
 
 #[cfg(test)]
@@ -115,7 +118,7 @@ pub(crate) fn base(
         function_sections: false,
         dynamic_linking: true,
         families: cvs!["unix"],
-        is_like_osx: true,
+        is_like_darwin: true,
         binary_format: BinaryFormat::MachO,
         // LLVM notes that macOS 10.11+ and iOS 9+ default
         // to v4, so we do the same.
@@ -222,3 +225,107 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
         cvs!["MACOSX_DEPLOYMENT_TARGET"]
     }
 }
+
+/// Deployment target or SDK version.
+///
+/// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct OSVersion {
+    pub major: u16,
+    pub minor: u8,
+    pub patch: u8,
+}
+
+impl FromStr for OSVersion {
+    type Err = ParseIntError;
+
+    /// Parse an OS version triple (SDK version or deployment target).
+    fn from_str(version: &str) -> Result<Self, ParseIntError> {
+        if let Some((major, minor)) = version.split_once('.') {
+            let major = major.parse()?;
+            if let Some((minor, patch)) = minor.split_once('.') {
+                Ok(Self { major, minor: minor.parse()?, patch: patch.parse()? })
+            } else {
+                Ok(Self { major, minor: minor.parse()?, patch: 0 })
+            }
+        } else {
+            Ok(Self { major: version.parse()?, minor: 0, patch: 0 })
+        }
+    }
+}
+
+impl OSVersion {
+    pub fn new(major: u16, minor: u8, patch: u8) -> Self {
+        Self { major, minor, patch }
+    }
+
+    pub fn fmt_pretty(self) -> impl Display {
+        let Self { major, minor, patch } = self;
+        from_fn(move |f| {
+            write!(f, "{major}.{minor}")?;
+            if patch != 0 {
+                write!(f, ".{patch}")?;
+            }
+            Ok(())
+        })
+    }
+
+    pub fn fmt_full(self) -> impl Display {
+        let Self { major, minor, patch } = self;
+        from_fn(move |f| write!(f, "{major}.{minor}.{patch}"))
+    }
+
+    /// Minimum operating system versions currently supported by `rustc`.
+    pub fn os_minimum_deployment_target(os: &str) -> Self {
+        // When bumping a version in here, remember to update the platform-support docs too.
+        //
+        // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the
+        // default deployment target, prefer:
+        // ```
+        // $ rustc --print deployment-target
+        // ```
+        let (major, minor, patch) = match os {
+            "macos" => (10, 12, 0),
+            "ios" => (10, 0, 0),
+            "tvos" => (10, 0, 0),
+            "watchos" => (5, 0, 0),
+            "visionos" => (1, 0, 0),
+            _ => unreachable!("tried to get deployment target for non-Apple platform"),
+        };
+        Self { major, minor, patch }
+    }
+
+    /// The deployment target for the given target.
+    ///
+    /// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense
+    /// to raise the minimum OS version.
+    ///
+    /// This matches what LLVM does, see in part:
+    /// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
+    pub fn minimum_deployment_target(target: &Target) -> Self {
+        let (major, minor, patch) = match (&*target.os, &*target.arch, &*target.abi) {
+            ("macos", "aarch64", _) => (11, 0, 0),
+            ("ios", "aarch64", "macabi") => (14, 0, 0),
+            ("ios", "aarch64", "sim") => (14, 0, 0),
+            ("ios", _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0),
+            // Mac Catalyst defaults to 13.1 in Clang.
+            ("ios", _, "macabi") => (13, 1, 0),
+            ("tvos", "aarch64", "sim") => (14, 0, 0),
+            ("watchos", "aarch64", "sim") => (7, 0, 0),
+            (os, _, _) => return Self::os_minimum_deployment_target(os),
+        };
+        Self { major, minor, patch }
+    }
+}
+
+/// Name of the environment variable used to fetch the deployment target on the given OS.
+pub fn deployment_target_env_var(os: &str) -> &'static str {
+    match os {
+        "macos" => "MACOSX_DEPLOYMENT_TARGET",
+        "ios" => "IPHONEOS_DEPLOYMENT_TARGET",
+        "watchos" => "WATCHOS_DEPLOYMENT_TARGET",
+        "tvos" => "TVOS_DEPLOYMENT_TARGET",
+        "visionos" => "XROS_DEPLOYMENT_TARGET",
+        _ => unreachable!("tried to get deployment target env var for non-Apple platform"),
+    }
+}
diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs
index 7a985ad4dc0..391f3470104 100644
--- a/compiler/rustc_target/src/spec/base/apple/tests.rs
+++ b/compiler/rustc_target/src/spec/base/apple/tests.rs
@@ -1,3 +1,4 @@
+use super::OSVersion;
 use crate::spec::targets::{
     aarch64_apple_darwin, aarch64_apple_ios_sim, aarch64_apple_visionos_sim,
     aarch64_apple_watchos_sim, i686_apple_darwin, x86_64_apple_darwin, x86_64_apple_ios,
@@ -42,3 +43,11 @@ fn macos_link_environment_unmodified() {
         );
     }
 }
+
+#[test]
+fn test_parse_version() {
+    assert_eq!("10".parse(), Ok(OSVersion::new(10, 0, 0)));
+    assert_eq!("10.12".parse(), Ok(OSVersion::new(10, 12, 0)));
+    assert_eq!("10.12.6".parse(), Ok(OSVersion::new(10, 12, 6)));
+    assert_eq!("9999.99.99".parse(), Ok(OSVersion::new(9999, 99, 99)));
+}
diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs
index e8fdc871785..71b6528c2dd 100644
--- a/compiler/rustc_target/src/spec/base/mod.rs
+++ b/compiler/rustc_target/src/spec/base/mod.rs
@@ -1,6 +1,6 @@
 pub(crate) mod aix;
 pub(crate) mod android;
-pub(crate) mod apple;
+pub mod apple;
 pub(crate) mod avr;
 pub(crate) mod bpf;
 pub(crate) mod cygwin;
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index 4b6de5e18f5..be71da76b4a 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -598,7 +598,7 @@ impl Target {
         key!(families, target_families);
         key!(abi_return_struct_as_int, bool);
         key!(is_like_aix, bool);
-        key!(is_like_osx, bool);
+        key!(is_like_darwin, bool);
         key!(is_like_solaris, bool);
         key!(is_like_windows, bool);
         key!(is_like_msvc, bool);
@@ -777,7 +777,7 @@ impl ToJson for Target {
         target_option_val!(families, "target-family");
         target_option_val!(abi_return_struct_as_int);
         target_option_val!(is_like_aix);
-        target_option_val!(is_like_osx);
+        target_option_val!(is_like_darwin);
         target_option_val!(is_like_solaris);
         target_option_val!(is_like_windows);
         target_option_val!(is_like_msvc);
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 7234d1dc63e..79f73ef28b3 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -60,6 +60,7 @@ pub mod crt_objects;
 mod base;
 mod json;
 
+pub use base::apple;
 pub use base::avr::ef_avr_arch;
 
 /// Linker is called through a C/C++ compiler.
@@ -81,7 +82,7 @@ pub enum Lld {
 /// of classes that we call "linker flavors".
 ///
 /// Technically, it's not even necessary, we can nearly always infer the flavor from linker name
-/// and target properties like `is_like_windows`/`is_like_osx`/etc. However, the PRs originally
+/// and target properties like `is_like_windows`/`is_like_darwin`/etc. However, the PRs originally
 /// introducing `-Clinker-flavor` (#40018 and friends) were aiming to reduce this kind of inference
 /// and provide something certain and explicitly specified instead, and that design goal is still
 /// relevant now.
@@ -2406,7 +2407,7 @@ pub struct TargetOptions {
     /// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
     /// Also indicates whether to use Apple-specific ABI changes, such as extending function
     /// parameters to 32-bits.
-    pub is_like_osx: bool,
+    pub is_like_darwin: bool,
     /// Whether the target toolchain is like Solaris's.
     /// Only useful for compiling against Illumos/Solaris,
     /// as they have a different set of linker flags. Defaults to false.
@@ -2700,7 +2701,7 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
 impl TargetOptions {
     pub fn supports_comdat(&self) -> bool {
         // XCOFF and MachO don't support COMDAT.
-        !self.is_like_aix && !self.is_like_osx
+        !self.is_like_aix && !self.is_like_darwin
     }
 }
 
@@ -2804,7 +2805,7 @@ impl Default for TargetOptions {
             families: cvs![],
             abi_return_struct_as_int: false,
             is_like_aix: false,
-            is_like_osx: false,
+            is_like_darwin: false,
             is_like_solaris: false,
             is_like_windows: false,
             is_like_msvc: false,
@@ -3070,9 +3071,9 @@ impl Target {
         }
 
         check_eq!(
-            self.is_like_osx,
+            self.is_like_darwin,
             self.vendor == "apple",
-            "`is_like_osx` must be set if and only if `vendor` is `apple`"
+            "`is_like_darwin` must be set if and only if `vendor` is `apple`"
         );
         check_eq!(
             self.is_like_solaris,
@@ -3098,9 +3099,9 @@ impl Target {
 
         // Check that default linker flavor is compatible with some other key properties.
         check_eq!(
-            self.is_like_osx,
+            self.is_like_darwin,
             matches!(self.linker_flavor, LinkerFlavor::Darwin(..)),
-            "`linker_flavor` must be `darwin` if and only if `is_like_osx` is set"
+            "`linker_flavor` must be `darwin` if and only if `is_like_darwin` is set"
         );
         check_eq!(
             self.is_like_msvc,
@@ -3516,7 +3517,7 @@ impl Target {
                     Err("the `i586-pc-windows-msvc` target has been removed. Use the `i686-pc-windows-msvc` target instead.\n\
                         Windows 10 (the minimum required OS version) requires a CPU baseline of at least i686 so you can safely switch".into())
                 } else {
-                    Err(format!("Could not find specification for target {target_tuple:?}"))
+                    Err(format!("could not find specification for target {target_tuple:?}"))
                 }
             }
             TargetTuple::TargetJson { ref contents, .. } => {
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs
index dbe1540364a..860629b08e1 100644
--- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs
@@ -2,7 +2,7 @@ use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     Target {
-        llvm_target: "armv5te-unknown-linux-uclibcgnueabi".into(),
+        llvm_target: "armv5te-unknown-linux-gnueabi".into(),
         metadata: TargetMetadata {
             description: Some("Armv5TE Linux with uClibc".into()),
             tier: Some(3),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
index 5d292bbf8ad..6a83835059e 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
     );
 
     Target {
-        llvm_target: "thumbv7a-vita-eabihf".into(),
+        llvm_target: "thumbv7a-sony-vita-eabihf".into(),
         metadata: TargetMetadata {
             description: Some(
                 "Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)".into(),
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
index 2a26323e514..e775c8fc524 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
@@ -20,7 +20,7 @@ pub(crate) fn target() -> Target {
         llvm_target: "i686-pc-windows-gnu".into(),
         metadata: TargetMetadata {
             description: Some("32-bit MinGW (Windows 10+)".into()),
-            tier: Some(1),
+            tier: Some(2),
             host_tools: Some(true),
             std: Some(true),
         },
diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
index 1300280e35b..71b3fbe00b2 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
@@ -23,6 +23,7 @@ pub(crate) fn target() -> Target {
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
         arch: "mips64".into(),
         options: TargetOptions {
+            vendor: "openwrt".into(),
             abi: "abi64".into(),
             endian: Endian::Big,
             mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
index 0955b3debea..c14bfbf46d2 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
@@ -4,7 +4,7 @@ use crate::spec::{Target, TargetMetadata, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     Target {
-        llvm_target: "mips-unknown-linux-uclibc".into(),
+        llvm_target: "mips-unknown-linux-gnu".into(),
         metadata: TargetMetadata {
             description: Some("MIPS Linux with uClibc".into()),
             tier: Some(3),
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs
index 08c4347fe01..f0056799d66 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs
@@ -2,7 +2,7 @@ use crate::spec::{Target, TargetMetadata, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     Target {
-        llvm_target: "mipsel-unknown-linux-uclibc".into(),
+        llvm_target: "mipsel-unknown-linux-gnu".into(),
         metadata: TargetMetadata {
             description: Some("MIPS (LE) Linux with uClibc".into()),
             tier: Some(3),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
index 8a4bc58e546..efc17d8d083 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
@@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv32".into(),
             llvm_abiname: "ilp32d".into(),
             max_atomic_width: Some(32),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             stack_probes: StackProbeType::Inline,
             ..base::vxworks::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs
index 6dda346aaaf..5b7feef70d0 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs
@@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv32".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             llvm_abiname: "ilp32d".into(),
             max_atomic_width: Some(32),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
index ba10e3c6881..938b39b10c6 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
@@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv32".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             llvm_abiname: "ilp32d".into(),
             max_atomic_width: Some(32),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs
index c8ef737b9e7..9f02ed4bcbe 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs
@@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c,+zba,+zbb,+zbs,+v".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei,+zba,+zbb,+zbs,+v".into(),
             llvm_abiname: "lp64d".into(),
             supported_sanitizers: SanitizerSet::ADDRESS,
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
index 39aa70035e4..8d8c21952de 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
@@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
             cpu: "generic-rv64".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             stack_probes: StackProbeType::Inline,
             ..base::vxworks::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs
index ecf65677531..e628095b88a 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             ..base::freebsd::opts()
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
index e260237ca77..c4466e13d14 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
@@ -4,7 +4,7 @@ pub(crate) fn target() -> Target {
     let mut base = base::fuchsia::opts();
     base.code_model = Some(CodeModel::Medium);
     base.cpu = "generic-rv64".into();
-    base.features = "+m,+a,+f,+d,+c".into();
+    base.features = "+m,+a,+f,+d,+c,+zicsr,+zifencei".into();
     base.llvm_abiname = "lp64d".into();
     base.max_atomic_width = Some(64);
     base.stack_probes = StackProbeType::Inline;
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs
index 88b5dca284a..5c15bdd9f64 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs
@@ -14,7 +14,7 @@ pub(crate) fn target() -> Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         options: TargetOptions {
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             relocation_model: RelocModel::Pic,
             code_model: Some(CodeModel::Medium),
             tls_model: TlsModel::LocalExec,
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs
index 8ffb622511d..af2f42fa00a 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs
@@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
index 33b08fdcb05..70c19952af0 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
@@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs
index 2b647e36f18..1f359d1e7fe 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             mcount: "__mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs
index d6f0a5499b9..5a5aad93efb 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs
@@ -22,7 +22,7 @@ pub(crate) fn target() -> Target {
             llvm_abiname: "lp64d".into(),
             cpu: "generic-rv64".into(),
             max_atomic_width: Some(64),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs
index bc6829897a4..e8abc926dd0 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs
@@ -24,7 +24,7 @@ pub(crate) fn target() -> Target {
             llvm_abiname: "lp64d".into(),
             cpu: "generic-rv64".into(),
             max_atomic_width: Some(64),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs
index 75f508d8e93..85d7dfe7865 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             ..base::openbsd::opts()
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs
index a034a9fb244..4107249dcf1 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs
@@ -8,7 +8,7 @@ pub(crate) fn target() -> Target {
     base.panic_strategy = PanicStrategy::Abort;
 
     Target {
-        llvm_target: "x86_64-unknown-l4re-uclibc".into(),
+        llvm_target: "x86_64-unknown-l4re-gnu".into(),
         metadata: TargetMetadata {
             description: None,
             tier: Some(3),
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index a96caf227f7..b4ec1879fed 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -380,11 +380,16 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
     ("adx", Stable, &[]),
     ("aes", Stable, &["sse2"]),
+    ("amx-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
     ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
     ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
     ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("amx-fp8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
     ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
     ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
+    ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
     ("avx", Stable, &["sse4.2"]),
     ("avx2", Stable, &["avx"]),
     ("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]),
@@ -418,6 +423,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
     ("lzcnt", Stable, &[]),
     ("movbe", Stable, &[]),
+    ("movrs", Unstable(sym::movrs_target_feature), &[]),
     ("pclmulqdq", Stable, &["sse2"]),
     ("popcnt", Stable, &[]),
     ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
@@ -488,7 +494,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("c", Stable, &[]),
     ("d", Unstable(sym::riscv_target_feature), &["f"]),
     ("e", Unstable(sym::riscv_target_feature), &[]),
-    ("f", Unstable(sym::riscv_target_feature), &[]),
+    ("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
     (
         "forced-atomics",
         Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
@@ -497,7 +503,8 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("m", Stable, &[]),
     ("relax", Unstable(sym::riscv_target_feature), &[]),
     ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
-    ("v", Unstable(sym::riscv_target_feature), &[]),
+    ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]),
+    ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]),
     ("za128rs", Unstable(sym::riscv_target_feature), &[]),
     ("za64rs", Unstable(sym::riscv_target_feature), &[]),
     ("zaamo", Unstable(sym::riscv_target_feature), &[]),
@@ -516,19 +523,59 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
     ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
     ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
-    ("zfinx", Unstable(sym::riscv_target_feature), &[]),
+    ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
     ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
     ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
+    ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
+    ("zicsr", Unstable(sym::riscv_target_feature), &[]),
+    ("zifencei", Unstable(sym::riscv_target_feature), &[]),
+    ("zihintpause", Unstable(sym::riscv_target_feature), &[]),
+    ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
     ("zk", Stable, &["zkn", "zkr", "zkt"]),
     ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
     ("zknd", Stable, &[]),
     ("zkne", Stable, &[]),
     ("zknh", Stable, &[]),
-    ("zkr", Stable, &[]),
+    ("zkr", Stable, &["zicsr"]),
     ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
     ("zksed", Stable, &[]),
     ("zksh", Stable, &[]),
     ("zkt", Stable, &[]),
+    ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]),
+    ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
+    ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
+    ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
+    ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
+    ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
+    ("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]),
+    ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zfhmin"]),
+    ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
+    ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]),
+    ("zvkg", Unstable(sym::riscv_target_feature), &["zve32x"]),
+    ("zvkn", Unstable(sym::riscv_target_feature), &["zvkned", "zvknhb", "zvkb", "zvkt"]),
+    ("zvknc", Unstable(sym::riscv_target_feature), &["zvkn", "zvbc"]),
+    ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]),
+    ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]),
+    ("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]),
+    ("zvknhb", Unstable(sym::riscv_target_feature), &["zve64x"]),
+    ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]),
+    ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]),
+    ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]),
+    ("zvksg", Unstable(sym::riscv_target_feature), &["zvks", "zvkg"]),
+    ("zvksh", Unstable(sym::riscv_target_feature), &["zve32x"]),
+    ("zvkt", Unstable(sym::riscv_target_feature), &[]),
+    ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]),
+    ("zvl128b", Unstable(sym::riscv_target_feature), &["zvl64b"]),
+    ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]),
+    ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]),
+    ("zvl256b", Unstable(sym::riscv_target_feature), &["zvl128b"]),
+    ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]),
+    ("zvl32b", Unstable(sym::riscv_target_feature), &[]),
+    ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]),
+    ("zvl512b", Unstable(sym::riscv_target_feature), &["zvl256b"]),
+    ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]),
+    ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]),
+    ("zvl8192b", Unstable(sym::riscv_target_feature), &["zvl4096b"]),
     // tidy-alphabetical-end
 ];
 
@@ -704,8 +751,20 @@ const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(1
 const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
 const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
 const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
-const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
-    &[/*(64, "zvl64b"), */ (128, "v")];
+const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
+    (32, "zvl32b"),
+    (64, "zvl64b"),
+    (128, "zvl128b"),
+    (256, "zvl256b"),
+    (512, "zvl512b"),
+    (1024, "zvl1024b"),
+    (2048, "zvl2048b"),
+    (4096, "zvl4096b"),
+    (8192, "zvl8192b"),
+    (16384, "zvl16384b"),
+    (32768, "zvl32768b"),
+    (65536, "zvl65536b"),
+];
 // Always warn on SPARC, as the necessary target features cannot be enabled in Rust at the moment.
 const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(64, "vis")*/];
 
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index 4db9d9915b1..05bbb42fb7c 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -264,8 +264,15 @@ trait_selection_oc_no_diverge = `else` clause of `let...else` does not diverge
 trait_selection_oc_no_else = `if` may be missing an `else` clause
 trait_selection_oc_try_compat = `?` operator has incompatible types
 trait_selection_oc_type_compat = type not compatible with trait
+
 trait_selection_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds
     .label = opaque type defined here
+trait_selection_opaque_type_non_generic_param =
+    expected generic {$kind} parameter, found `{$ty}`
+    .label = {STREQ($ty, "'static") ->
+        [true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+        *[other] this generic parameter must be used with a generic {$kind} parameter
+    }
 
 trait_selection_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type
 trait_selection_outlives_content = lifetime of reference outlives lifetime of borrowed content...
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index 0bcb5f6f3b2..f45e3904212 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -1051,7 +1051,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                             None?
                         }
                         let args = self.node_args_opt(expr.hir_id)?;
-                        let span = tcx.hir().span(segment.hir_id);
+                        let span = tcx.hir_span(segment.hir_id);
                         let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
                         InsertableGenericArgs {
                             insert_span,
@@ -1110,7 +1110,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                 if generics.has_impl_trait() {
                     return None;
                 }
-                let span = tcx.hir().span(segment.hir_id);
+                let span = tcx.hir_span(segment.hir_id);
                 let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
                 Some(InsertableGenericArgs {
                     insert_span,
@@ -1144,7 +1144,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                     if !segment.infer_args || generics.has_impl_trait() {
                         do yeet ();
                     }
-                    let span = tcx.hir().span(segment.hir_id);
+                    let span = tcx.hir_span(segment.hir_id);
                     let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
                     InsertableGenericArgs {
                         insert_span,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index 083ce022238..3559c660ee2 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -365,7 +365,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                 // obligation comes from the `impl`. Find that `impl` so that we can point
                 // at it in the suggestion.
                 let trait_did = trait_id.to_def_id();
-                tcx.hir_trait_impls(trait_did).iter().find_map(|&impl_did| {
+                tcx.local_trait_impls(trait_did).iter().find_map(|&impl_did| {
                     if let Node::Item(Item {
                         kind: ItemKind::Impl(hir::Impl { self_ty, .. }), ..
                     }) = tcx.hir_node_by_def_id(impl_did)
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs
index 00f053fa599..683b5b528c6 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs
@@ -51,7 +51,6 @@ pub fn find_param_with_region<'tcx>(
         _ => return None, // not a free region
     };
 
-    let hir = &tcx.hir();
     let def_id = id.as_local()?;
 
     // FIXME: use def_kind
@@ -93,7 +92,7 @@ pub fn find_param_with_region<'tcx>(
             });
             found_anon_region.then(|| {
                 let ty_hir_id = fn_decl.inputs[index].hir_id;
-                let param_ty_span = hir.span(ty_hir_id);
+                let param_ty_span = tcx.hir_span(ty_hir_id);
                 let is_first = index == 0;
                 AnonymousParamInfo { param, param_ty: new_param_ty, param_ty_span, kind, is_first }
             })
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 07a67cde3be..bc45fc11e9b 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -14,6 +14,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, LangItem, Node};
 use rustc_infer::infer::{InferOk, TypeTrace};
+use rustc_infer::traits::solve::Goal;
 use rustc_middle::traits::SignatureMismatchData;
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
@@ -930,7 +931,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             )) = arg.kind
             && let Node::Pat(pat) = self.tcx.hir_node(*hir_id)
             && let Some((preds, guar)) = self.reported_trait_errors.borrow().get(&pat.span)
-            && preds.contains(&obligation.predicate)
+            && preds.contains(&obligation.as_goal())
         {
             return Err(*guar);
         }
@@ -1236,7 +1237,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 );
                 // Only suggest derive if this isn't a derived obligation,
                 // and the struct is local.
-                if let Some(span) = self.tcx.hir().span_if_local(def.did())
+                if let Some(span) = self.tcx.hir_span_if_local(def.did())
                     && obligation.cause.code().parent().is_none()
                 {
                     if ty.is_structural_eq_shallow(self.tcx) {
@@ -1292,6 +1293,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     fn can_match_trait(
         &self,
+        param_env: ty::ParamEnv<'tcx>,
         goal: ty::TraitPredicate<'tcx>,
         assumption: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
@@ -1306,11 +1308,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             assumption,
         );
 
-        self.can_eq(ty::ParamEnv::empty(), goal.trait_ref, trait_assumption.trait_ref)
+        self.can_eq(param_env, goal.trait_ref, trait_assumption.trait_ref)
     }
 
     fn can_match_projection(
         &self,
+        param_env: ty::ParamEnv<'tcx>,
         goal: ty::ProjectionPredicate<'tcx>,
         assumption: ty::PolyProjectionPredicate<'tcx>,
     ) -> bool {
@@ -1320,7 +1323,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             assumption,
         );
 
-        let param_env = ty::ParamEnv::empty();
         self.can_eq(param_env, goal.projection_term, assumption.projection_term)
             && self.can_eq(param_env, goal.term, assumption.term)
     }
@@ -1330,24 +1332,32 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     #[instrument(level = "debug", skip(self), ret)]
     pub(super) fn error_implies(
         &self,
-        cond: ty::Predicate<'tcx>,
-        error: ty::Predicate<'tcx>,
+        cond: Goal<'tcx, ty::Predicate<'tcx>>,
+        error: Goal<'tcx, ty::Predicate<'tcx>>,
     ) -> bool {
         if cond == error {
             return true;
         }
 
-        if let Some(error) = error.as_trait_clause() {
+        // FIXME: We could be smarter about this, i.e. if cond's param-env is a
+        // subset of error's param-env. This only matters when binders will carry
+        // predicates though, and obviously only matters for error reporting.
+        if cond.param_env != error.param_env {
+            return false;
+        }
+        let param_env = error.param_env;
+
+        if let Some(error) = error.predicate.as_trait_clause() {
             self.enter_forall(error, |error| {
-                elaborate(self.tcx, std::iter::once(cond))
+                elaborate(self.tcx, std::iter::once(cond.predicate))
                     .filter_map(|implied| implied.as_trait_clause())
-                    .any(|implied| self.can_match_trait(error, implied))
+                    .any(|implied| self.can_match_trait(param_env, error, implied))
             })
-        } else if let Some(error) = error.as_projection_clause() {
+        } else if let Some(error) = error.predicate.as_projection_clause() {
             self.enter_forall(error, |error| {
-                elaborate(self.tcx, std::iter::once(cond))
+                elaborate(self.tcx, std::iter::once(cond.predicate))
                     .filter_map(|implied| implied.as_projection_clause())
-                    .any(|implied| self.can_match_projection(error, implied))
+                    .any(|implied| self.can_match_projection(param_env, error, implied))
             })
         } else {
             false
@@ -2943,7 +2953,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
 
         let found_node = found_did.and_then(|did| self.tcx.hir_get_if_local(did));
-        let found_span = found_did.and_then(|did| self.tcx.hir().span_if_local(did));
+        let found_span = found_did.and_then(|did| self.tcx.hir_span_if_local(did));
 
         if !self.reported_signature_mismatch.borrow_mut().insert((span, found_span)) {
             // We check closures twice, with obligations flowing in different directions,
@@ -3030,7 +3040,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         node: Node<'_>,
     ) -> Option<(Span, Option<Span>, Vec<ArgKind>)> {
         let sm = self.tcx.sess.source_map();
-        let hir = self.tcx.hir();
         Some(match node {
             Node::Expr(&hir::Expr {
                 kind: hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, fn_arg_span, .. }),
@@ -3086,7 +3095,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     .collect::<Vec<ArgKind>>(),
             ),
             Node::Ctor(variant_data) => {
-                let span = variant_data.ctor_hir_id().map_or(DUMMY_SP, |id| hir.span(id));
+                let span = variant_data.ctor_hir_id().map_or(DUMMY_SP, |id| self.tcx.hir_span(id));
                 (span, None, vec![ArgKind::empty(); variant_data.fields().len()])
             }
             _ => panic!("non-FnLike node found: {node:?}"),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index 98df09b6f7b..8ff7030717a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -12,6 +12,7 @@ use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_cod
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, AmbigArg, LangItem};
+use rustc_infer::traits::solve::Goal;
 use rustc_infer::traits::{
     DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode,
     PredicateObligation, SelectionError,
@@ -144,7 +145,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         #[derive(Debug)]
         struct ErrorDescriptor<'tcx> {
-            predicate: ty::Predicate<'tcx>,
+            goal: Goal<'tcx, ty::Predicate<'tcx>>,
             index: Option<usize>, // None if this is an old error
         }
 
@@ -152,15 +153,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             .reported_trait_errors
             .borrow()
             .iter()
-            .map(|(&span, predicates)| {
-                (
-                    span,
-                    predicates
-                        .0
-                        .iter()
-                        .map(|&predicate| ErrorDescriptor { predicate, index: None })
-                        .collect(),
-                )
+            .map(|(&span, goals)| {
+                (span, goals.0.iter().map(|&goal| ErrorDescriptor { goal, index: None }).collect())
             })
             .collect();
 
@@ -186,10 +180,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 span = expn_data.call_site;
             }
 
-            error_map.entry(span).or_default().push(ErrorDescriptor {
-                predicate: error.obligation.predicate,
-                index: Some(index),
-            });
+            error_map
+                .entry(span)
+                .or_default()
+                .push(ErrorDescriptor { goal: error.obligation.as_goal(), index: Some(index) });
         }
 
         // We do this in 2 passes because we want to display errors in order, though
@@ -210,9 +204,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             continue;
                         }
 
-                        if self.error_implies(error2.predicate, error.predicate)
+                        if self.error_implies(error2.goal, error.goal)
                             && !(error2.index >= error.index
-                                && self.error_implies(error.predicate, error2.predicate))
+                                && self.error_implies(error.goal, error2.goal))
                         {
                             info!("skipping {:?} (implied by {:?})", error, error2);
                             is_suppressed[index] = true;
@@ -243,7 +237,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         .entry(span)
                         .or_insert_with(|| (vec![], guar))
                         .0
-                        .push(error.obligation.predicate);
+                        .push(error.obligation.as_goal());
                 }
             }
         }
@@ -398,7 +392,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         );
 
         if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) {
-            if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
+            if let Some(span) = self.tcx.hir_span_if_local(trait_item_def_id) {
                 let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
                 err.span_label(span, format!("definition of `{item_name}` from trait"));
             }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index dc8022b95c3..38fcba4ea62 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1193,7 +1193,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             // FIXME(compiler-errors): This is kind of a mess, but required for obligations
             // that come from a path expr to affect the *call* expr.
             c @ ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, _)
-                if self.tcx.hir().span(*hir_id).lo() == span.lo() =>
+                if self.tcx.hir_span(*hir_id).lo() == span.lo() =>
             {
                 c
             }
@@ -4481,7 +4481,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             Obligation::new(self.tcx, obligation.cause.clone(), obligation.param_env, trait_ref);
 
         if self.predicate_must_hold_modulo_regions(&obligation) {
-            let arg_span = self.tcx.hir().span(*arg_hir_id);
+            let arg_span = self.tcx.hir_span(*arg_hir_id);
             err.multipart_suggestion_verbose(
                 format!("use a unary tuple instead"),
                 vec![(arg_span.shrink_to_lo(), "(".into()), (arg_span.shrink_to_hi(), ",)".into())],
@@ -4521,7 +4521,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     parent_code: _,
                 } = cause.code()
                 {
-                    let arg_span = self.tcx.hir().span(*arg_hir_id);
+                    let arg_span = self.tcx.hir_span(*arg_hir_id);
                     let mut sp: MultiSpan = arg_span.into();
 
                     sp.push_span_label(
@@ -4530,7 +4530,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         generic types that should be inferred from this argument",
                     );
                     sp.push_span_label(
-                        self.tcx.hir().span(*call_hir_id),
+                        self.tcx.hir_span(*call_hir_id),
                         "add turbofish arguments to this call to \
                         specify the types manually, even if it's redundant",
                     );
@@ -4939,7 +4939,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         .type_implements_trait(pred.def_id(), [rhs_ty, lhs_ty], param_env)
                         .must_apply_modulo_regions()
                 {
-                    let lhs_span = tcx.hir().span(lhs_hir_id);
+                    let lhs_span = tcx.hir_span(lhs_hir_id);
                     let sm = tcx.sess.source_map();
                     if let Ok(rhs_snippet) = sm.span_to_snippet(rhs_span)
                         && let Ok(lhs_snippet) = sm.span_to_snippet(lhs_span)
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index b30390a9330..9f7bfe5101a 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -12,7 +12,7 @@ use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty};
 use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, IsAnonInPath, Node};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
-use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, Region, Ty, TyCtxt};
+use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, GenericArg, Region, Ty, TyCtxt};
 use rustc_span::{BytePos, Ident, Span, Symbol, kw};
 
 use crate::error_reporting::infer::ObligationCauseAsDiagArg;
@@ -1922,3 +1922,14 @@ impl Subdiagnostic for AddPreciseCapturingForOvercapture {
         }
     }
 }
+
+#[derive(Diagnostic)]
+#[diag(trait_selection_opaque_type_non_generic_param, code = E0792)]
+pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
+    pub ty: GenericArg<'tcx>,
+    pub kind: &'a str,
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub param_span: Span,
+}
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index b18fb0fb8fd..93c11805304 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -36,6 +36,7 @@
 pub mod error_reporting;
 pub mod errors;
 pub mod infer;
+pub mod opaque_types;
 pub mod regions;
 pub mod solve;
 pub mod traits;
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
new file mode 100644
index 00000000000..c7b8f063196
--- /dev/null
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -0,0 +1,182 @@
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_hir::OpaqueTyOrigin;
+use rustc_hir::def_id::LocalDefId;
+use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_middle::ty::{
+    self, DefiningScopeKind, GenericArgKind, GenericArgs, OpaqueTypeKey, TyCtxt, TypeVisitableExt,
+    TypingMode, fold_regions,
+};
+use rustc_span::{ErrorGuaranteed, Span};
+
+use crate::errors::NonGenericOpaqueTypeParam;
+use crate::regions::OutlivesEnvironmentBuildExt;
+use crate::traits::ObligationCtxt;
+
+/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter].
+///
+/// [rustc-dev-guide chapter]:
+/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html
+pub fn check_opaque_type_parameter_valid<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    opaque_type_key: OpaqueTypeKey<'tcx>,
+    span: Span,
+    defining_scope_kind: DefiningScopeKind,
+) -> Result<(), ErrorGuaranteed> {
+    let tcx = infcx.tcx;
+    let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
+    let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
+    let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
+
+    // Avoid duplicate errors in case the opaque has already been malformed in
+    // HIR typeck.
+    if let DefiningScopeKind::MirBorrowck = defining_scope_kind {
+        if let Err(guar) = infcx
+            .tcx
+            .type_of_opaque_hir_typeck(opaque_type_key.def_id)
+            .instantiate_identity()
+            .error_reported()
+        {
+            return Err(guar);
+        }
+    }
+
+    for (i, arg) in opaque_type_key.iter_captured_args(tcx) {
+        let arg_is_param = match arg.unpack() {
+            GenericArgKind::Lifetime(lt) => match defining_scope_kind {
+                DefiningScopeKind::HirTypeck => continue,
+                DefiningScopeKind::MirBorrowck => {
+                    matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_))
+                        || (lt.is_static() && opaque_env.param_equal_static(i))
+                }
+            },
+            GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
+            GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)),
+        };
+
+        if arg_is_param {
+            // Register if the same lifetime appears multiple times in the generic args.
+            // There is an exception when the opaque type *requires* the lifetimes to be equal.
+            // See [rustc-dev-guide chapter] § "An exception to uniqueness rule".
+            let seen_where = seen_params.entry(arg).or_default();
+            if !seen_where.first().is_some_and(|&prev_i| opaque_env.params_equal(i, prev_i)) {
+                seen_where.push(i);
+            }
+        } else {
+            // Prevent `fn foo() -> Foo<u32>` from being defining.
+            let opaque_param = opaque_generics.param_at(i, tcx);
+            let kind = opaque_param.kind.descr();
+
+            opaque_env.param_is_error(i)?;
+
+            return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
+                ty: arg,
+                kind,
+                span,
+                param_span: tcx.def_span(opaque_param.def_id),
+            }));
+        }
+    }
+
+    for (_, indices) in seen_params {
+        if indices.len() > 1 {
+            let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
+            let spans: Vec<_> = indices
+                .into_iter()
+                .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
+                .collect();
+            return Err(infcx
+                .dcx()
+                .struct_span_err(span, "non-defining opaque type use in defining scope")
+                .with_span_note(spans, format!("{descr} used multiple times"))
+                .emit());
+        }
+    }
+
+    Ok(())
+}
+
+/// Computes if an opaque type requires a lifetime parameter to be equal to
+/// another one or to the `'static` lifetime.
+/// These requirements are derived from the explicit and implied bounds.
+struct LazyOpaqueTyEnv<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+
+    /// Equal parameters will have the same name. Computed Lazily.
+    /// Example:
+    ///     `type Opaque<'a: 'static, 'b: 'c, 'c: 'b> = impl Sized;`
+    ///     Identity args: `['a, 'b, 'c]`
+    ///     Canonical args: `['static, 'b, 'b]`
+    canonical_args: std::cell::OnceCell<ty::GenericArgsRef<'tcx>>,
+}
+
+impl<'tcx> LazyOpaqueTyEnv<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
+        Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() }
+    }
+
+    fn param_equal_static(&self, param_index: usize) -> bool {
+        self.get_canonical_args()[param_index].expect_region().is_static()
+    }
+
+    fn params_equal(&self, param1: usize, param2: usize) -> bool {
+        let canonical_args = self.get_canonical_args();
+        canonical_args[param1] == canonical_args[param2]
+    }
+
+    fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> {
+        self.get_canonical_args()[param_index].error_reported()
+    }
+
+    fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> {
+        if let Some(&canonical_args) = self.canonical_args.get() {
+            return canonical_args;
+        }
+
+        let &Self { tcx, def_id, .. } = self;
+        let origin = tcx.local_opaque_ty_origin(def_id);
+        let parent = match origin {
+            OpaqueTyOrigin::FnReturn { parent, .. }
+            | OpaqueTyOrigin::AsyncFn { parent, .. }
+            | OpaqueTyOrigin::TyAlias { parent, .. } => parent,
+        };
+        let param_env = tcx.param_env(parent);
+        let args = GenericArgs::identity_for_item(tcx, parent).extend_to(
+            tcx,
+            def_id.to_def_id(),
+            |param, _| {
+                tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into()
+            },
+        );
+
+        // FIXME(#132279): It feels wrong to use `non_body_analysis` here given that we're
+        // in a body here.
+        let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
+        let ocx = ObligationCtxt::new(&infcx);
+
+        let wf_tys = ocx.assumed_wf_types(param_env, parent).unwrap_or_else(|_| {
+            tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds");
+            Default::default()
+        });
+        let outlives_env = OutlivesEnvironment::new(&infcx, parent, param_env, wf_tys);
+
+        let mut seen = vec![tcx.lifetimes.re_static];
+        let canonical_args = fold_regions(tcx, args, |r1, _| {
+            if r1.is_error() {
+                r1
+            } else if let Some(&r2) = seen.iter().find(|&&r2| {
+                let free_regions = outlives_env.free_region_map();
+                free_regions.sub_free_regions(tcx, r1, r2)
+                    && free_regions.sub_free_regions(tcx, r2, r1)
+            }) {
+                r2
+            } else {
+                seen.push(r1);
+                r1
+            }
+        });
+        self.canonical_args.set(canonical_args).unwrap();
+        canonical_args
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 3d9a90eb74e..e0b425fa739 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -149,16 +149,16 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         self.0.instantiate_canonical_var(span, cv_info, universe_map)
     }
 
-    fn insert_hidden_type(
+    fn register_hidden_type_in_storage(
         &self,
-        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        hidden_ty: Ty<'tcx>,
-        goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
-    ) -> Result<(), NoSolution> {
-        self.0
-            .insert_hidden_type(opaque_type_key, DUMMY_SP, param_env, hidden_ty, goals)
-            .map_err(|_| NoSolution)
+        opaque_type_key: rustc_type_ir::OpaqueTypeKey<Self::Interner>,
+        hidden_ty: <Self::Interner as ty::Interner>::Ty,
+        span: <Self::Interner as ty::Interner>::Span,
+    ) -> Option<<Self::Interner as ty::Interner>::Ty> {
+        self.0.register_hidden_type_in_storage(
+            opaque_type_key,
+            ty::OpaqueHiddenType { span, ty: hidden_ty },
+        )
     }
 
     fn add_item_bounds_for_hidden_type(
@@ -172,15 +172,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals);
     }
 
-    fn inject_new_hidden_type_unchecked(
-        &self,
-        key: ty::OpaqueTypeKey<'tcx>,
-        hidden_ty: Ty<'tcx>,
-        span: Span,
-    ) {
-        self.0.inject_new_hidden_type_unchecked(key, ty::OpaqueHiddenType { ty: hidden_ty, span })
-    }
-
     fn reset_opaque_types(&self) {
         let _ = self.take_opaque_types();
     }
@@ -204,6 +195,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
             match self.typing_mode() {
                 TypingMode::Coherence
                 | TypingMode::Analysis { .. }
+                | TypingMode::Borrowck { .. }
                 | TypingMode::PostBorrowckAnalysis { .. } => false,
                 TypingMode::PostAnalysis => {
                     let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref);
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index 78a45243983..fa6bbf1d6e5 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -583,27 +583,36 @@ fn receiver_is_dispatchable<'tcx>(
     // create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
     // its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
     let param_env = {
-        let param_env = tcx.param_env(method.def_id);
+        // N.B. We generally want to emulate the construction of the `unnormalized_param_env`
+        // in the param-env query here. The fact that we don't just start with the clauses
+        // in the param-env of the method is because those are already normalized, and mixing
+        // normalized and unnormalized copies of predicates in `normalize_param_env_or_error`
+        // will cause ambiguity that the user can't really avoid.
+        //
+        // We leave out certain complexities of the param-env query here. Specifically, we:
+        // 1. Do not add `~const` bounds since there are no `dyn const Trait`s.
+        // 2. Do not add RPITIT self projection bounds for defaulted methods, since we
+        //    are not constructing a param-env for "inside" of the body of the defaulted
+        //    method, so we don't really care about projecting to a specific RPIT type,
+        //    and because RPITITs are not dyn compatible (yet).
+        let mut predicates = tcx.predicates_of(method.def_id).instantiate_identity(tcx).predicates;
 
         // Self: Unsize<U>
         let unsize_predicate =
-            ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]).upcast(tcx);
+            ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]);
+        predicates.push(unsize_predicate.upcast(tcx));
 
         // U: Trait<Arg1, ..., ArgN>
-        let trait_predicate = {
-            let trait_def_id = method.trait_container(tcx).unwrap();
-            let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
-                if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
-            });
-
-            ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
-        };
+        let trait_def_id = method.trait_container(tcx).unwrap();
+        let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
+            if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
+        });
+        let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args);
+        predicates.push(trait_predicate.upcast(tcx));
 
         normalize_param_env_or_error(
             tcx,
-            ty::ParamEnv::new(tcx.mk_clauses_from_iter(
-                param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]),
-            )),
+            ty::ParamEnv::new(tcx.mk_clauses(&predicates)),
             ObligationCause::dummy_with_span(tcx.def_span(method.def_id)),
         )
     };
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index 3c127416cbf..defbafac20b 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -106,10 +106,6 @@ fn match_candidate<'tcx>(
 
     more_nested(selcx, &mut nested);
 
-    for nested in &mut nested {
-        nested.set_depth_from_parent(obligation.recursion_depth);
-    }
-
     Ok(nested)
 }
 
@@ -263,7 +259,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
                 .all_fields()
                 .map(|field| ty::TraitRef::new(tcx, destruct_def_id, [field.ty(tcx, args)]))
                 .collect();
-            match adt_def.destructor(tcx).map(|dtor| dtor.constness) {
+            match adt_def.destructor(tcx).map(|dtor| tcx.constness(dtor.did)) {
                 // `Drop` impl exists, but it's not const. Type cannot be `~const Destruct`.
                 Some(hir::Constness::NotConst) => return Err(EvaluationFailure::NoSolution),
                 // `Drop` impl exists, and it's const. Require `Ty: ~const Drop` to hold.
@@ -378,10 +374,6 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>(
                             }),
                     );
 
-                    for nested in &mut nested {
-                        nested.set_depth_from_parent(obligation.recursion_depth);
-                    }
-
                     Ok(nested)
                 }
                 _ => Err(EvaluationFailure::NoSolution),
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index e39f8e673db..e98a240a53f 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -225,9 +225,15 @@ struct FulfillProcessor<'a, 'tcx> {
     selcx: SelectionContext<'a, 'tcx>,
 }
 
-fn mk_pending<'tcx>(os: PredicateObligations<'tcx>) -> PendingPredicateObligations<'tcx> {
+fn mk_pending<'tcx>(
+    parent: &PredicateObligation<'tcx>,
+    os: PredicateObligations<'tcx>,
+) -> PendingPredicateObligations<'tcx> {
     os.into_iter()
-        .map(|o| PendingPredicateObligation { obligation: o, stalled_on: vec![] })
+        .map(|mut o| {
+            o.set_depth_from_parent(parent.recursion_depth);
+            PendingPredicateObligation { obligation: o, stalled_on: vec![] }
+        })
         .collect()
 }
 
@@ -341,7 +347,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
             );
             if predicate != obligation.predicate {
                 obligations.push(obligation.with(infcx.tcx, predicate));
-                return ProcessResult::Changed(mk_pending(obligations));
+                return ProcessResult::Changed(mk_pending(obligation, obligations));
             }
         }
         let binder = obligation.predicate.kind();
@@ -385,7 +391,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     let mut obligations = PredicateObligations::with_capacity(1);
                     obligations.push(obligation.with(infcx.tcx, pred));
 
-                    ProcessResult::Changed(mk_pending(obligations))
+                    ProcessResult::Changed(mk_pending(obligation, obligations))
                 }
                 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
                 ty::PredicateKind::NormalizesTo(..) => {
@@ -410,6 +416,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     let host_obligation = obligation.with(infcx.tcx, data);
 
                     self.process_host_obligation(
+                        obligation,
                         host_obligation,
                         &mut pending_obligation.stalled_on,
                     )
@@ -486,7 +493,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         // `<lhs_ty as Add<rhs_ty>>::Output` when this is an `Expr` representing
                         // `lhs + rhs`.
                         ty::ConstKind::Expr(_) => {
-                            return ProcessResult::Changed(mk_pending(PredicateObligations::new()));
+                            return ProcessResult::Changed(mk_pending(
+                                obligation,
+                                PredicateObligations::new(),
+                            ));
                         }
                         ty::ConstKind::Placeholder(_) => {
                             bug!("placeholder const {:?} in old solver", ct)
@@ -503,7 +513,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         ct_ty,
                         ty,
                     ) {
-                        Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
+                        Ok(inf_ok) => ProcessResult::Changed(mk_pending(
+                            obligation,
+                            inf_ok.into_obligations(),
+                        )),
                         Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
                             SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty },
                         )),
@@ -537,7 +550,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 vec![TyOrConstInferVar::maybe_from_generic_arg(arg).unwrap()];
                             ProcessResult::Unchanged
                         }
-                        Some(os) => ProcessResult::Changed(mk_pending(os)),
+                        Some(os) => ProcessResult::Changed(mk_pending(obligation, os)),
                     }
                 }
 
@@ -553,11 +566,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
                             ProcessResult::Unchanged
                         }
-                        Ok(Ok(mut ok)) => {
-                            for subobligation in &mut ok.obligations {
-                                subobligation.set_depth_from_parent(obligation.recursion_depth);
-                            }
-                            ProcessResult::Changed(mk_pending(ok.obligations))
+                        Ok(Ok(ok)) => {
+                            ProcessResult::Changed(mk_pending(obligation, ok.obligations))
                         }
                         Ok(Err(err)) => {
                             let expected_found = if subtype.a_is_expected {
@@ -582,7 +592,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
                             ProcessResult::Unchanged
                         }
-                        Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
+                        Ok(Ok(ok)) => {
+                            ProcessResult::Changed(mk_pending(obligation, ok.obligations))
+                        }
                         Ok(Err(err)) => {
                             let expected_found = ExpectedFound::new(coerce.b, coerce.a);
                             ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
@@ -645,6 +657,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                     )
                                 {
                                     return ProcessResult::Changed(mk_pending(
+                                        obligation,
                                         new_obligations.into_obligations(),
                                     ));
                                 }
@@ -659,6 +672,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                     .eq(DefineOpaqueTypes::Yes, c1, c2)
                                 {
                                     return ProcessResult::Changed(mk_pending(
+                                        obligation,
                                         new_obligations.into_obligations(),
                                     ));
                                 }
@@ -704,9 +718,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 c1,
                                 c2,
                             ) {
-                                Ok(inf_ok) => {
-                                    ProcessResult::Changed(mk_pending(inf_ok.into_obligations()))
-                                }
+                                Ok(inf_ok) => ProcessResult::Changed(mk_pending(
+                                    obligation,
+                                    inf_ok.into_obligations(),
+                                )),
                                 Err(err) => {
                                     ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
                                         ExpectedFound::new(c1, c2),
@@ -790,7 +805,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
         match self.selcx.poly_select(&trait_obligation) {
             Ok(Some(impl_source)) => {
                 debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth);
-                ProcessResult::Changed(mk_pending(impl_source.nested_obligations()))
+                ProcessResult::Changed(mk_pending(obligation, impl_source.nested_obligations()))
             }
             Ok(None) => {
                 debug!("selecting trait at depth {} yielded Ok(None)", obligation.recursion_depth);
@@ -854,7 +869,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
         }
 
         match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) {
-            ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
+            ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(obligation, os)),
             ProjectAndUnifyResult::FailedNormalization => {
                 stalled_on.clear();
                 stalled_on.extend(args_infer_vars(
@@ -868,7 +883,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
                 let mut obligations = PredicateObligations::with_capacity(1);
                 obligations.push(project_obligation.with(tcx, project_obligation.predicate));
 
-                ProcessResult::Changed(mk_pending(obligations))
+                ProcessResult::Changed(mk_pending(obligation, obligations))
             }
             ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
                 ProcessResult::Error(FulfillmentErrorCode::Project(e))
@@ -878,11 +893,12 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
 
     fn process_host_obligation(
         &mut self,
+        obligation: &PredicateObligation<'tcx>,
         host_obligation: HostEffectObligation<'tcx>,
         stalled_on: &mut Vec<TyOrConstInferVar>,
     ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
         match effects::evaluate_host_effect_obligation(&mut self.selcx, &host_obligation) {
-            Ok(nested) => ProcessResult::Changed(mk_pending(nested)),
+            Ok(nested) => ProcessResult::Changed(mk_pending(obligation, nested)),
             Err(effects::EvaluationFailure::Ambiguous) => {
                 stalled_on.clear();
                 stalled_on.extend(args_infer_vars(
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index ad62b456ad4..4ac45172a0e 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -130,6 +130,7 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
         // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis
         TypingMode::Coherence
         | TypingMode::Analysis { .. }
+        | TypingMode::Borrowck { .. }
         | TypingMode::PostBorrowckAnalysis { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE),
         TypingMode::PostAnalysis => {}
     }
@@ -226,6 +227,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                     // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis
                     TypingMode::Coherence
                     | TypingMode::Analysis { .. }
+                    | TypingMode::Borrowck { .. }
                     | TypingMode::PostBorrowckAnalysis { .. } => ty.super_fold_with(self),
                     TypingMode::PostAnalysis => {
                         let recursion_limit = self.cx().recursion_limit();
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 6057b66c483..349569d750e 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -952,6 +952,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                             match selcx.infcx.typing_mode() {
                                 TypingMode::Coherence
                                 | TypingMode::Analysis { .. }
+                                | TypingMode::Borrowck { .. }
                                 | TypingMode::PostBorrowckAnalysis { .. } => {
                                     debug!(
                                         assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 165c63f3745..5dbb4382fd1 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -216,6 +216,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
                 match self.infcx.typing_mode() {
                     TypingMode::Coherence
                     | TypingMode::Analysis { .. }
+                    | TypingMode::Borrowck { .. }
                     | TypingMode::PostBorrowckAnalysis { .. } => ty.try_super_fold_with(self)?,
 
                     TypingMode::PostAnalysis => {
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 4cfd8149b1e..cf6d2bc151f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -86,10 +86,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // `Pointee` is automatically implemented for every type.
                 candidates.vec.push(BuiltinCandidate { has_nested: false });
             } else if tcx.is_lang_item(def_id, LangItem::Sized) {
-                // Sized is never implementable by end-users, it is
-                // always automatically computed.
-                let sized_conditions = self.sized_conditions(obligation);
-                self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
+                self.assemble_builtin_sized_candidate(obligation, &mut candidates);
             } else if tcx.is_lang_item(def_id, LangItem::Unsize) {
                 self.assemble_candidates_for_unsizing(obligation, &mut candidates);
             } else if tcx.is_lang_item(def_id, LangItem::Destruct) {
@@ -695,6 +692,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let def_id = obligation.predicate.def_id();
 
+        let mut check_impls = || {
+            // Only consider auto impls if there are no manual impls for the root of `self_ty`.
+            //
+            // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
+            // for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
+            // for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
+            //
+            // Generally, we have to guarantee that for all `SimplifiedType`s the only crate
+            // which may define impls for that type is either the crate defining the type
+            // or the trait. This should be guaranteed by the orphan check.
+            let mut has_impl = false;
+            self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
+            if !has_impl {
+                candidates.vec.push(AutoImplCandidate)
+            }
+        };
+
         if self.tcx().trait_is_auto(def_id) {
             match *self_ty.kind() {
                 ty::Dynamic(..) => {
@@ -708,6 +722,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     // we don't add any `..` impl. Default traits could
                     // still be provided by a manual implementation for
                     // this trait and type.
+
+                    // Backward compatibility for default auto traits.
+                    // Test: ui/traits/default_auto_traits/extern-types.rs
+                    if self.tcx().is_default_trait(def_id) {
+                        check_impls()
+                    }
                 }
                 ty::Param(..)
                 | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
@@ -808,20 +828,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         return;
                     }
 
-                    // Only consider auto impls if there are no manual impls for the root of `self_ty`.
-                    //
-                    // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
-                    // for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
-                    // for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
-                    //
-                    // Generally, we have to guarantee that for all `SimplifiedType`s the only crate
-                    // which may define impls for that type is either the crate defining the type
-                    // or the trait. This should be guaranteed by the orphan check.
-                    let mut has_impl = false;
-                    self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
-                    if !has_impl {
-                        candidates.vec.push(AutoImplCandidate)
-                    }
+                    check_impls();
                 }
                 ty::Error(_) => {
                     candidates.vec.push(AutoImplCandidate);
@@ -1061,6 +1068,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// Assembles the trait which are built-in to the language itself:
     /// `Copy`, `Clone` and `Sized`.
     #[instrument(level = "debug", skip(self, candidates))]
+    fn assemble_builtin_sized_candidate(
+        &mut self,
+        obligation: &PolyTraitObligation<'tcx>,
+        candidates: &mut SelectionCandidateSet<'tcx>,
+    ) {
+        match self.sized_conditions(obligation) {
+            BuiltinImplConditions::Where(nested) => {
+                candidates
+                    .vec
+                    .push(SizedCandidate { has_nested: !nested.skip_binder().is_empty() });
+            }
+            BuiltinImplConditions::None => {}
+            BuiltinImplConditions::Ambiguous => {
+                candidates.ambiguous = true;
+            }
+        }
+    }
+
+    /// Assembles the trait which are built-in to the language itself:
+    /// e.g. `Copy` and `Clone`.
+    #[instrument(level = "debug", skip(self, candidates))]
     fn assemble_builtin_bound_candidates(
         &mut self,
         conditions: BuiltinImplConditions<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index a66c958c109..2cb7d2d8931 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -39,7 +39,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &PolyTraitObligation<'tcx>,
         candidate: SelectionCandidate<'tcx>,
     ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
-        let mut impl_src = match candidate {
+        Ok(match candidate {
+            SizedCandidate { has_nested } => {
+                let data = self.confirm_builtin_candidate(obligation, has_nested);
+                ImplSource::Builtin(BuiltinImplSource::Misc, data)
+            }
+
             BuiltinCandidate { has_nested } => {
                 let data = self.confirm_builtin_candidate(obligation, has_nested);
                 ImplSource::Builtin(BuiltinImplSource::Misc, data)
@@ -134,15 +139,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             BikeshedGuaranteedNoDropCandidate => {
                 self.confirm_bikeshed_guaranteed_no_drop_candidate(obligation)
             }
-        };
-
-        // The obligations returned by confirmation are recursively evaluated
-        // so we need to make sure they have the correct depth.
-        for subobligation in impl_src.borrow_nested_obligations_mut() {
-            subobligation.set_depth_from_parent(obligation.recursion_depth);
-        }
-
-        Ok(impl_src)
+        })
     }
 
     fn confirm_projection_candidate(
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index e439df76cd4..56ff46e89e7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1446,6 +1446,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         match self.infcx.typing_mode() {
             TypingMode::Coherence => {}
             TypingMode::Analysis { .. }
+            | TypingMode::Borrowck { .. }
             | TypingMode::PostBorrowckAnalysis { .. }
             | TypingMode::PostAnalysis => return Ok(()),
         }
@@ -1491,7 +1492,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // However, if we disqualify *all* goals from being cached, perf suffers.
             // This is likely fixed by better caching in general in the new solver.
             // See: <https://github.com/rust-lang/rust/issues/132064>.
-            TypingMode::Analysis { defining_opaque_types } => {
+            TypingMode::Analysis { defining_opaque_types }
+            | TypingMode::Borrowck { defining_opaque_types } => {
                 defining_opaque_types.is_empty() || !pred.has_opaque_types()
             }
             // The hidden types of `defined_opaque_types` is not local to the current
@@ -1801,17 +1803,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             return Some(candidates.pop().unwrap().candidate);
         }
 
-        // We prefer trivial builtin candidates, i.e. builtin impls without any nested
-        // requirements, over all others. This is a fix for #53123 and prevents winnowing
-        // from accidentally extending the lifetime of a variable.
-        let mut trivial_builtin = candidates
-            .iter()
-            .filter(|c| matches!(c.candidate, BuiltinCandidate { has_nested: false }));
-        if let Some(_trivial) = trivial_builtin.next() {
-            // There should only ever be a single trivial builtin candidate
+        // We prefer `Sized` candidates over everything.
+        let mut sized_candidates =
+            candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate { has_nested: _ }));
+        if let Some(sized_candidate) = sized_candidates.next() {
+            // There should only ever be a single sized candidate
             // as they would otherwise overlap.
-            debug_assert_eq!(trivial_builtin.next(), None);
-            return Some(BuiltinCandidate { has_nested: false });
+            debug_assert_eq!(sized_candidates.next(), None);
+            // Only prefer the built-in `Sized` candidate if its nested goals are certain.
+            // Otherwise, we may encounter failure later on if inference causes this candidate
+            // to not hold, but a where clause would've applied instead.
+            if sized_candidate.evaluation.must_apply_modulo_regions() {
+                return Some(sized_candidate.candidate.clone());
+            } else {
+                return None;
+            }
         }
 
         // Before we consider where-bounds, we have to deduplicate them here and also
@@ -1940,7 +1946,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             // Don't use impl candidates which overlap with other candidates.
             // This should pretty much only ever happen with malformed impls.
             if candidates.iter().all(|c| match c.candidate {
-                BuiltinCandidate { has_nested: _ }
+                SizedCandidate { has_nested: _ }
+                | BuiltinCandidate { has_nested: _ }
                 | TransmutabilityCandidate
                 | AutoImplCandidate
                 | ClosureCandidate { .. }
@@ -2294,6 +2301,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             | ty::Never
             | ty::Char => ty::Binder::dummy(Vec::new()),
 
+            // This branch is only for `experimental_default_bounds`.
+            // Other foreign types were rejected earlier in
+            // `assemble_candidates_from_auto_impls`.
+            ty::Foreign(..) => ty::Binder::dummy(Vec::new()),
+
             // FIXME(unsafe_binders): Squash the double binder for now, I guess.
             ty::UnsafeBinder(_) => return Err(SelectionError::Unimplemented),
 
@@ -2303,7 +2315,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             ty::Placeholder(..)
             | ty::Dynamic(..)
             | ty::Param(..)
-            | ty::Foreign(..)
             | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
             | ty::Bound(..)
             | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 962e1353ebc..66c18bed5e7 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -149,6 +149,7 @@ fn resolve_associated_item<'tcx>(
                 match typing_env.typing_mode {
                     ty::TypingMode::Coherence
                     | ty::TypingMode::Analysis { .. }
+                    | ty::TypingMode::Borrowck { .. }
                     | ty::TypingMode::PostBorrowckAnalysis { .. } => false,
                     ty::TypingMode::PostAnalysis => !trait_ref.still_further_specializable(),
                 }
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index 0bc8b94bbf4..e58f25f4ce7 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -54,7 +54,7 @@ use tracing::{debug, instrument};
 
 use crate::inherent::*;
 use crate::visit::{TypeVisitable, TypeVisitableExt as _};
-use crate::{self as ty, Interner};
+use crate::{self as ty, Interner, TypeFlags};
 
 #[cfg(feature = "nightly")]
 type Never = !;
@@ -438,12 +438,12 @@ where
 pub fn fold_regions<I: Interner, T>(
     cx: I,
     value: T,
-    mut f: impl FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
+    f: impl FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
 ) -> T
 where
     T: TypeFoldable<I>,
 {
-    value.fold_with(&mut RegionFolder::new(cx, &mut f))
+    value.fold_with(&mut RegionFolder::new(cx, f))
 }
 
 /// Folds over the substructure of a type, visiting its component
@@ -453,7 +453,7 @@ where
 /// new bound regions which are not visited by this visitors as
 /// they are not free; only regions that occur free will be
 /// visited by `fld_r`.
-pub struct RegionFolder<'a, I: Interner> {
+pub struct RegionFolder<I, F> {
     cx: I,
 
     /// Stores the index of a binder *just outside* the stuff we have
@@ -464,20 +464,21 @@ pub struct RegionFolder<'a, I: Interner> {
     /// Callback invokes for each free region. The `DebruijnIndex`
     /// points to the binder *just outside* the ones we have passed
     /// through.
-    fold_region_fn: &'a mut (dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region + 'a),
+    fold_region_fn: F,
 }
 
-impl<'a, I: Interner> RegionFolder<'a, I> {
+impl<I, F> RegionFolder<I, F> {
     #[inline]
-    pub fn new(
-        cx: I,
-        fold_region_fn: &'a mut dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
-    ) -> RegionFolder<'a, I> {
+    pub fn new(cx: I, fold_region_fn: F) -> RegionFolder<I, F> {
         RegionFolder { cx, current_index: ty::INNERMOST, fold_region_fn }
     }
 }
 
-impl<'a, I: Interner> TypeFolder<I> for RegionFolder<'a, I> {
+impl<I, F> TypeFolder<I> for RegionFolder<I, F>
+where
+    I: Interner,
+    F: FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
+{
     fn cx(&self) -> I {
         self.cx
     }
@@ -502,4 +503,34 @@ impl<'a, I: Interner> TypeFolder<I> for RegionFolder<'a, I> {
             }
         }
     }
+
+    fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
+        if t.has_type_flags(
+            TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
+        ) {
+            t.super_fold_with(self)
+        } else {
+            t
+        }
+    }
+
+    fn fold_const(&mut self, ct: I::Const) -> I::Const {
+        if ct.has_type_flags(
+            TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
+        ) {
+            ct.super_fold_with(self)
+        } else {
+            ct
+        }
+    }
+
+    fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
+        if p.has_type_flags(
+            TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
+        ) {
+            p.super_fold_with(self)
+        } else {
+            p
+        }
+    }
 }
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index e512e8fc838..fec6e24e2cb 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -66,6 +66,14 @@ pub enum TypingMode<I: Interner> {
     /// }
     /// ```
     Analysis { defining_opaque_types: I::DefiningOpaqueTypes },
+    /// The behavior during MIR borrowck is identical to `TypingMode::Analysis`
+    /// except that the initial value for opaque types is the type computed during
+    /// HIR typeck with unique unconstrained region inference variables.
+    ///
+    /// This is currently only used with by the new solver as it results in new
+    /// non-universal defining uses of opaque types, which is a breaking change.
+    /// See tests/ui/impl-trait/non-defining-use/as-projection-term.rs.
+    Borrowck { defining_opaque_types: I::DefiningOpaqueTypes },
     /// Any analysis after borrowck for a given body should be able to use all the
     /// hidden types defined by borrowck, without being able to define any new ones.
     ///
@@ -95,6 +103,10 @@ impl<I: Interner> TypingMode<I> {
         TypingMode::Analysis { defining_opaque_types: cx.opaque_types_defined_by(body_def_id) }
     }
 
+    pub fn borrowck(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
+        TypingMode::Borrowck { defining_opaque_types: cx.opaque_types_defined_by(body_def_id) }
+    }
+
     pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
         TypingMode::PostBorrowckAnalysis {
             defined_opaque_types: cx.opaque_types_defined_by(body_def_id),
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index d4134bdf3a7..59c2d3c2fc8 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -146,67 +146,14 @@ pub trait Ty<I: Interner<Ty = Self>>:
     fn has_unsafe_fields(self) -> bool;
 
     fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
-        match self.kind() {
-            ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
-            ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
-            ty::Error(_) => {
-                // ignore errors (#54954)
-                ty::Binder::dummy(ty::FnSig {
-                    inputs_and_output: Default::default(),
-                    c_variadic: false,
-                    safety: I::Safety::safe(),
-                    abi: I::Abi::rust(),
-                })
-            }
-            ty::Closure(..) => panic!(
-                "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
-            ),
-            _ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self),
-        }
+        self.kind().fn_sig(interner)
     }
 
     fn discriminant_ty(self, interner: I) -> I::Ty;
 
     fn async_destructor_ty(self, interner: I) -> I::Ty;
-
-    /// Returns `true` when the outermost type cannot be further normalized,
-    /// resolved, or instantiated. This includes all primitive types, but also
-    /// things like ADTs and trait objects, since even if their arguments or
-    /// nested types may be further simplified, the outermost [`ty::TyKind`] or
-    /// type constructor remains the same.
     fn is_known_rigid(self) -> bool {
-        match self.kind() {
-            ty::Bool
-            | ty::Char
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Adt(_, _)
-            | ty::Foreign(_)
-            | ty::Str
-            | ty::Array(_, _)
-            | ty::Pat(_, _)
-            | ty::Slice(_)
-            | ty::RawPtr(_, _)
-            | ty::Ref(_, _, _)
-            | ty::FnDef(_, _)
-            | ty::FnPtr(..)
-            | ty::UnsafeBinder(_)
-            | ty::Dynamic(_, _, _)
-            | ty::Closure(_, _)
-            | ty::CoroutineClosure(_, _)
-            | ty::Coroutine(_, _)
-            | ty::CoroutineWitness(..)
-            | ty::Never
-            | ty::Tuple(_) => true,
-
-            ty::Error(_)
-            | ty::Infer(_)
-            | ty::Alias(_, _)
-            | ty::Param(_)
-            | ty::Bound(_, _)
-            | ty::Placeholder(_) => false,
-        }
+        self.kind().is_known_rigid()
     }
 }
 
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 8f86270d7dc..fce93b735d7 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -149,6 +149,8 @@ pub trait Interner:
     ) -> Option<Self::VariancesOf>;
 
     fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
+    fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId)
+    -> ty::EarlyBinder<Self, Self::Ty>;
 
     type AdtDef: AdtDef<Self>;
     fn adt_def(self, adt_def_id: Self::DefId) -> Self::AdtDef;
@@ -259,6 +261,8 @@ pub trait Interner:
 
     fn is_lang_item(self, def_id: Self::DefId, lang_item: TraitSolverLangItem) -> bool;
 
+    fn is_default_trait(self, def_id: Self::DefId) -> bool;
+
     fn as_lang_item(self, def_id: Self::DefId) -> Option<TraitSolverLangItem>;
 
     fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId>;
diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs
index d49f8d3093d..8dd7c4df244 100644
--- a/compiler/rustc_type_ir/src/relate/combine.rs
+++ b/compiler/rustc_type_ir/src/relate/combine.rs
@@ -137,6 +137,7 @@ where
                     Ok(a)
                 }
                 TypingMode::Analysis { .. }
+                | TypingMode::Borrowck { .. }
                 | TypingMode::PostBorrowckAnalysis { .. }
                 | TypingMode::PostAnalysis => structurally_relate_tys(relation, a, b),
             }
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 9bea4482b55..d35b22d517c 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -273,6 +273,68 @@ pub enum TyKind<I: Interner> {
     Error(I::ErrorGuaranteed),
 }
 
+impl<I: Interner> TyKind<I> {
+    pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
+        match self {
+            ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
+            ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
+            ty::Error(_) => {
+                // ignore errors (#54954)
+                ty::Binder::dummy(ty::FnSig {
+                    inputs_and_output: Default::default(),
+                    c_variadic: false,
+                    safety: I::Safety::safe(),
+                    abi: I::Abi::rust(),
+                })
+            }
+            ty::Closure(..) => panic!(
+                "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
+            ),
+            _ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self),
+        }
+    }
+
+    /// Returns `true` when the outermost type cannot be further normalized,
+    /// resolved, or instantiated. This includes all primitive types, but also
+    /// things like ADTs and trait objects, since even if their arguments or
+    /// nested types may be further simplified, the outermost [`ty::TyKind`] or
+    /// type constructor remains the same.
+    pub fn is_known_rigid(self) -> bool {
+        match self {
+            ty::Bool
+            | ty::Char
+            | ty::Int(_)
+            | ty::Uint(_)
+            | ty::Float(_)
+            | ty::Adt(_, _)
+            | ty::Foreign(_)
+            | ty::Str
+            | ty::Array(_, _)
+            | ty::Pat(_, _)
+            | ty::Slice(_)
+            | ty::RawPtr(_, _)
+            | ty::Ref(_, _, _)
+            | ty::FnDef(_, _)
+            | ty::FnPtr(..)
+            | ty::UnsafeBinder(_)
+            | ty::Dynamic(_, _, _)
+            | ty::Closure(_, _)
+            | ty::CoroutineClosure(_, _)
+            | ty::Coroutine(_, _)
+            | ty::CoroutineWitness(..)
+            | ty::Never
+            | ty::Tuple(_) => true,
+
+            ty::Error(_)
+            | ty::Infer(_)
+            | ty::Alias(_, _)
+            | ty::Param(_)
+            | ty::Bound(_, _)
+            | ty::Placeholder(_) => false,
+        }
+    }
+}
+
 // This is manually implemented because a derive would require `I: Debug`
 impl<I: Interner> fmt::Debug for TyKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml
index d691a0e4f22..3a01ee5783e 100644
--- a/compiler/stable_mir/Cargo.toml
+++ b/compiler/stable_mir/Cargo.toml
@@ -4,5 +4,4 @@ version = "0.1.0-preview"
 edition = "2024"
 
 [dependencies]
-scoped-tls = "1.0"
-serde = { version = "1.0.125", features = [ "derive" ] }
+rustc_smir = { path = "../rustc_smir" }
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index 70d42dfbfcb..cc0fb52433d 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -1,228 +1,7 @@
-//! The WIP stable interface to rustc internals.
+//! We've temporarily moved the `stable_mir` implementation to [`rustc_smir::stable_mir`],
+//! during refactoring to break the circular dependency between `rustc_smir` and `stable_mir`,
 //!
-//! For more information see <https://github.com/rust-lang/project-stable-mir>
-//!
-//! # Note
-//!
-//! This API is still completely unstable and subject to change.
-
-#![doc(
-    html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
-    test(attr(allow(unused_variables), deny(warnings)))
-)]
-//!
-//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to
-//! interact with the compiler.
-//!
-//! The goal is to eventually be published on
-//! [crates.io](https://crates.io).
-
-use std::fmt::Debug;
-use std::{fmt, io};
-
-use serde::Serialize;
-
-use crate::compiler_interface::with;
-pub use crate::crate_def::{CrateDef, CrateDefType, DefId};
-pub use crate::error::*;
-use crate::mir::mono::StaticDef;
-use crate::mir::{Body, Mutability};
-use crate::ty::{FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
-
-pub mod abi;
-#[macro_use]
-pub mod crate_def;
-pub mod compiler_interface;
-#[macro_use]
-pub mod error;
-pub mod mir;
-pub mod target;
-pub mod ty;
-pub mod visitor;
-
-/// Use String for now but we should replace it.
-pub type Symbol = String;
-
-/// The number that identifies a crate.
-pub type CrateNum = usize;
-
-impl Debug for DefId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("DefId").field("id", &self.0).field("name", &self.name()).finish()
-    }
-}
-
-impl IndexedVal for DefId {
-    fn to_val(index: usize) -> Self {
-        DefId(index)
-    }
-
-    fn to_index(&self) -> usize {
-        self.0
-    }
-}
-
-/// A list of crate items.
-pub type CrateItems = Vec<CrateItem>;
-
-/// A list of trait decls.
-pub type TraitDecls = Vec<TraitDef>;
-
-/// A list of impl trait decls.
-pub type ImplTraitDecls = Vec<ImplDef>;
-
-/// Holds information about a crate.
-#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
-pub struct Crate {
-    pub id: CrateNum,
-    pub name: Symbol,
-    pub is_local: bool,
-}
-
-impl Crate {
-    /// The list of foreign modules in this crate.
-    pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> {
-        with(|cx| cx.foreign_modules(self.id))
-    }
-
-    /// The list of traits declared in this crate.
-    pub fn trait_decls(&self) -> TraitDecls {
-        with(|cx| cx.trait_decls(self.id))
-    }
-
-    /// The list of trait implementations in this crate.
-    pub fn trait_impls(&self) -> ImplTraitDecls {
-        with(|cx| cx.trait_impls(self.id))
-    }
-
-    /// Return a list of function definitions from this crate independent on their visibility.
-    pub fn fn_defs(&self) -> Vec<FnDef> {
-        with(|cx| cx.crate_functions(self.id))
-    }
-
-    /// Return a list of static items defined in this crate independent on their visibility.
-    pub fn statics(&self) -> Vec<StaticDef> {
-        with(|cx| cx.crate_statics(self.id))
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
-pub enum ItemKind {
-    Fn,
-    Static,
-    Const,
-    Ctor(CtorKind),
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
-pub enum CtorKind {
-    Const,
-    Fn,
-}
-
-pub type Filename = String;
-
-crate_def_with_ty! {
-    /// Holds information about an item in a crate.
-    #[derive(Serialize)]
-    pub CrateItem;
-}
-
-impl CrateItem {
-    /// This will return the body of an item or panic if it's not available.
-    pub fn expect_body(&self) -> mir::Body {
-        with(|cx| cx.mir_body(self.0))
-    }
-
-    /// Return the body of an item if available.
-    pub fn body(&self) -> Option<mir::Body> {
-        with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
-    }
-
-    /// Check if a body is available for this item.
-    pub fn has_body(&self) -> bool {
-        with(|cx| cx.has_body(self.0))
-    }
-
-    pub fn span(&self) -> Span {
-        with(|cx| cx.span_of_an_item(self.0))
-    }
-
-    pub fn kind(&self) -> ItemKind {
-        with(|cx| cx.item_kind(*self))
-    }
-
-    pub fn requires_monomorphization(&self) -> bool {
-        with(|cx| cx.requires_monomorphization(self.0))
-    }
-
-    pub fn ty(&self) -> Ty {
-        with(|cx| cx.def_ty(self.0))
-    }
-
-    pub fn is_foreign_item(&self) -> bool {
-        with(|cx| cx.is_foreign_item(self.0))
-    }
-
-    /// Emit MIR for this item body.
-    pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
-        self.body()
-            .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
-            .dump(w, &self.name())
-    }
-}
-
-/// Return the function where execution starts if the current
-/// crate defines that. This is usually `main`, but could be
-/// `start` if the crate is a no-std crate.
-pub fn entry_fn() -> Option<CrateItem> {
-    with(|cx| cx.entry_fn())
-}
-
-/// Access to the local crate.
-pub fn local_crate() -> Crate {
-    with(|cx| cx.local_crate())
-}
-
-/// Try to find a crate or crates if multiple crates exist from given name.
-pub fn find_crates(name: &str) -> Vec<Crate> {
-    with(|cx| cx.find_crates(name))
-}
-
-/// Try to find a crate with the given name.
-pub fn external_crates() -> Vec<Crate> {
-    with(|cx| cx.external_crates())
-}
-
-/// Retrieve all items in the local crate that have a MIR associated with them.
-pub fn all_local_items() -> CrateItems {
-    with(|cx| cx.all_local_items())
-}
-
-pub fn all_trait_decls() -> TraitDecls {
-    with(|cx| cx.all_trait_decls())
-}
-
-pub fn all_trait_impls() -> ImplTraitDecls {
-    with(|cx| cx.all_trait_impls())
-}
-
-/// A type that provides internal information but that can still be used for debug purpose.
-#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
-pub struct Opaque(String);
-
-impl std::fmt::Display for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
-
-impl std::fmt::Debug for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
+//! This is a transitional measure as described in [PR #139319](https://github.com/rust-lang/rust/pull/139319).
+//! Once the refactoring is complete, the `stable_mir` implementation will be moved back here.
 
-pub fn opaque<T: Debug>(value: &T) -> Opaque {
-    Opaque(format!("{value:?}"))
-}
+pub use rustc_smir::stable_mir::*;
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 6b1a0a08055..23d9d926eba 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -89,9 +89,9 @@ dependencies = [
 
 [[package]]
 name = "dlmalloc"
-version = "0.2.7"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b5e0d321d61de16390ed273b647ce51605b575916d3c25e6ddf27a1e140035"
+checksum = "8cff88b751e7a276c4ab0e222c3f355190adc6dde9ce39c851db39da34990df7"
 dependencies = [
  "cfg-if",
  "compiler_builtins",
@@ -176,9 +176,9 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.3"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
+checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
 dependencies = [
  "adler2",
  "compiler_builtins",
@@ -223,9 +223,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.93"
+version = "1.0.94"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
 dependencies = [
  "unicode-ident",
 ]
@@ -247,9 +247,9 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
 dependencies = [
  "proc-macro2",
 ]
@@ -287,12 +287,9 @@ dependencies = [
 
 [[package]]
 name = "rand_core"
-version = "0.9.0"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
-dependencies = [
- "zerocopy",
-]
+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
 
 [[package]]
 name = "rand_xorshift"
@@ -382,9 +379,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.98"
+version = "2.0.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -413,9 +410,9 @@ dependencies = [
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.16"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "unicode-width"
@@ -540,18 +537,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
 name = "zerocopy"
-version = "0.8.17"
+version = "0.8.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713"
+checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
 dependencies = [
  "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.8.17"
+version = "0.8.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626"
+checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/library/Cargo.toml b/library/Cargo.toml
index 4d5955593ff..026ba147008 100644
--- a/library/Cargo.toml
+++ b/library/Cargo.toml
@@ -38,8 +38,11 @@ adler2.debug = 0
 gimli.debug = 0
 gimli.opt-level = "s"
 miniz_oxide.debug = 0
+miniz_oxide.opt-level = "s"
+# `opt-level = "s"` for `object` led to a size regression when tried previously
 object.debug = 0
 rustc-demangle.debug = 0
+rustc-demangle.opt-level = "s"
 
 [patch.crates-io]
 # See comments in `library/rustc-std-workspace-core/README.md` for what's going on
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index b729d5e116d..1d2dd1e6081 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -36,5 +36,4 @@ check-cfg = [
     'cfg(no_global_oom_handling)',
     'cfg(no_rc)',
     'cfg(no_sync)',
-    'cfg(randomized_layouts)',
 ]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index c62f8e5b70f..be581661f4c 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -20,7 +20,7 @@ use core::iter;
 use core::marker::{PhantomData, Unsize};
 use core::mem::{self, ManuallyDrop, align_of_val_raw};
 use core::num::NonZeroUsize;
-use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, LegacyReceiver};
+use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver};
 use core::panic::{RefUnwindSafe, UnwindSafe};
 use core::pin::{Pin, PinCoerceUnsized};
 use core::ptr::{self, NonNull};
@@ -4066,3 +4066,413 @@ impl<T: core::error::Error + ?Sized> core::error::Error for Arc<T> {
         core::error::Error::provide(&**self, req);
     }
 }
+
+/// A uniquely owned [`Arc`].
+///
+/// This represents an `Arc` that is known to be uniquely owned -- that is, have exactly one strong
+/// reference. Multiple weak pointers can be created, but attempts to upgrade those to strong
+/// references will fail unless the `UniqueArc` they point to has been converted into a regular `Arc`.
+///
+/// Because it is uniquely owned, the contents of a `UniqueArc` can be freely mutated. A common
+/// use case is to have an object be mutable during its initialization phase but then have it become
+/// immutable and converted to a normal `Arc`.
+///
+/// This can be used as a flexible way to create cyclic data structures, as in the example below.
+///
+/// ```
+/// #![feature(unique_rc_arc)]
+/// use std::sync::{Arc, Weak, UniqueArc};
+///
+/// struct Gadget {
+///     me: Weak<Gadget>,
+/// }
+///
+/// fn create_gadget() -> Option<Arc<Gadget>> {
+///     let mut rc = UniqueArc::new(Gadget {
+///         me: Weak::new(),
+///     });
+///     rc.me = UniqueArc::downgrade(&rc);
+///     Some(UniqueArc::into_arc(rc))
+/// }
+///
+/// create_gadget().unwrap();
+/// ```
+///
+/// An advantage of using `UniqueArc` over [`Arc::new_cyclic`] to build cyclic data structures is that
+/// [`Arc::new_cyclic`]'s `data_fn` parameter cannot be async or return a [`Result`]. As shown in the
+/// previous example, `UniqueArc` allows for more flexibility in the construction of cyclic data,
+/// including fallible or async constructors.
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+pub struct UniqueArc<
+    T: ?Sized,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    ptr: NonNull<ArcInner<T>>,
+    // Define the ownership of `ArcInner<T>` for drop-check
+    _marker: PhantomData<ArcInner<T>>,
+    // Invariance is necessary for soundness: once other `Weak`
+    // references exist, we already have a form of shared mutability!
+    _marker2: PhantomData<*mut T>,
+    alloc: A,
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+unsafe impl<T: ?Sized + Sync + Send, A: Allocator + Send> Send for UniqueArc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+unsafe impl<T: ?Sized + Sync + Send, A: Allocator + Sync> Sync for UniqueArc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+// #[unstable(feature = "coerce_unsized", issue = "18598")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<UniqueArc<U, A>>
+    for UniqueArc<T, A>
+{
+}
+
+//#[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<UniqueArc<U>> for UniqueArc<T> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + fmt::Display, A: Allocator> fmt::Display for UniqueArc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for UniqueArc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> fmt::Pointer for UniqueArc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Pointer::fmt(&(&raw const **self), f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for UniqueArc<T, A> {
+    fn borrow(&self) -> &T {
+        &**self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for UniqueArc<T, A> {
+    fn borrow_mut(&mut self) -> &mut T {
+        &mut **self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> AsRef<T> for UniqueArc<T, A> {
+    fn as_ref(&self) -> &T {
+        &**self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> AsMut<T> for UniqueArc<T, A> {
+    fn as_mut(&mut self) -> &mut T {
+        &mut **self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> Unpin for UniqueArc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for UniqueArc<T, A> {
+    /// Equality for two `UniqueArc`s.
+    ///
+    /// Two `UniqueArc`s are equal if their inner values are equal.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::sync::UniqueArc;
+    ///
+    /// let five = UniqueArc::new(5);
+    ///
+    /// assert!(five == UniqueArc::new(5));
+    /// ```
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for UniqueArc<T, A> {
+    /// Partial comparison for two `UniqueArc`s.
+    ///
+    /// The two are compared by calling `partial_cmp()` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::sync::UniqueArc;
+    /// use std::cmp::Ordering;
+    ///
+    /// let five = UniqueArc::new(5);
+    ///
+    /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueArc::new(6)));
+    /// ```
+    #[inline(always)]
+    fn partial_cmp(&self, other: &UniqueArc<T, A>) -> Option<Ordering> {
+        (**self).partial_cmp(&**other)
+    }
+
+    /// Less-than comparison for two `UniqueArc`s.
+    ///
+    /// The two are compared by calling `<` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::sync::UniqueArc;
+    ///
+    /// let five = UniqueArc::new(5);
+    ///
+    /// assert!(five < UniqueArc::new(6));
+    /// ```
+    #[inline(always)]
+    fn lt(&self, other: &UniqueArc<T, A>) -> bool {
+        **self < **other
+    }
+
+    /// 'Less than or equal to' comparison for two `UniqueArc`s.
+    ///
+    /// The two are compared by calling `<=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::sync::UniqueArc;
+    ///
+    /// let five = UniqueArc::new(5);
+    ///
+    /// assert!(five <= UniqueArc::new(5));
+    /// ```
+    #[inline(always)]
+    fn le(&self, other: &UniqueArc<T, A>) -> bool {
+        **self <= **other
+    }
+
+    /// Greater-than comparison for two `UniqueArc`s.
+    ///
+    /// The two are compared by calling `>` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::sync::UniqueArc;
+    ///
+    /// let five = UniqueArc::new(5);
+    ///
+    /// assert!(five > UniqueArc::new(4));
+    /// ```
+    #[inline(always)]
+    fn gt(&self, other: &UniqueArc<T, A>) -> bool {
+        **self > **other
+    }
+
+    /// 'Greater than or equal to' comparison for two `UniqueArc`s.
+    ///
+    /// The two are compared by calling `>=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::sync::UniqueArc;
+    ///
+    /// let five = UniqueArc::new(5);
+    ///
+    /// assert!(five >= UniqueArc::new(5));
+    /// ```
+    #[inline(always)]
+    fn ge(&self, other: &UniqueArc<T, A>) -> bool {
+        **self >= **other
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Ord, A: Allocator> Ord for UniqueArc<T, A> {
+    /// Comparison for two `UniqueArc`s.
+    ///
+    /// The two are compared by calling `cmp()` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::sync::UniqueArc;
+    /// use std::cmp::Ordering;
+    ///
+    /// let five = UniqueArc::new(5);
+    ///
+    /// assert_eq!(Ordering::Less, five.cmp(&UniqueArc::new(6)));
+    /// ```
+    #[inline]
+    fn cmp(&self, other: &UniqueArc<T, A>) -> Ordering {
+        (**self).cmp(&**other)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Eq, A: Allocator> Eq for UniqueArc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Hash, A: Allocator> Hash for UniqueArc<T, A> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (**self).hash(state);
+    }
+}
+
+impl<T> UniqueArc<T, Global> {
+    /// Creates a new `UniqueArc`.
+    ///
+    /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading
+    /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`].
+    /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will
+    /// point to the new [`Arc`].
+    #[cfg(not(no_global_oom_handling))]
+    #[unstable(feature = "unique_rc_arc", issue = "112566")]
+    #[must_use]
+    pub fn new(value: T) -> Self {
+        Self::new_in(value, Global)
+    }
+}
+
+impl<T, A: Allocator> UniqueArc<T, A> {
+    /// Creates a new `UniqueArc` in the provided allocator.
+    ///
+    /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading
+    /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`].
+    /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will
+    /// point to the new [`Arc`].
+    #[cfg(not(no_global_oom_handling))]
+    #[unstable(feature = "unique_rc_arc", issue = "112566")]
+    #[must_use]
+    // #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn new_in(data: T, alloc: A) -> Self {
+        let (ptr, alloc) = Box::into_unique(Box::new_in(
+            ArcInner {
+                strong: atomic::AtomicUsize::new(0),
+                // keep one weak reference so if all the weak pointers that are created are dropped
+                // the UniqueArc still stays valid.
+                weak: atomic::AtomicUsize::new(1),
+                data,
+            },
+            alloc,
+        ));
+        Self { ptr: ptr.into(), _marker: PhantomData, _marker2: PhantomData, alloc }
+    }
+}
+
+impl<T: ?Sized, A: Allocator> UniqueArc<T, A> {
+    /// Converts the `UniqueArc` into a regular [`Arc`].
+    ///
+    /// This consumes the `UniqueArc` and returns a regular [`Arc`] that contains the `value` that
+    /// is passed to `into_arc`.
+    ///
+    /// Any weak references created before this method is called can now be upgraded to strong
+    /// references.
+    #[unstable(feature = "unique_rc_arc", issue = "112566")]
+    #[must_use]
+    pub fn into_arc(this: Self) -> Arc<T, A> {
+        let this = ManuallyDrop::new(this);
+
+        // Move the allocator out.
+        // SAFETY: `this.alloc` will not be accessed again, nor dropped because it is in
+        // a `ManuallyDrop`.
+        let alloc: A = unsafe { ptr::read(&this.alloc) };
+
+        // SAFETY: This pointer was allocated at creation time so we know it is valid.
+        unsafe {
+            // Convert our weak reference into a strong reference
+            (*this.ptr.as_ptr()).strong.store(1, Release);
+            Arc::from_inner_in(this.ptr, alloc)
+        }
+    }
+}
+
+impl<T: ?Sized, A: Allocator + Clone> UniqueArc<T, A> {
+    /// Creates a new weak reference to the `UniqueArc`.
+    ///
+    /// Attempting to upgrade this weak reference will fail before the `UniqueArc` has been converted
+    /// to a [`Arc`] using [`UniqueArc::into_arc`].
+    #[unstable(feature = "unique_rc_arc", issue = "112566")]
+    #[must_use]
+    pub fn downgrade(this: &Self) -> Weak<T, A> {
+        // Using a relaxed ordering is alright here, as knowledge of the
+        // original reference prevents other threads from erroneously deleting
+        // the object or converting the object to a normal `Arc<T, A>`.
+        //
+        // Note that we don't need to test if the weak counter is locked because there
+        // are no such operations like `Arc::get_mut` or `Arc::make_mut` that will lock
+        // the weak counter.
+        //
+        // SAFETY: This pointer was allocated at creation time so we know it is valid.
+        let old_size = unsafe { (*this.ptr.as_ptr()).weak.fetch_add(1, Relaxed) };
+
+        // See comments in Arc::clone() for why we do this (for mem::forget).
+        if old_size > MAX_REFCOUNT {
+            abort();
+        }
+
+        Weak { ptr: this.ptr, alloc: this.alloc.clone() }
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> Deref for UniqueArc<T, A> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        // SAFETY: This pointer was allocated at creation time so we know it is valid.
+        unsafe { &self.ptr.as_ref().data }
+    }
+}
+
+// #[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
+unsafe impl<T: ?Sized> PinCoerceUnsized for UniqueArc<T> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> DerefMut for UniqueArc<T, A> {
+    fn deref_mut(&mut self) -> &mut T {
+        // SAFETY: This pointer was allocated at creation time so we know it is valid. We know we
+        // have unique ownership and therefore it's safe to make a mutable reference because
+        // `UniqueArc` owns the only strong reference to itself.
+        // We also need to be careful to only create a mutable reference to the `data` field,
+        // as a mutable reference to the entire `ArcInner` would assert uniqueness over the
+        // ref count fields too, invalidating any attempt by `Weak`s to access the ref count.
+        unsafe { &mut (*self.ptr.as_ptr()).data }
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+// #[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<T: ?Sized, A: Allocator> DerefPure for UniqueArc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueArc<T, A> {
+    fn drop(&mut self) {
+        // See `Arc::drop_slow` which drops an `Arc` with a strong count of 0.
+        // SAFETY: This pointer was allocated at creation time so we know it is valid.
+        let _weak = Weak { ptr: self.ptr, alloc: &self.alloc };
+
+        unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) };
+    }
+}
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 3782f9e9519..633ef717e04 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -3360,10 +3360,6 @@ impl<T: Hash, A: Allocator> Hash for Vec<T, A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(
-    message = "vector indices are of type `usize` or ranges of `usize`",
-    label = "vector indices are of type `usize` or ranges of `usize`"
-)]
 impl<T, I: SliceIndex<[T]>, A: Allocator> Index<I> for Vec<T, A> {
     type Output = I::Output;
 
@@ -3374,10 +3370,6 @@ impl<T, I: SliceIndex<[T]>, A: Allocator> Index<I> for Vec<T, A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(
-    message = "vector indices are of type `usize` or ranges of `usize`",
-    label = "vector indices are of type `usize` or ranges of `usize`"
-)]
 impl<T, I: SliceIndex<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut Self::Output {
diff --git a/library/alloctests/tests/arc.rs b/library/alloctests/tests/arc.rs
index 0baa50f439b..00bdf527133 100644
--- a/library/alloctests/tests/arc.rs
+++ b/library/alloctests/tests/arc.rs
@@ -1,7 +1,7 @@
 use std::any::Any;
 use std::cell::{Cell, RefCell};
 use std::iter::TrustedLen;
-use std::sync::{Arc, Weak};
+use std::sync::{Arc, UniqueArc, Weak};
 
 #[test]
 fn uninhabited() {
@@ -263,9 +263,30 @@ fn make_mut_unsized() {
     assert_eq!(*other_data, [110, 20, 30]);
 }
 
+#[test]
+fn test_unique_arc_weak() {
+    let data = UniqueArc::new(32);
+
+    // Test that `Weak` downgraded from `UniqueArc` cannot be upgraded.
+    let weak = UniqueArc::downgrade(&data);
+    assert_eq!(weak.strong_count(), 0);
+    assert_eq!(weak.weak_count(), 0);
+    assert!(weak.upgrade().is_none());
+
+    // Test that `Weak` can now be upgraded after the `UniqueArc` being converted to `Arc`.
+    let strong = UniqueArc::into_arc(data);
+    assert_eq!(*strong, 32);
+    assert_eq!(weak.strong_count(), 1);
+    assert_eq!(weak.weak_count(), 1);
+    let upgraded = weak.upgrade().unwrap();
+    assert_eq!(*upgraded, 32);
+    assert_eq!(weak.strong_count(), 2);
+    assert_eq!(weak.weak_count(), 1);
+}
+
 #[allow(unused)]
 mod pin_coerce_unsized {
-    use alloc::sync::Arc;
+    use alloc::sync::{Arc, UniqueArc};
     use core::pin::Pin;
 
     pub trait MyTrait {}
@@ -275,4 +296,7 @@ mod pin_coerce_unsized {
     pub fn pin_arc(arg: Pin<Arc<String>>) -> Pin<Arc<dyn MyTrait>> {
         arg
     }
+    pub fn pin_unique_arc(arg: Pin<UniqueArc<String>>) -> Pin<UniqueArc<dyn MyTrait>> {
+        arg
+    }
 }
diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs
index 46c11ea150b..f1f4cc6f93b 100644
--- a/library/alloctests/tests/lib.rs
+++ b/library/alloctests/tests/lib.rs
@@ -63,6 +63,7 @@ mod fmt;
 mod heap;
 mod linked_list;
 mod misc_tests;
+mod num;
 mod rc;
 mod slice;
 mod sort;
diff --git a/library/alloctests/tests/num.rs b/library/alloctests/tests/num.rs
new file mode 100644
index 00000000000..3c76e68c606
--- /dev/null
+++ b/library/alloctests/tests/num.rs
@@ -0,0 +1,69 @@
+use std::fmt::{Debug, Display};
+use std::str::FromStr;
+
+fn assert_nb<Int: ToString + FromStr + Debug + Display + Eq>(value: Int) {
+    let s = value.to_string();
+    let s2 = format!("s: {}.", value);
+
+    assert_eq!(format!("s: {s}."), s2);
+    let Ok(ret) = Int::from_str(&s) else {
+        panic!("failed to convert into to string");
+    };
+    assert_eq!(ret, value);
+}
+
+macro_rules! uint_to_s {
+    ($($fn_name:ident, $int:ident,)+) => {
+        $(
+            #[test]
+            fn $fn_name() {
+                assert_nb::<$int>($int::MIN);
+                assert_nb::<$int>($int::MAX);
+                assert_nb::<$int>(1);
+                assert_nb::<$int>($int::MIN / 2);
+                assert_nb::<$int>($int::MAX / 2);
+            }
+        )+
+    }
+}
+macro_rules! int_to_s {
+    ($($fn_name:ident, $int:ident,)+) => {
+        $(
+            #[test]
+            fn $fn_name() {
+                assert_nb::<$int>($int::MIN);
+                assert_nb::<$int>($int::MAX);
+                assert_nb::<$int>(1);
+                assert_nb::<$int>(0);
+                assert_nb::<$int>(-1);
+                assert_nb::<$int>($int::MIN / 2);
+                assert_nb::<$int>($int::MAX / 2);
+            }
+        )+
+    }
+}
+
+int_to_s!(
+    test_i8_to_string,
+    i8,
+    test_i16_to_string,
+    i16,
+    test_i32_to_string,
+    i32,
+    test_i64_to_string,
+    i64,
+    test_i128_to_string,
+    i128,
+);
+uint_to_s!(
+    test_u8_to_string,
+    u8,
+    test_u16_to_string,
+    u16,
+    test_u32_to_string,
+    u32,
+    test_u64_to_string,
+    u64,
+    test_u128_to_string,
+    u128,
+);
diff --git a/library/core/src/bstr.rs b/library/core/src/bstr/mod.rs
index ae84fd8adb6..c8d0c701ba8 100644
--- a/library/core/src/bstr.rs
+++ b/library/core/src/bstr/mod.rs
@@ -1,12 +1,13 @@
 //! The `ByteStr` type and trait implementations.
 
+mod traits;
+
+#[unstable(feature = "bstr_internals", issue = "none")]
+pub use traits::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord};
+
 use crate::borrow::{Borrow, BorrowMut};
-use crate::cmp::Ordering;
-use crate::ops::{
-    Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive,
-    RangeTo, RangeToInclusive,
-};
-use crate::{fmt, hash};
+use crate::fmt;
+use crate::ops::{Deref, DerefMut, DerefPure};
 
 /// A wrapper for `&[u8]` representing a human-readable string that's conventionally, but not
 /// always, UTF-8.
@@ -91,6 +92,13 @@ impl ByteStr {
     pub fn as_bytes(&self) -> &[u8] {
         &self.0
     }
+
+    #[doc(hidden)]
+    #[unstable(feature = "bstr_internals", issue = "none")]
+    #[inline]
+    pub fn as_bytes_mut(&mut self) -> &mut [u8] {
+        &mut self.0
+    }
 }
 
 #[unstable(feature = "bstr", issue = "134915")]
@@ -296,273 +304,6 @@ impl<'a> Default for &'a mut ByteStr {
 // }
 
 #[unstable(feature = "bstr", issue = "134915")]
-impl hash::Hash for ByteStr {
-    #[inline]
-    fn hash<H: hash::Hasher>(&self, state: &mut H) {
-        self.0.hash(state);
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<usize> for ByteStr {
-    type Output = u8;
-
-    #[inline]
-    fn index(&self, idx: usize) -> &u8 {
-        &self.0[idx]
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeFull> for ByteStr {
-    type Output = ByteStr;
-
-    #[inline]
-    fn index(&self, _: RangeFull) -> &ByteStr {
-        self
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<Range<usize>> for ByteStr {
-    type Output = ByteStr;
-
-    #[inline]
-    fn index(&self, r: Range<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeInclusive<usize>> for ByteStr {
-    type Output = ByteStr;
-
-    #[inline]
-    fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeFrom<usize>> for ByteStr {
-    type Output = ByteStr;
-
-    #[inline]
-    fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeTo<usize>> for ByteStr {
-    type Output = ByteStr;
-
-    #[inline]
-    fn index(&self, r: RangeTo<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeToInclusive<usize>> for ByteStr {
-    type Output = ByteStr;
-
-    #[inline]
-    fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<usize> for ByteStr {
-    #[inline]
-    fn index_mut(&mut self, idx: usize) -> &mut u8 {
-        &mut self.0[idx]
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeFull> for ByteStr {
-    #[inline]
-    fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
-        self
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<Range<usize>> for ByteStr {
-    #[inline]
-    fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeInclusive<usize>> for ByteStr {
-    #[inline]
-    fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeFrom<usize>> for ByteStr {
-    #[inline]
-    fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeTo<usize>> for ByteStr {
-    #[inline]
-    fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeToInclusive<usize>> for ByteStr {
-    #[inline]
-    fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Eq for ByteStr {}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl PartialEq<ByteStr> for ByteStr {
-    #[inline]
-    fn eq(&self, other: &ByteStr) -> bool {
-        &self.0 == &other.0
-    }
-}
-
-#[doc(hidden)]
-#[macro_export]
-#[unstable(feature = "bstr_internals", issue = "none")]
-macro_rules! impl_partial_eq {
-    ($lhs:ty, $rhs:ty) => {
-        #[allow(unused_lifetimes)]
-        impl<'a> PartialEq<$rhs> for $lhs {
-            #[inline]
-            fn eq(&self, other: &$rhs) -> bool {
-                let other: &[u8] = other.as_ref();
-                PartialEq::eq(self.as_bytes(), other)
-            }
-        }
-
-        #[allow(unused_lifetimes)]
-        impl<'a> PartialEq<$lhs> for $rhs {
-            #[inline]
-            fn eq(&self, other: &$lhs) -> bool {
-                let this: &[u8] = self.as_ref();
-                PartialEq::eq(this, other.as_bytes())
-            }
-        }
-    };
-}
-
-#[doc(hidden)]
-#[unstable(feature = "bstr_internals", issue = "none")]
-pub use impl_partial_eq;
-
-#[doc(hidden)]
-#[macro_export]
-#[unstable(feature = "bstr_internals", issue = "none")]
-macro_rules! impl_partial_eq_ord {
-    ($lhs:ty, $rhs:ty) => {
-        $crate::bstr::impl_partial_eq!($lhs, $rhs);
-
-        #[allow(unused_lifetimes)]
-        #[unstable(feature = "bstr", issue = "134915")]
-        impl<'a> PartialOrd<$rhs> for $lhs {
-            #[inline]
-            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
-                let other: &[u8] = other.as_ref();
-                PartialOrd::partial_cmp(self.as_bytes(), other)
-            }
-        }
-
-        #[allow(unused_lifetimes)]
-        #[unstable(feature = "bstr", issue = "134915")]
-        impl<'a> PartialOrd<$lhs> for $rhs {
-            #[inline]
-            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
-                let this: &[u8] = self.as_ref();
-                PartialOrd::partial_cmp(this, other.as_bytes())
-            }
-        }
-    };
-}
-
-#[doc(hidden)]
-#[unstable(feature = "bstr_internals", issue = "none")]
-pub use impl_partial_eq_ord;
-
-#[doc(hidden)]
-#[macro_export]
-#[unstable(feature = "bstr_internals", issue = "none")]
-macro_rules! impl_partial_eq_n {
-    ($lhs:ty, $rhs:ty) => {
-        #[allow(unused_lifetimes)]
-        #[unstable(feature = "bstr", issue = "134915")]
-        impl<const N: usize> PartialEq<$rhs> for $lhs {
-            #[inline]
-            fn eq(&self, other: &$rhs) -> bool {
-                let other: &[u8] = other.as_ref();
-                PartialEq::eq(self.as_bytes(), other)
-            }
-        }
-
-        #[allow(unused_lifetimes)]
-        #[unstable(feature = "bstr", issue = "134915")]
-        impl<const N: usize> PartialEq<$lhs> for $rhs {
-            #[inline]
-            fn eq(&self, other: &$lhs) -> bool {
-                let this: &[u8] = self.as_ref();
-                PartialEq::eq(this, other.as_bytes())
-            }
-        }
-    };
-}
-
-#[doc(hidden)]
-#[unstable(feature = "bstr_internals", issue = "none")]
-pub use impl_partial_eq_n;
-
-// PartialOrd with `[u8]` omitted to avoid inference failures
-impl_partial_eq!(ByteStr, [u8]);
-// PartialOrd with `&[u8]` omitted to avoid inference failures
-impl_partial_eq!(ByteStr, &[u8]);
-// PartialOrd with `str` omitted to avoid inference failures
-impl_partial_eq!(ByteStr, str);
-// PartialOrd with `&str` omitted to avoid inference failures
-impl_partial_eq!(ByteStr, &str);
-// PartialOrd with `[u8; N]` omitted to avoid inference failures
-impl_partial_eq_n!(ByteStr, [u8; N]);
-// PartialOrd with `[u8; N]` omitted to avoid inference failures
-impl_partial_eq_n!(ByteStr, &[u8; N]);
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Ord for ByteStr {
-    #[inline]
-    fn cmp(&self, other: &ByteStr) -> Ordering {
-        Ord::cmp(&self.0, &other.0)
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl PartialOrd for ByteStr {
-    #[inline]
-    fn partial_cmp(&self, other: &ByteStr) -> Option<Ordering> {
-        PartialOrd::partial_cmp(&self.0, &other.0)
-    }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
 impl<'a> TryFrom<&'a ByteStr> for &'a str {
     type Error = crate::str::Utf8Error;
 
diff --git a/library/core/src/bstr/traits.rs b/library/core/src/bstr/traits.rs
new file mode 100644
index 00000000000..ff46bb13ba4
--- /dev/null
+++ b/library/core/src/bstr/traits.rs
@@ -0,0 +1,277 @@
+//! Trait implementations for `ByteStr`.
+
+use crate::bstr::ByteStr;
+use crate::cmp::Ordering;
+use crate::slice::SliceIndex;
+use crate::{hash, ops, range};
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Ord for ByteStr {
+    #[inline]
+    fn cmp(&self, other: &ByteStr) -> Ordering {
+        Ord::cmp(&self.0, &other.0)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl PartialOrd for ByteStr {
+    #[inline]
+    fn partial_cmp(&self, other: &ByteStr) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&self.0, &other.0)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl PartialEq<ByteStr> for ByteStr {
+    #[inline]
+    fn eq(&self, other: &ByteStr) -> bool {
+        &self.0 == &other.0
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Eq for ByteStr {}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl hash::Hash for ByteStr {
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.0.hash(state);
+    }
+}
+
+#[doc(hidden)]
+#[macro_export]
+#[unstable(feature = "bstr_internals", issue = "none")]
+macro_rules! impl_partial_eq {
+    ($lhs:ty, $rhs:ty) => {
+        #[allow(unused_lifetimes)]
+        impl<'a> PartialEq<$rhs> for $lhs {
+            #[inline]
+            fn eq(&self, other: &$rhs) -> bool {
+                let other: &[u8] = other.as_ref();
+                PartialEq::eq(self.as_bytes(), other)
+            }
+        }
+
+        #[allow(unused_lifetimes)]
+        impl<'a> PartialEq<$lhs> for $rhs {
+            #[inline]
+            fn eq(&self, other: &$lhs) -> bool {
+                let this: &[u8] = self.as_ref();
+                PartialEq::eq(this, other.as_bytes())
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[unstable(feature = "bstr_internals", issue = "none")]
+pub use impl_partial_eq;
+
+#[doc(hidden)]
+#[macro_export]
+#[unstable(feature = "bstr_internals", issue = "none")]
+macro_rules! impl_partial_eq_ord {
+    ($lhs:ty, $rhs:ty) => {
+        $crate::bstr::impl_partial_eq!($lhs, $rhs);
+
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<'a> PartialOrd<$rhs> for $lhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
+                let other: &[u8] = other.as_ref();
+                PartialOrd::partial_cmp(self.as_bytes(), other)
+            }
+        }
+
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<'a> PartialOrd<$lhs> for $rhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
+                let this: &[u8] = self.as_ref();
+                PartialOrd::partial_cmp(this, other.as_bytes())
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[unstable(feature = "bstr_internals", issue = "none")]
+pub use impl_partial_eq_ord;
+
+#[doc(hidden)]
+#[macro_export]
+#[unstable(feature = "bstr_internals", issue = "none")]
+macro_rules! impl_partial_eq_n {
+    ($lhs:ty, $rhs:ty) => {
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<const N: usize> PartialEq<$rhs> for $lhs {
+            #[inline]
+            fn eq(&self, other: &$rhs) -> bool {
+                let other: &[u8] = other.as_ref();
+                PartialEq::eq(self.as_bytes(), other)
+            }
+        }
+
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<const N: usize> PartialEq<$lhs> for $rhs {
+            #[inline]
+            fn eq(&self, other: &$lhs) -> bool {
+                let this: &[u8] = self.as_ref();
+                PartialEq::eq(this, other.as_bytes())
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[unstable(feature = "bstr_internals", issue = "none")]
+pub use impl_partial_eq_n;
+
+// PartialOrd with `[u8]` omitted to avoid inference failures
+impl_partial_eq!(ByteStr, [u8]);
+// PartialOrd with `&[u8]` omitted to avoid inference failures
+impl_partial_eq!(ByteStr, &[u8]);
+// PartialOrd with `str` omitted to avoid inference failures
+impl_partial_eq!(ByteStr, str);
+// PartialOrd with `&str` omitted to avoid inference failures
+impl_partial_eq!(ByteStr, &str);
+// PartialOrd with `[u8; N]` omitted to avoid inference failures
+impl_partial_eq_n!(ByteStr, [u8; N]);
+// PartialOrd with `[u8; N]` omitted to avoid inference failures
+impl_partial_eq_n!(ByteStr, &[u8; N]);
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl<I> ops::Index<I> for ByteStr
+where
+    I: SliceIndex<ByteStr>,
+{
+    type Output = I::Output;
+
+    #[inline]
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl<I> ops::IndexMut<I> for ByteStr
+where
+    I: SliceIndex<ByteStr>,
+{
+    #[inline]
+    fn index_mut(&mut self, index: I) -> &mut I::Output {
+        index.index_mut(self)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+unsafe impl SliceIndex<ByteStr> for ops::RangeFull {
+    type Output = ByteStr;
+    #[inline]
+    fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
+        Some(slice)
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
+        Some(slice)
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
+        slice
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
+        slice
+    }
+    #[inline]
+    fn index(self, slice: &ByteStr) -> &Self::Output {
+        slice
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
+        slice
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+unsafe impl SliceIndex<ByteStr> for usize {
+    type Output = u8;
+    #[inline]
+    fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
+        self.get(slice.as_bytes())
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
+        self.get_mut(slice.as_bytes_mut())
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { self.get_unchecked(slice as *const [u8]) }
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { self.get_unchecked_mut(slice as *mut [u8]) }
+    }
+    #[inline]
+    fn index(self, slice: &ByteStr) -> &Self::Output {
+        self.index(slice.as_bytes())
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
+        self.index_mut(slice.as_bytes_mut())
+    }
+}
+
+macro_rules! impl_slice_index {
+    ($index:ty) => {
+        #[unstable(feature = "bstr", issue = "134915")]
+        unsafe impl SliceIndex<ByteStr> for $index {
+            type Output = ByteStr;
+            #[inline]
+            fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
+                self.get(slice.as_bytes()).map(ByteStr::from_bytes)
+            }
+            #[inline]
+            fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
+                self.get_mut(slice.as_bytes_mut()).map(ByteStr::from_bytes_mut)
+            }
+            #[inline]
+            unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
+                // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+                unsafe { self.get_unchecked(slice as *const [u8]) as *const ByteStr }
+            }
+            #[inline]
+            unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
+                // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+                unsafe { self.get_unchecked_mut(slice as *mut [u8]) as *mut ByteStr }
+            }
+            #[inline]
+            fn index(self, slice: &ByteStr) -> &Self::Output {
+                ByteStr::from_bytes(self.index(slice.as_bytes()))
+            }
+            #[inline]
+            fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
+                ByteStr::from_bytes_mut(self.index_mut(slice.as_bytes_mut()))
+            }
+        }
+    };
+}
+
+impl_slice_index!(ops::IndexRange);
+impl_slice_index!(ops::Range<usize>);
+impl_slice_index!(range::Range<usize>);
+impl_slice_index!(ops::RangeTo<usize>);
+impl_slice_index!(ops::RangeFrom<usize>);
+impl_slice_index!(range::RangeFrom<usize>);
+impl_slice_index!(ops::RangeInclusive<usize>);
+impl_slice_index!(range::RangeInclusive<usize>);
+impl_slice_index!(ops::RangeToInclusive<usize>);
+impl_slice_index!((ops::Bound<usize>, ops::Bound<usize>));
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 1a320b316a4..09117e4968d 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -495,7 +495,7 @@ impl<T> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "move_cell", since = "1.17.0")]
-    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    #[rustc_const_stable(feature = "const_cell", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_confusables("swap")]
     pub const fn replace(&self, val: T) -> T {
         // SAFETY: This can cause data races if called from a separate thread,
@@ -537,14 +537,14 @@ impl<T: Copy> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    #[rustc_const_stable(feature = "const_cell", since = "CURRENT_RUSTC_VERSION")]
     pub const fn get(&self) -> T {
         // SAFETY: This can cause data races if called from a separate thread,
         // but `Cell` is `!Sync` so this won't happen.
         unsafe { *self.value.get() }
     }
 
-    /// Updates the contained value using a function and returns the new value.
+    /// Updates the contained value using a function.
     ///
     /// # Examples
     ///
@@ -554,21 +554,14 @@ impl<T: Copy> Cell<T> {
     /// use std::cell::Cell;
     ///
     /// let c = Cell::new(5);
-    /// let new = c.update(|x| x + 1);
-    ///
-    /// assert_eq!(new, 6);
+    /// c.update(|x| x + 1);
     /// assert_eq!(c.get(), 6);
     /// ```
     #[inline]
     #[unstable(feature = "cell_update", issue = "50186")]
-    pub fn update<F>(&self, f: F) -> T
-    where
-        F: FnOnce(T) -> T,
-    {
+    pub fn update(&self, f: impl FnOnce(T) -> T) {
         let old = self.get();
-        let new = f(old);
-        self.set(new);
-        new
+        self.set(f(old));
     }
 }
 
@@ -617,7 +610,7 @@ impl<T: ?Sized> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "cell_get_mut", since = "1.11.0")]
-    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    #[rustc_const_stable(feature = "const_cell", since = "CURRENT_RUSTC_VERSION")]
     pub const fn get_mut(&mut self) -> &mut T {
         self.value.get_mut()
     }
@@ -637,7 +630,7 @@ impl<T: ?Sized> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "as_cell", since = "1.37.0")]
-    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    #[rustc_const_stable(feature = "const_cell", since = "CURRENT_RUSTC_VERSION")]
     pub const fn from_mut(t: &mut T) -> &Cell<T> {
         // SAFETY: `&mut` ensures unique access.
         unsafe { &*(t as *mut T as *const Cell<T>) }
@@ -695,7 +688,7 @@ impl<T> Cell<[T]> {
     /// assert_eq!(slice_cell.len(), 3);
     /// ```
     #[stable(feature = "as_cell", since = "1.37.0")]
-    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    #[rustc_const_stable(feature = "const_cell", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_slice_of_cells(&self) -> &[Cell<T>] {
         // SAFETY: `Cell<T>` has the same memory layout as `T`.
         unsafe { &*(self as *const Cell<[T]> as *const [Cell<T>]) }
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 30fd2d7815f..ec7c1705fb8 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -743,6 +743,7 @@ impl<'a> Arguments<'a> {
     #[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")]
     #[must_use]
     #[inline]
+    #[doc(hidden)]
     pub fn as_statically_known_str(&self) -> Option<&'static str> {
         let s = self.as_str();
         if core::intrinsics::is_val_statically_known(s.is_some()) { s } else { None }
@@ -3016,6 +3017,6 @@ impl<T: ?Sized> Debug for SyncUnsafeCell<T> {
     }
 }
 
-// If you expected tests to be here, look instead at the core/tests/fmt.rs file,
+// If you expected tests to be here, look instead at coretests/tests/fmt/;
 // it's a lot easier than creating all of the rt::Piece structures here.
-// There are also tests in the alloc crate, for those that need allocations.
+// There are also tests in alloctests/tests/fmt.rs, for those that need allocations.
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index d27f7e6e0d8..0b04ebccae2 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -20,8 +20,8 @@ pub struct Placeholder {
     pub width: Count,
 }
 
+#[cfg(bootstrap)]
 impl Placeholder {
-    #[cfg(bootstrap)]
     #[inline]
     pub const fn new(
         position: usize,
@@ -33,12 +33,6 @@ impl Placeholder {
     ) -> Self {
         Self { position, fill, align, flags, precision, width }
     }
-
-    #[cfg(not(bootstrap))]
-    #[inline]
-    pub const fn new(position: usize, flags: u32, precision: Count, width: Count) -> Self {
-        Self { position, flags, precision, width }
-    }
 }
 
 #[cfg(bootstrap)]
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 81e59a1f349..afd6192d7c4 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2475,35 +2475,35 @@ pub unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> In
 
 /// Float addition that allows optimizations based on algebraic rules.
 ///
-/// This intrinsic does not have a stable counterpart.
+/// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`].
 #[rustc_nounwind]
 #[rustc_intrinsic]
 pub fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
 
 /// Float subtraction that allows optimizations based on algebraic rules.
 ///
-/// This intrinsic does not have a stable counterpart.
+/// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`].
 #[rustc_nounwind]
 #[rustc_intrinsic]
 pub fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
 
 /// Float multiplication that allows optimizations based on algebraic rules.
 ///
-/// This intrinsic does not have a stable counterpart.
+/// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`].
 #[rustc_nounwind]
 #[rustc_intrinsic]
 pub fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
 
 /// Float division that allows optimizations based on algebraic rules.
 ///
-/// This intrinsic does not have a stable counterpart.
+/// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`].
 #[rustc_nounwind]
 #[rustc_intrinsic]
 pub fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
 
 /// Float remainder that allows optimizations based on algebraic rules.
 ///
-/// This intrinsic does not have a stable counterpart.
+/// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`].
 #[rustc_nounwind]
 #[rustc_intrinsic]
 pub fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs
index 5b7d95c2f65..12e2b8b393a 100644
--- a/library/core/src/iter/traits/accum.rs
+++ b/library/core/src/iter/traits/accum.rs
@@ -10,7 +10,7 @@ use crate::num::Wrapping;
 /// [`sum()`]: Iterator::sum
 /// [`FromIterator`]: iter::FromIterator
 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-#[rustc_on_unimplemented(
+#[diagnostic::on_unimplemented(
     message = "a value of type `{Self}` cannot be made by summing an iterator over elements of type `{A}`",
     label = "value of type `{Self}` cannot be made by summing a `std::iter::Iterator<Item={A}>`"
 )]
@@ -31,7 +31,7 @@ pub trait Sum<A = Self>: Sized {
 /// [`product()`]: Iterator::product
 /// [`FromIterator`]: iter::FromIterator
 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-#[rustc_on_unimplemented(
+#[diagnostic::on_unimplemented(
     message = "a value of type `{Self}` cannot be made by multiplying all elements of type `{A}` from an iterator",
     label = "value of type `{Self}` cannot be made by multiplying all elements from a `std::iter::Iterator<Item={A}>`"
 )]
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index b17190971c3..08c34e852da 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -1362,4 +1362,54 @@ impl f128 {
         // SAFETY: this is actually a safe intrinsic
         unsafe { intrinsics::copysignf128(self, sign) }
     }
+
+    /// Float addition that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_add(self, rhs: f128) -> f128 {
+        intrinsics::fadd_algebraic(self, rhs)
+    }
+
+    /// Float subtraction that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_sub(self, rhs: f128) -> f128 {
+        intrinsics::fsub_algebraic(self, rhs)
+    }
+
+    /// Float multiplication that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_mul(self, rhs: f128) -> f128 {
+        intrinsics::fmul_algebraic(self, rhs)
+    }
+
+    /// Float division that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_div(self, rhs: f128) -> f128 {
+        intrinsics::fdiv_algebraic(self, rhs)
+    }
+
+    /// Float remainder that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_rem(self, rhs: f128) -> f128 {
+        intrinsics::frem_algebraic(self, rhs)
+    }
 }
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index d20677f43b4..a33e5f53014 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -1338,4 +1338,54 @@ impl f16 {
         // SAFETY: this is actually a safe intrinsic
         unsafe { intrinsics::copysignf16(self, sign) }
     }
+
+    /// Float addition that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_add(self, rhs: f16) -> f16 {
+        intrinsics::fadd_algebraic(self, rhs)
+    }
+
+    /// Float subtraction that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_sub(self, rhs: f16) -> f16 {
+        intrinsics::fsub_algebraic(self, rhs)
+    }
+
+    /// Float multiplication that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_mul(self, rhs: f16) -> f16 {
+        intrinsics::fmul_algebraic(self, rhs)
+    }
+
+    /// Float division that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_div(self, rhs: f16) -> f16 {
+        intrinsics::fdiv_algebraic(self, rhs)
+    }
+
+    /// Float remainder that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_rem(self, rhs: f16) -> f16 {
+        intrinsics::frem_algebraic(self, rhs)
+    }
 }
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 53373584d55..e473fac0393 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1504,4 +1504,54 @@ impl f32 {
         // SAFETY: this is actually a safe intrinsic
         unsafe { intrinsics::copysignf32(self, sign) }
     }
+
+    /// Float addition that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_add(self, rhs: f32) -> f32 {
+        intrinsics::fadd_algebraic(self, rhs)
+    }
+
+    /// Float subtraction that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_sub(self, rhs: f32) -> f32 {
+        intrinsics::fsub_algebraic(self, rhs)
+    }
+
+    /// Float multiplication that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_mul(self, rhs: f32) -> f32 {
+        intrinsics::fmul_algebraic(self, rhs)
+    }
+
+    /// Float division that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_div(self, rhs: f32) -> f32 {
+        intrinsics::fdiv_algebraic(self, rhs)
+    }
+
+    /// Float remainder that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_rem(self, rhs: f32) -> f32 {
+        intrinsics::frem_algebraic(self, rhs)
+    }
 }
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index ca28b40bb3a..6522a80b0b7 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1503,4 +1503,54 @@ impl f64 {
         // SAFETY: this is actually a safe intrinsic
         unsafe { intrinsics::copysignf64(self, sign) }
     }
+
+    /// Float addition that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_add(self, rhs: f64) -> f64 {
+        intrinsics::fadd_algebraic(self, rhs)
+    }
+
+    /// Float subtraction that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_sub(self, rhs: f64) -> f64 {
+        intrinsics::fsub_algebraic(self, rhs)
+    }
+
+    /// Float multiplication that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_mul(self, rhs: f64) -> f64 {
+        intrinsics::fmul_algebraic(self, rhs)
+    }
+
+    /// Float division that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_div(self, rhs: f64) -> f64 {
+        intrinsics::fdiv_algebraic(self, rhs)
+    }
+
+    /// Float remainder that allows optimizations based on algebraic rules.
+    ///
+    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_algebraic", issue = "136469")]
+    #[inline]
+    pub fn algebraic_rem(self, rhs: f64) -> f64 {
+        intrinsics::frem_algebraic(self, rhs)
+    }
 }
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 89c856fe107..369bf18c2b9 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -127,15 +127,13 @@ mod prim_bool {}
 /// [`Result<String, !>`] which we can unpack like this:
 ///
 /// ```
-/// #![feature(exhaustive_patterns)]
 /// use std::str::FromStr;
 /// let Ok(s) = String::from_str("hello");
 /// ```
 ///
-/// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns`
-/// feature is present this means we can exhaustively match on [`Result<T, !>`] by just taking the
-/// [`Ok`] variant. This illustrates another behavior of `!` - it can be used to "delete" certain
-/// enum variants from generic types like `Result`.
+/// Since the [`Err`] variant contains a `!`, it can never occur. This means we can exhaustively
+/// match on [`Result<T, !>`] by just taking the [`Ok`] variant. This illustrates another behavior
+/// of `!` - it can be used to "delete" certain enum variants from generic types like `Result`.
 ///
 /// ## Infinite loops
 ///
@@ -1315,6 +1313,51 @@ mod prim_f16 {}
 /// | `wasm32`, `wasm64` | If all input NaNs are quiet with all-zero payload: None.<br> Otherwise: all possible payloads. |
 ///
 /// For targets not in this table, all payloads are possible.
+///
+/// # Algebraic operators
+///
+/// Algebraic operators of the form `a.algebraic_*(b)` allow the compiler to optimize
+/// floating point operations using all the usual algebraic properties of real numbers --
+/// despite the fact that those properties do *not* hold on floating point numbers.
+/// This can give a great performance boost since it may unlock vectorization.
+///
+/// The exact set of optimizations is unspecified but typically allows combining operations,
+/// rearranging series of operations based on mathematical properties, converting between division
+/// and reciprocal multiplication, and disregarding the sign of zero. This means that the results of
+/// elementary operations may have undefined precision, and "non-mathematical" values
+/// such as NaN, +/-Inf, or -0.0 may behave in unexpected ways, but these operations
+/// will never cause undefined behavior.
+///
+/// Because of the unpredictable nature of compiler optimizations, the same inputs may produce
+/// different results even within a single program run. **Unsafe code must not rely on any property
+/// of the return value for soundness.** However, implementations will generally do their best to
+/// pick a reasonable tradeoff between performance and accuracy of the result.
+///
+/// For example:
+///
+/// ```
+/// # #![feature(float_algebraic)]
+/// # #![allow(unused_assignments)]
+/// # let mut x: f32 = 0.0;
+/// # let a: f32 = 1.0;
+/// # let b: f32 = 2.0;
+/// # let c: f32 = 3.0;
+/// # let d: f32 = 4.0;
+/// x = a.algebraic_add(b).algebraic_add(c).algebraic_add(d);
+/// ```
+///
+/// May be rewritten as:
+///
+/// ```
+/// # #![allow(unused_assignments)]
+/// # let mut x: f32 = 0.0;
+/// # let a: f32 = 1.0;
+/// # let b: f32 = 2.0;
+/// # let c: f32 = 3.0;
+/// # let d: f32 = 4.0;
+/// x = a + b + c + d; // As written
+/// x = (a + c) + (b + d); // Reordered to shorten critical path and enable vectorization
+/// ```
 
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_f32 {}
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 7d0839aff3f..71a84aff246 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -386,7 +386,8 @@ impl<T: ?Sized> *const T {
     /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
-    ///   of the address space.
+    ///   of the address space. Note that "range" here refers to a half-open range as usual in Rust,
+    ///   i.e., `self..result` for non-negative offsets and `result..self` for negative offsets.
     ///
     /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
     /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index b960a3d86be..9e62beb8049 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1574,8 +1574,9 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::replace`]: crate::ptr::replace()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
+    #[rustc_const_stable(feature = "const_inherent_ptr_replace", since = "CURRENT_RUSTC_VERSION")]
     #[inline(always)]
-    pub unsafe fn replace(self, src: T) -> T
+    pub const unsafe fn replace(self, src: T) -> T
     where
         T: Sized,
     {
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index c769ba673c6..e019aafad39 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -1166,7 +1166,8 @@ impl<T: ?Sized> NonNull<T> {
     /// [`ptr::replace`]: crate::ptr::replace()
     #[inline(always)]
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    pub unsafe fn replace(self, src: T) -> T
+    #[rustc_const_stable(feature = "const_inherent_ptr_replace", since = "CURRENT_RUSTC_VERSION")]
+    pub const unsafe fn replace(self, src: T) -> T
     where
         T: Sized,
     {
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index a687ed7129d..f507ee563ac 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -93,9 +93,9 @@ unsafe impl<T: Sync> Send for Iter<'_, T> {}
 
 impl<'a, T> Iter<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a [T]) -> Self {
+    pub(super) const fn new(slice: &'a [T]) -> Self {
         let len = slice.len();
-        let ptr: NonNull<T> = NonNull::from(slice).cast();
+        let ptr: NonNull<T> = NonNull::from_ref(slice).cast();
         // SAFETY: Similar to `IterMut::new`.
         unsafe {
             let end_or_len =
@@ -218,9 +218,9 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
 
 impl<'a, T> IterMut<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a mut [T]) -> Self {
+    pub(super) const fn new(slice: &'a mut [T]) -> Self {
         let len = slice.len();
-        let ptr: NonNull<T> = NonNull::from(slice).cast();
+        let ptr: NonNull<T> = NonNull::from_mut(slice).cast();
         // SAFETY: There are several things here:
         //
         // `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
@@ -1335,7 +1335,7 @@ pub struct Windows<'a, T: 'a> {
 
 impl<'a, T: 'a> Windows<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a [T], size: NonZero<usize>) -> Self {
+    pub(super) const fn new(slice: &'a [T], size: NonZero<usize>) -> Self {
         Self { v: slice, size }
     }
 }
@@ -1380,14 +1380,16 @@ impl<'a, T> Iterator for Windows<'a, T> {
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
-        let (end, overflow) = self.size.get().overflowing_add(n);
-        if end > self.v.len() || overflow {
-            self.v = &[];
-            None
-        } else {
-            let nth = &self.v[n..end];
-            self.v = &self.v[n + 1..];
+        let size = self.size.get();
+        if let Some(rest) = self.v.get(n..)
+            && let Some(nth) = rest.get(..size)
+        {
+            self.v = &rest[1..];
             Some(nth)
+        } else {
+            // setting length to 0 is cheaper than overwriting the pointer when assigning &[]
+            self.v = &self.v[..0]; // cheaper than &[]
+            None
         }
     }
 
@@ -1427,7 +1429,7 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
         let (end, overflow) = self.v.len().overflowing_sub(n);
         if end < self.size.get() || overflow {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             let ret = &self.v[end - self.size.get()..end];
@@ -1487,7 +1489,7 @@ pub struct Chunks<'a, T: 'a> {
 
 impl<'a, T: 'a> Chunks<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+    pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
         Self { v: slice, chunk_size: size }
     }
 }
@@ -1536,17 +1538,15 @@ impl<'a, T> Iterator for Chunks<'a, T> {
     #[inline]
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
         let (start, overflow) = n.overflowing_mul(self.chunk_size);
-        if start >= self.v.len() || overflow {
-            self.v = &[];
-            None
-        } else {
-            let end = match start.checked_add(self.chunk_size) {
-                Some(sum) => cmp::min(self.v.len(), sum),
-                None => self.v.len(),
-            };
-            let nth = &self.v[start..end];
-            self.v = &self.v[end..];
+        // min(len) makes a wrong start harmless, but enables optimizing this to brachless code
+        let chunk_start = &self.v[start.min(self.v.len())..];
+        let (nth, remainder) = chunk_start.split_at(self.chunk_size.min(chunk_start.len()));
+        if !overflow && start < self.v.len() {
+            self.v = remainder;
             Some(nth)
+        } else {
+            self.v = &self.v[..0]; // cheaper than &[]
+            None
         }
     }
 
@@ -1609,7 +1609,7 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
         let len = self.len();
         if n >= len {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             let start = (len - 1 - n) * self.chunk_size;
@@ -1677,7 +1677,7 @@ pub struct ChunksMut<'a, T: 'a> {
 
 impl<'a, T: 'a> ChunksMut<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
+    pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
         Self { v: slice, chunk_size: size, _marker: PhantomData }
     }
 }
@@ -1863,7 +1863,7 @@ pub struct ChunksExact<'a, T: 'a> {
 
 impl<'a, T> ChunksExact<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
+    pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
         let rem = slice.len() % chunk_size;
         let fst_len = slice.len() - rem;
         // SAFETY: 0 <= fst_len <= slice.len() by construction above
@@ -1933,7 +1933,7 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
         let (start, overflow) = n.overflowing_mul(self.chunk_size);
         if start >= self.v.len() || overflow {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             let (_, snd) = self.v.split_at(start);
@@ -1971,7 +1971,7 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
         let len = self.len();
         if n >= len {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             let start = (len - 1 - n) * self.chunk_size;
@@ -2043,7 +2043,7 @@ pub struct ChunksExactMut<'a, T: 'a> {
 
 impl<'a, T> ChunksExactMut<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
+    pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
         let rem = slice.len() % chunk_size;
         let fst_len = slice.len() - rem;
         // SAFETY: 0 <= fst_len <= slice.len() by construction above
@@ -2210,7 +2210,7 @@ pub struct ArrayWindows<'a, T: 'a, const N: usize> {
 
 impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
     #[inline]
-    pub(super) fn new(slice: &'a [T]) -> Self {
+    pub(super) const fn new(slice: &'a [T]) -> Self {
         let num_windows = slice.len().saturating_sub(N - 1);
         Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData }
     }
@@ -2334,8 +2334,10 @@ pub struct ArrayChunks<'a, T: 'a, const N: usize> {
 }
 
 impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
+    // #[rustc_const_unstable(feature = "slice_as_chunks", issue = "74985")]
     #[inline]
-    pub(super) fn new(slice: &'a [T]) -> Self {
+    pub(super) const fn new(slice: &'a [T]) -> Self {
         let (array_slice, rem) = slice.as_chunks();
         Self { iter: array_slice.iter(), rem }
     }
@@ -2460,8 +2462,9 @@ pub struct ArrayChunksMut<'a, T: 'a, const N: usize> {
 }
 
 impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> {
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
-    pub(super) fn new(slice: &'a mut [T]) -> Self {
+    pub(super) const fn new(slice: &'a mut [T]) -> Self {
         let (array_slice, rem) = slice.as_chunks_mut();
         Self { iter: array_slice.iter_mut(), rem }
     }
@@ -2579,7 +2582,7 @@ pub struct RChunks<'a, T: 'a> {
 
 impl<'a, T: 'a> RChunks<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+    pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
         Self { v: slice, chunk_size: size }
     }
 }
@@ -2635,7 +2638,7 @@ impl<'a, T> Iterator for RChunks<'a, T> {
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
         let (end, overflow) = n.overflowing_mul(self.chunk_size);
         if end >= self.v.len() || overflow {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             // Can't underflow because of the check above
@@ -2692,7 +2695,7 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
         let len = self.len();
         if n >= len {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             // can't underflow because `n < len`
@@ -2759,7 +2762,7 @@ pub struct RChunksMut<'a, T: 'a> {
 
 impl<'a, T: 'a> RChunksMut<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
+    pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
         Self { v: slice, chunk_size: size, _marker: PhantomData }
     }
 }
@@ -2950,7 +2953,7 @@ pub struct RChunksExact<'a, T: 'a> {
 
 impl<'a, T> RChunksExact<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
+    pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
         let rem = slice.len() % chunk_size;
         // SAFETY: 0 <= rem <= slice.len() by construction above
         let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
@@ -2976,7 +2979,8 @@ impl<'a, T> RChunksExact<'a, T> {
     /// ```
     #[must_use]
     #[stable(feature = "rchunks", since = "1.31.0")]
-    pub fn remainder(&self) -> &'a [T] {
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
+    pub const fn remainder(&self) -> &'a [T] {
         self.rem
     }
 }
@@ -3019,7 +3023,7 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
         let (end, overflow) = n.overflowing_mul(self.chunk_size);
         if end >= self.v.len() || overflow {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             let (fst, _) = self.v.split_at(self.v.len() - end);
@@ -3058,7 +3062,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
         let len = self.len();
         if n >= len {
-            self.v = &[];
+            self.v = &self.v[..0]; // cheaper than &[]
             None
         } else {
             // now that we know that `n` corresponds to a chunk,
@@ -3132,7 +3136,7 @@ pub struct RChunksExactMut<'a, T: 'a> {
 
 impl<'a, T> RChunksExactMut<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
+    pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
         let rem = slice.len() % chunk_size;
         // SAFETY: 0 <= rem <= slice.len() by construction above
         let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
@@ -3144,7 +3148,8 @@ impl<'a, T> RChunksExactMut<'a, T> {
     /// elements.
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rchunks", since = "1.31.0")]
-    pub fn into_remainder(self) -> &'a mut [T] {
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
+    pub const fn into_remainder(self) -> &'a mut [T] {
         self.rem
     }
 }
@@ -3308,7 +3313,7 @@ pub struct ChunkBy<'a, T: 'a, P> {
 
 #[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
-    pub(super) fn new(slice: &'a [T], predicate: P) -> Self {
+    pub(super) const fn new(slice: &'a [T], predicate: P) -> Self {
         ChunkBy { slice, predicate }
     }
 }
@@ -3395,7 +3400,7 @@ pub struct ChunkByMut<'a, T: 'a, P> {
 
 #[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
-    pub(super) fn new(slice: &'a mut [T], predicate: P) -> Self {
+    pub(super) const fn new(slice: &'a mut [T], predicate: P) -> Self {
         ChunkByMut { slice, predicate }
     }
 }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 058515efdfd..c7e8d5f989d 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -382,16 +382,11 @@ impl<T> [T] {
     #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {
-        if self.len() < N {
-            None
-        } else {
-            // SAFETY: We manually verified the bounds of the split.
-            let (first, tail) = unsafe { self.split_at_unchecked(N) };
+        let Some((first, tail)) = self.split_at_checked(N) else { return None };
 
-            // SAFETY: We explicitly check for the correct number of elements,
-            //   and do not let the references outlive the slice.
-            Some((unsafe { &*(first.as_ptr().cast::<[T; N]>()) }, tail))
-        }
+        // SAFETY: We explicitly check for the correct number of elements,
+        //   and do not let the references outlive the slice.
+        Some((unsafe { &*(first.as_ptr().cast::<[T; N]>()) }, tail))
     }
 
     /// Returns a mutable array reference to the first `N` items in the slice and the remaining
@@ -419,17 +414,12 @@ impl<T> [T] {
     pub const fn split_first_chunk_mut<const N: usize>(
         &mut self,
     ) -> Option<(&mut [T; N], &mut [T])> {
-        if self.len() < N {
-            None
-        } else {
-            // SAFETY: We manually verified the bounds of the split.
-            let (first, tail) = unsafe { self.split_at_mut_unchecked(N) };
+        let Some((first, tail)) = self.split_at_mut_checked(N) else { return None };
 
-            // SAFETY: We explicitly check for the correct number of elements,
-            //   do not let the reference outlive the slice,
-            //   and enforce exclusive mutability of the chunk by the split.
-            Some((unsafe { &mut *(first.as_mut_ptr().cast::<[T; N]>()) }, tail))
-        }
+        // SAFETY: We explicitly check for the correct number of elements,
+        //   do not let the reference outlive the slice,
+        //   and enforce exclusive mutability of the chunk by the split.
+        Some((unsafe { &mut *(first.as_mut_ptr().cast::<[T; N]>()) }, tail))
     }
 
     /// Returns an array reference to the last `N` items in the slice and the remaining slice.
@@ -452,16 +442,12 @@ impl<T> [T] {
     #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])> {
-        if self.len() < N {
-            None
-        } else {
-            // SAFETY: We manually verified the bounds of the split.
-            let (init, last) = unsafe { self.split_at_unchecked(self.len() - N) };
+        let Some(index) = self.len().checked_sub(N) else { return None };
+        let (init, last) = self.split_at(index);
 
-            // SAFETY: We explicitly check for the correct number of elements,
-            //   and do not let the references outlive the slice.
-            Some((init, unsafe { &*(last.as_ptr().cast::<[T; N]>()) }))
-        }
+        // SAFETY: We explicitly check for the correct number of elements,
+        //   and do not let the references outlive the slice.
+        Some((init, unsafe { &*(last.as_ptr().cast::<[T; N]>()) }))
     }
 
     /// Returns a mutable array reference to the last `N` items in the slice and the remaining
@@ -489,17 +475,13 @@ impl<T> [T] {
     pub const fn split_last_chunk_mut<const N: usize>(
         &mut self,
     ) -> Option<(&mut [T], &mut [T; N])> {
-        if self.len() < N {
-            None
-        } else {
-            // SAFETY: We manually verified the bounds of the split.
-            let (init, last) = unsafe { self.split_at_mut_unchecked(self.len() - N) };
+        let Some(index) = self.len().checked_sub(N) else { return None };
+        let (init, last) = self.split_at_mut(index);
 
-            // SAFETY: We explicitly check for the correct number of elements,
-            //   do not let the reference outlive the slice,
-            //   and enforce exclusive mutability of the chunk by the split.
-            Some((init, unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) }))
-        }
+        // SAFETY: We explicitly check for the correct number of elements,
+        //   do not let the reference outlive the slice,
+        //   and enforce exclusive mutability of the chunk by the split.
+        Some((init, unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) }))
     }
 
     /// Returns an array reference to the last `N` items in the slice.
@@ -522,17 +504,13 @@ impl<T> [T] {
     #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_stable(feature = "const_slice_last_chunk", since = "1.80.0")]
     pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]> {
-        if self.len() < N {
-            None
-        } else {
-            // SAFETY: We manually verified the bounds of the slice.
-            // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
-            let last = unsafe { self.split_at_unchecked(self.len() - N).1 };
+        // FIXME(const-hack): Without const traits, we need this instead of `get`.
+        let Some(index) = self.len().checked_sub(N) else { return None };
+        let (_, last) = self.split_at(index);
 
-            // SAFETY: We explicitly check for the correct number of elements,
-            //   and do not let the references outlive the slice.
-            Some(unsafe { &*(last.as_ptr().cast::<[T; N]>()) })
-        }
+        // SAFETY: We explicitly check for the correct number of elements,
+        //   and do not let the references outlive the slice.
+        Some(unsafe { &*(last.as_ptr().cast::<[T; N]>()) })
     }
 
     /// Returns a mutable array reference to the last `N` items in the slice.
@@ -556,18 +534,14 @@ impl<T> [T] {
     #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]
     pub const fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
-        if self.len() < N {
-            None
-        } else {
-            // SAFETY: We manually verified the bounds of the slice.
-            // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
-            let last = unsafe { self.split_at_mut_unchecked(self.len() - N).1 };
+        // FIXME(const-hack): Without const traits, we need this instead of `get`.
+        let Some(index) = self.len().checked_sub(N) else { return None };
+        let (_, last) = self.split_at_mut(index);
 
-            // SAFETY: We explicitly check for the correct number of elements,
-            //   do not let the reference outlive the slice,
-            //   and require exclusive access to the entire slice to mutate the chunk.
-            Some(unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) })
-        }
+        // SAFETY: We explicitly check for the correct number of elements,
+        //   do not let the reference outlive the slice,
+        //   and require exclusive access to the entire slice to mutate the chunk.
+        Some(unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) })
     }
 
     /// Returns a reference to an element or subslice depending on the type of
@@ -1043,9 +1017,10 @@ impl<T> [T] {
     /// assert_eq!(iterator.next(), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[rustc_diagnostic_item = "slice_iter"]
-    pub fn iter(&self) -> Iter<'_, T> {
+    pub const fn iter(&self) -> Iter<'_, T> {
         Iter::new(self)
     }
 
@@ -1062,9 +1037,10 @@ impl<T> [T] {
     /// }
     /// assert_eq!(x, &[3, 4, 6]);
     /// ```
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
+    pub const fn iter_mut(&mut self) -> IterMut<'_, T> {
         IterMut::new(self)
     }
 
@@ -1116,9 +1092,10 @@ impl<T> [T] {
     /// assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn windows(&self, size: usize) -> Windows<'_, T> {
+    pub const fn windows(&self, size: usize) -> Windows<'_, T> {
         let size = NonZero::new(size).expect("window size must be non-zero");
         Windows::new(self, size)
     }
@@ -1151,9 +1128,10 @@ impl<T> [T] {
     /// [`chunks_exact`]: slice::chunks_exact
     /// [`rchunks`]: slice::rchunks
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
+    pub const fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         Chunks::new(self, chunk_size)
     }
@@ -1190,9 +1168,10 @@ impl<T> [T] {
     /// [`chunks_exact_mut`]: slice::chunks_exact_mut
     /// [`rchunks_mut`]: slice::rchunks_mut
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
+    pub const fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         ChunksMut::new(self, chunk_size)
     }
@@ -1228,9 +1207,10 @@ impl<T> [T] {
     /// [`chunks`]: slice::chunks
     /// [`rchunks_exact`]: slice::rchunks_exact
     #[stable(feature = "chunks_exact", since = "1.31.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
+    pub const fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         ChunksExact::new(self, chunk_size)
     }
@@ -1271,9 +1251,10 @@ impl<T> [T] {
     /// [`chunks_mut`]: slice::chunks_mut
     /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
     #[stable(feature = "chunks_exact", since = "1.31.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
+    pub const fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         ChunksExactMut::new(self, chunk_size)
     }
@@ -1429,9 +1410,10 @@ impl<T> [T] {
     ///
     /// [`chunks_exact`]: slice::chunks_exact
     #[unstable(feature = "array_chunks", issue = "74985")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
+    pub const fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
         assert!(N != 0, "chunk size must be non-zero");
         ArrayChunks::new(self)
     }
@@ -1592,9 +1574,10 @@ impl<T> [T] {
     ///
     /// [`chunks_exact_mut`]: slice::chunks_exact_mut
     #[unstable(feature = "array_chunks", issue = "74985")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
+    pub const fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
         assert!(N != 0, "chunk size must be non-zero");
         ArrayChunksMut::new(self)
     }
@@ -1625,9 +1608,10 @@ impl<T> [T] {
     ///
     /// [`windows`]: slice::windows
     #[unstable(feature = "array_windows", issue = "75027")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
+    pub const fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
         assert!(N != 0, "window size must be non-zero");
         ArrayWindows::new(self)
     }
@@ -1660,9 +1644,10 @@ impl<T> [T] {
     /// [`rchunks_exact`]: slice::rchunks_exact
     /// [`chunks`]: slice::chunks
     #[stable(feature = "rchunks", since = "1.31.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
+    pub const fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         RChunks::new(self, chunk_size)
     }
@@ -1699,9 +1684,10 @@ impl<T> [T] {
     /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
     /// [`chunks_mut`]: slice::chunks_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
+    pub const fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         RChunksMut::new(self, chunk_size)
     }
@@ -1739,9 +1725,10 @@ impl<T> [T] {
     /// [`rchunks`]: slice::rchunks
     /// [`chunks_exact`]: slice::chunks_exact
     #[stable(feature = "rchunks", since = "1.31.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
+    pub const fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         RChunksExact::new(self, chunk_size)
     }
@@ -1783,9 +1770,10 @@ impl<T> [T] {
     /// [`rchunks_mut`]: slice::rchunks_mut
     /// [`chunks_exact_mut`]: slice::chunks_exact_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
     #[track_caller]
-    pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
+    pub const fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
         assert!(chunk_size != 0, "chunk size must be non-zero");
         RChunksExactMut::new(self, chunk_size)
     }
@@ -1823,8 +1811,9 @@ impl<T> [T] {
     /// assert_eq!(iter.next(), None);
     /// ```
     #[stable(feature = "slice_group_by", since = "1.77.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
-    pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
+    pub const fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
     where
         F: FnMut(&T, &T) -> bool,
     {
@@ -1864,8 +1853,9 @@ impl<T> [T] {
     /// assert_eq!(iter.next(), None);
     /// ```
     #[stable(feature = "slice_group_by", since = "1.77.0")]
+    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
-    pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
+    pub const fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
     where
         F: FnMut(&T, &T) -> bool,
     {
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index 4655d35e9c4..25b9c6e0e0e 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -47,45 +47,78 @@ const fn bitset_search<
     (word & (1 << (needle % 64) as u64)) != 0
 }
 
-fn decode_prefix_sum(short_offset_run_header: u32) -> u32 {
-    short_offset_run_header & ((1 << 21) - 1)
-}
+#[repr(transparent)]
+struct ShortOffsetRunHeader(u32);
+
+impl ShortOffsetRunHeader {
+    const fn new(start_index: usize, prefix_sum: u32) -> Self {
+        assert!(start_index < (1 << 11));
+        assert!(prefix_sum < (1 << 21));
+
+        Self((start_index as u32) << 21 | prefix_sum)
+    }
 
-fn decode_length(short_offset_run_header: u32) -> usize {
-    (short_offset_run_header >> 21) as usize
+    #[inline]
+    const fn start_index(&self) -> usize {
+        (self.0 >> 21) as usize
+    }
+
+    #[inline]
+    const fn prefix_sum(&self) -> u32 {
+        self.0 & ((1 << 21) - 1)
+    }
 }
 
+/// # Safety
+///
+/// - The last element of `short_offset_runs` must be greater than `std::char::MAX`.
+/// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`.
 #[inline(always)]
-fn skip_search<const SOR: usize, const OFFSETS: usize>(
-    needle: u32,
-    short_offset_runs: &[u32; SOR],
+unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
+    needle: char,
+    short_offset_runs: &[ShortOffsetRunHeader; SOR],
     offsets: &[u8; OFFSETS],
 ) -> bool {
-    // Note that this *cannot* be past the end of the array, as the last
-    // element is greater than std::char::MAX (the largest possible needle).
-    //
-    // So, we cannot have found it (i.e. Ok(idx) + 1 != length) and the correct
-    // location cannot be past it, so Err(idx) != length either.
-    //
-    // This means that we can avoid bounds checking for the accesses below, too.
+    let needle = needle as u32;
+
     let last_idx =
-        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header << 11) {
+        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) {
             Ok(idx) => idx + 1,
             Err(idx) => idx,
         };
+    // SAFETY: `last_idx` *cannot* be past the end of the array, as the last
+    // element is greater than `std::char::MAX` (the largest possible needle)
+    // as guaranteed by the caller.
+    //
+    // So, we cannot have found it (i.e. `Ok(idx) => idx + 1 != length`) and the
+    // correct location cannot be past it, so `Err(idx) => idx != length` either.
+    //
+    // This means that we can avoid bounds checking for the accesses below, too.
+    //
+    // We need to use `intrinsics::assume` since the `panic_nounwind` contained
+    // in `hint::assert_unchecked` may not be optimized out.
+    unsafe { crate::intrinsics::assume(last_idx < SOR) };
 
-    let mut offset_idx = decode_length(short_offset_runs[last_idx]);
+    let mut offset_idx = short_offset_runs[last_idx].start_index();
     let length = if let Some(next) = short_offset_runs.get(last_idx + 1) {
-        decode_length(*next) - offset_idx
+        (*next).start_index() - offset_idx
     } else {
         offsets.len() - offset_idx
     };
+
     let prev =
-        last_idx.checked_sub(1).map(|prev| decode_prefix_sum(short_offset_runs[prev])).unwrap_or(0);
+        last_idx.checked_sub(1).map(|prev| short_offset_runs[prev].prefix_sum()).unwrap_or(0);
 
     let total = needle - prev;
     let mut prefix_sum = 0;
     for _ in 0..(length - 1) {
+        // SAFETY: It is guaranteed that `length <= OFFSETS - offset_idx`,
+        // so it follows that `length - 1 + offset_idx < OFFSETS`, therefore
+        // `offset_idx < OFFSETS` is always true in this loop.
+        //
+        // We need to use `intrinsics::assume` since the `panic_nounwind` contained
+        // in `hint::assert_unchecked` may not be optimized out.
+        unsafe { crate::intrinsics::assume(offset_idx < OFFSETS) };
         let offset = offsets[offset_idx];
         prefix_sum += offset as u32;
         if prefix_sum > total {
@@ -100,15 +133,36 @@ pub const UNICODE_VERSION: (u8, u8, u8) = (16, 0, 0);
 
 #[rustfmt::skip]
 pub mod alphabetic {
-    static SHORT_OFFSET_RUNS: [u32; 53] = [
-        706, 33559113, 876615277, 956309270, 1166025910, 1314925568, 1319120901, 1398813696,
-        1449151936, 1451271309, 1455465997, 1463867300, 1652619520, 1663105646, 1665203518,
-        1711342208, 1797326647, 1895898848, 2560697242, 2583768976, 2594255920, 2600551419,
-        2608940615, 2613141760, 2615240704, 2619435577, 2621533504, 2652997624, 2688650454,
-        2692853744, 2699145507, 2713826044, 2734799872, 2736903168, 2757875366, 2835472128,
-        2883707536, 2934039760, 2942429152, 2955013632, 2988568880, 3126984704, 3139610336,
-        3141711674, 3145911970, 3154308065, 3158503006, 3162699776, 3164797470, 3166896128,
-        3168998219, 3171099568, 3176407984,
+    use super::ShortOffsetRunHeader;
+
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 53] = [
+        ShortOffsetRunHeader::new(0, 706), ShortOffsetRunHeader::new(16, 4681),
+        ShortOffsetRunHeader::new(418, 5741), ShortOffsetRunHeader::new(456, 7958),
+        ShortOffsetRunHeader::new(556, 9398), ShortOffsetRunHeader::new(627, 11264),
+        ShortOffsetRunHeader::new(629, 12293), ShortOffsetRunHeader::new(667, 13312),
+        ShortOffsetRunHeader::new(691, 19904), ShortOffsetRunHeader::new(692, 42125),
+        ShortOffsetRunHeader::new(694, 42509), ShortOffsetRunHeader::new(698, 55204),
+        ShortOffsetRunHeader::new(788, 63744), ShortOffsetRunHeader::new(793, 64110),
+        ShortOffsetRunHeader::new(794, 64830), ShortOffsetRunHeader::new(816, 66176),
+        ShortOffsetRunHeader::new(857, 67383), ShortOffsetRunHeader::new(904, 73440),
+        ShortOffsetRunHeader::new(1221, 74650), ShortOffsetRunHeader::new(1232, 77712),
+        ShortOffsetRunHeader::new(1237, 78896), ShortOffsetRunHeader::new(1240, 82939),
+        ShortOffsetRunHeader::new(1244, 83527), ShortOffsetRunHeader::new(1246, 90368),
+        ShortOffsetRunHeader::new(1247, 92160), ShortOffsetRunHeader::new(1249, 92729),
+        ShortOffsetRunHeader::new(1250, 93504), ShortOffsetRunHeader::new(1265, 100344),
+        ShortOffsetRunHeader::new(1282, 101590), ShortOffsetRunHeader::new(1284, 110576),
+        ShortOffsetRunHeader::new(1287, 110883), ShortOffsetRunHeader::new(1294, 111356),
+        ShortOffsetRunHeader::new(1304, 113664), ShortOffsetRunHeader::new(1305, 119808),
+        ShortOffsetRunHeader::new(1315, 120486), ShortOffsetRunHeader::new(1352, 122624),
+        ShortOffsetRunHeader::new(1375, 123536), ShortOffsetRunHeader::new(1399, 124112),
+        ShortOffsetRunHeader::new(1403, 124896), ShortOffsetRunHeader::new(1409, 126464),
+        ShortOffsetRunHeader::new(1425, 127280), ShortOffsetRunHeader::new(1491, 131072),
+        ShortOffsetRunHeader::new(1497, 173792), ShortOffsetRunHeader::new(1498, 177978),
+        ShortOffsetRunHeader::new(1500, 183970), ShortOffsetRunHeader::new(1504, 191457),
+        ShortOffsetRunHeader::new(1506, 192094), ShortOffsetRunHeader::new(1508, 194560),
+        ShortOffsetRunHeader::new(1509, 195102), ShortOffsetRunHeader::new(1510, 196608),
+        ShortOffsetRunHeader::new(1511, 201547), ShortOffsetRunHeader::new(1512, 205744),
+        ShortOffsetRunHeader::new(1514, 1319856),
     ];
     static OFFSETS: [u8; 1515] = [
         65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 29,
@@ -169,22 +223,44 @@ pub mod alphabetic {
         0, 0, 0, 0, 5, 0, 0,
     ];
     pub fn lookup(c: char) -> bool {
-        super::skip_search(
-            c as u32,
-            &SHORT_OFFSET_RUNS,
-            &OFFSETS,
-        )
+        const {
+            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
+            let mut i = 0;
+            while i < SHORT_OFFSET_RUNS.len() {
+                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
+                i += 1;
+            }
+        }
+        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
+        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
+        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
     }
 }
 
 #[rustfmt::skip]
 pub mod case_ignorable {
-    static SHORT_OFFSET_RUNS: [u32; 37] = [
-        688, 44045149, 572528402, 576724925, 807414908, 878718981, 903913493, 929080568, 933275148,
-        937491230, 1138818560, 1147208189, 1210124160, 1222707713, 1235291428, 1260457643,
-        1277237295, 1537284411, 1545673776, 1604394739, 1667314736, 1692492062, 1700883184,
-        1709272384, 1721855823, 1730260976, 1747041437, 1759629056, 1768018279, 1776409088,
-        1797382144, 1822548654, 1856103659, 1864493264, 1872884731, 1882062849, 1887371760,
+    use super::ShortOffsetRunHeader;
+
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 37] = [
+        ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(21, 4957),
+        ShortOffsetRunHeader::new(273, 5906), ShortOffsetRunHeader::new(275, 8125),
+        ShortOffsetRunHeader::new(385, 11388), ShortOffsetRunHeader::new(419, 12293),
+        ShortOffsetRunHeader::new(431, 40981), ShortOffsetRunHeader::new(443, 42232),
+        ShortOffsetRunHeader::new(445, 42508), ShortOffsetRunHeader::new(447, 64286),
+        ShortOffsetRunHeader::new(543, 65024), ShortOffsetRunHeader::new(547, 66045),
+        ShortOffsetRunHeader::new(577, 67456), ShortOffsetRunHeader::new(583, 68097),
+        ShortOffsetRunHeader::new(589, 68900), ShortOffsetRunHeader::new(601, 69291),
+        ShortOffsetRunHeader::new(609, 71727), ShortOffsetRunHeader::new(733, 71995),
+        ShortOffsetRunHeader::new(737, 72752), ShortOffsetRunHeader::new(765, 73459),
+        ShortOffsetRunHeader::new(795, 78896), ShortOffsetRunHeader::new(807, 90398),
+        ShortOffsetRunHeader::new(811, 92912), ShortOffsetRunHeader::new(815, 93504),
+        ShortOffsetRunHeader::new(821, 94031), ShortOffsetRunHeader::new(825, 110576),
+        ShortOffsetRunHeader::new(833, 113821), ShortOffsetRunHeader::new(839, 118528),
+        ShortOffsetRunHeader::new(843, 119143), ShortOffsetRunHeader::new(847, 121344),
+        ShortOffsetRunHeader::new(857, 122880), ShortOffsetRunHeader::new(869, 123566),
+        ShortOffsetRunHeader::new(885, 124139), ShortOffsetRunHeader::new(889, 125136),
+        ShortOffsetRunHeader::new(893, 127995), ShortOffsetRunHeader::new(897, 917505),
+        ShortOffsetRunHeader::new(899, 2032112),
     ];
     static OFFSETS: [u8; 905] = [
         39, 1, 6, 1, 11, 1, 35, 1, 1, 1, 71, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2,
@@ -222,20 +298,36 @@ pub mod case_ignorable {
         1, 61, 4, 0, 5, 254, 2, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0,
     ];
     pub fn lookup(c: char) -> bool {
-        super::skip_search(
-            c as u32,
-            &SHORT_OFFSET_RUNS,
-            &OFFSETS,
-        )
+        const {
+            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
+            let mut i = 0;
+            while i < SHORT_OFFSET_RUNS.len() {
+                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
+                i += 1;
+            }
+        }
+        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
+        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
+        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
     }
 }
 
 #[rustfmt::skip]
 pub mod cased {
-    static SHORT_OFFSET_RUNS: [u32; 22] = [
-        4256, 115348384, 136322176, 144711446, 163587254, 320875520, 325101120, 350268208,
-        392231680, 404815649, 413205504, 421595008, 467733632, 484513952, 501313088, 505533440,
-        509728422, 587325184, 635559984, 648145152, 652341552, 657650058,
+    use super::ShortOffsetRunHeader;
+
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 22] = [
+        ShortOffsetRunHeader::new(0, 4256), ShortOffsetRunHeader::new(55, 5024),
+        ShortOffsetRunHeader::new(65, 7296), ShortOffsetRunHeader::new(69, 7958),
+        ShortOffsetRunHeader::new(78, 9398), ShortOffsetRunHeader::new(153, 11264),
+        ShortOffsetRunHeader::new(155, 42560), ShortOffsetRunHeader::new(167, 43824),
+        ShortOffsetRunHeader::new(187, 64256), ShortOffsetRunHeader::new(193, 65313),
+        ShortOffsetRunHeader::new(197, 66560), ShortOffsetRunHeader::new(201, 67456),
+        ShortOffsetRunHeader::new(223, 68736), ShortOffsetRunHeader::new(231, 71840),
+        ShortOffsetRunHeader::new(239, 93760), ShortOffsetRunHeader::new(241, 119808),
+        ShortOffsetRunHeader::new(243, 120486), ShortOffsetRunHeader::new(280, 122624),
+        ShortOffsetRunHeader::new(303, 122928), ShortOffsetRunHeader::new(309, 125184),
+        ShortOffsetRunHeader::new(311, 127280), ShortOffsetRunHeader::new(313, 1241482),
     ];
     static OFFSETS: [u8; 319] = [
         65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 1, 36, 7, 2, 30, 5,
@@ -252,39 +344,67 @@ pub mod cased {
         8, 0, 10, 1, 20, 6, 6, 0, 62, 0, 68, 0, 26, 6, 26, 6, 26, 0,
     ];
     pub fn lookup(c: char) -> bool {
-        super::skip_search(
-            c as u32,
-            &SHORT_OFFSET_RUNS,
-            &OFFSETS,
-        )
+        const {
+            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
+            let mut i = 0;
+            while i < SHORT_OFFSET_RUNS.len() {
+                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
+                i += 1;
+            }
+        }
+        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
+        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
+        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
     }
 }
 
 #[rustfmt::skip]
 pub mod cc {
-    static SHORT_OFFSET_RUNS: [u32; 1] = [
-        1114272,
+    use super::ShortOffsetRunHeader;
+
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 1] = [
+        ShortOffsetRunHeader::new(0, 1114272),
     ];
     static OFFSETS: [u8; 5] = [
         0, 32, 95, 33, 0,
     ];
     pub fn lookup(c: char) -> bool {
-        super::skip_search(
-            c as u32,
-            &SHORT_OFFSET_RUNS,
-            &OFFSETS,
-        )
+        const {
+            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
+            let mut i = 0;
+            while i < SHORT_OFFSET_RUNS.len() {
+                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
+                i += 1;
+            }
+        }
+        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
+        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
+        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
     }
 }
 
 #[rustfmt::skip]
 pub mod grapheme_extend {
-    static SHORT_OFFSET_RUNS: [u32; 34] = [
-        768, 2098307, 6292881, 10490717, 522196754, 526393356, 723528943, 731918378, 744531567,
-        752920578, 769719070, 908131840, 912326558, 920715773, 924912129, 937495844, 962662059,
-        971053103, 1256266800, 1323376371, 1386296384, 1407279390, 1415670512, 1424060239,
-        1432468637, 1449250560, 1453445477, 1461836288, 1487003648, 1512170158, 1541530860,
-        1549920464, 1559101472, 1568604656,
+    use super::ShortOffsetRunHeader;
+
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 34] = [
+        ShortOffsetRunHeader::new(0, 768), ShortOffsetRunHeader::new(1, 1155),
+        ShortOffsetRunHeader::new(3, 1425), ShortOffsetRunHeader::new(5, 4957),
+        ShortOffsetRunHeader::new(249, 5906), ShortOffsetRunHeader::new(251, 8204),
+        ShortOffsetRunHeader::new(345, 11503), ShortOffsetRunHeader::new(349, 12330),
+        ShortOffsetRunHeader::new(355, 42607), ShortOffsetRunHeader::new(359, 43010),
+        ShortOffsetRunHeader::new(367, 64286), ShortOffsetRunHeader::new(433, 65024),
+        ShortOffsetRunHeader::new(435, 65438), ShortOffsetRunHeader::new(439, 66045),
+        ShortOffsetRunHeader::new(441, 68097), ShortOffsetRunHeader::new(447, 68900),
+        ShortOffsetRunHeader::new(459, 69291), ShortOffsetRunHeader::new(463, 71727),
+        ShortOffsetRunHeader::new(599, 72752), ShortOffsetRunHeader::new(631, 73459),
+        ShortOffsetRunHeader::new(661, 78912), ShortOffsetRunHeader::new(671, 90398),
+        ShortOffsetRunHeader::new(675, 92912), ShortOffsetRunHeader::new(679, 94031),
+        ShortOffsetRunHeader::new(683, 113821), ShortOffsetRunHeader::new(691, 118528),
+        ShortOffsetRunHeader::new(693, 119141), ShortOffsetRunHeader::new(697, 121344),
+        ShortOffsetRunHeader::new(709, 122880), ShortOffsetRunHeader::new(721, 123566),
+        ShortOffsetRunHeader::new(735, 124140), ShortOffsetRunHeader::new(739, 125136),
+        ShortOffsetRunHeader::new(743, 917536), ShortOffsetRunHeader::new(747, 2032112),
     ];
     static OFFSETS: [u8; 751] = [
         0, 112, 0, 7, 0, 45, 1, 1, 1, 2, 1, 2, 1, 1, 72, 11, 48, 21, 16, 1, 101, 7, 2, 6, 2, 2, 1,
@@ -319,12 +439,20 @@ pub mod grapheme_extend {
     pub fn lookup(c: char) -> bool {
         (c as u32) >= 0x300 && lookup_slow(c)
     }
+
+    #[inline(never)]
     fn lookup_slow(c: char) -> bool {
-        super::skip_search(
-            c as u32,
-            &SHORT_OFFSET_RUNS,
-            &OFFSETS,
-        )
+        const {
+            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
+            let mut i = 0;
+            while i < SHORT_OFFSET_RUNS.len() {
+                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
+                i += 1;
+            }
+        }
+        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
+        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
+        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
     }
 }
 
@@ -436,13 +564,30 @@ pub mod lowercase {
 
 #[rustfmt::skip]
 pub mod n {
-    static SHORT_OFFSET_RUNS: [u32; 42] = [
-        1632, 18876774, 31461440, 102765417, 111154926, 115349830, 132128880, 165684320, 186656630,
-        195046653, 199241735, 203436434, 216049184, 241215536, 249605104, 274792208, 278987015,
-        283181793, 295766104, 320933114, 383848032, 396432464, 438376016, 446765280, 463543280,
-        471932752, 488711168, 497115440, 501312096, 505507184, 522284672, 526503152, 530698944,
-        534894542, 547479872, 551674608, 555869424, 560064711, 568454257, 576844032, 597818352,
-        603126778,
+    use super::ShortOffsetRunHeader;
+
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 42] = [
+        ShortOffsetRunHeader::new(0, 1632), ShortOffsetRunHeader::new(9, 2406),
+        ShortOffsetRunHeader::new(15, 4160), ShortOffsetRunHeader::new(49, 4969),
+        ShortOffsetRunHeader::new(53, 5870), ShortOffsetRunHeader::new(55, 6470),
+        ShortOffsetRunHeader::new(63, 8304), ShortOffsetRunHeader::new(79, 9312),
+        ShortOffsetRunHeader::new(89, 10102), ShortOffsetRunHeader::new(93, 11517),
+        ShortOffsetRunHeader::new(95, 12295), ShortOffsetRunHeader::new(97, 12690),
+        ShortOffsetRunHeader::new(103, 42528), ShortOffsetRunHeader::new(115, 43056),
+        ShortOffsetRunHeader::new(119, 44016), ShortOffsetRunHeader::new(131, 65296),
+        ShortOffsetRunHeader::new(133, 65799), ShortOffsetRunHeader::new(135, 66273),
+        ShortOffsetRunHeader::new(141, 67672), ShortOffsetRunHeader::new(153, 68858),
+        ShortOffsetRunHeader::new(183, 69216), ShortOffsetRunHeader::new(189, 70736),
+        ShortOffsetRunHeader::new(209, 71248), ShortOffsetRunHeader::new(213, 71904),
+        ShortOffsetRunHeader::new(221, 72688), ShortOffsetRunHeader::new(225, 73552),
+        ShortOffsetRunHeader::new(233, 74752), ShortOffsetRunHeader::new(237, 90416),
+        ShortOffsetRunHeader::new(239, 92768), ShortOffsetRunHeader::new(241, 93552),
+        ShortOffsetRunHeader::new(249, 93824), ShortOffsetRunHeader::new(251, 118000),
+        ShortOffsetRunHeader::new(253, 119488), ShortOffsetRunHeader::new(255, 120782),
+        ShortOffsetRunHeader::new(261, 123200), ShortOffsetRunHeader::new(263, 123632),
+        ShortOffsetRunHeader::new(265, 124144), ShortOffsetRunHeader::new(267, 125127),
+        ShortOffsetRunHeader::new(271, 126065), ShortOffsetRunHeader::new(275, 127232),
+        ShortOffsetRunHeader::new(285, 130032), ShortOffsetRunHeader::new(287, 1244154),
     ];
     static OFFSETS: [u8; 289] = [
         48, 10, 120, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118,
@@ -459,11 +604,17 @@ pub mod n {
         10, 247, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0,
     ];
     pub fn lookup(c: char) -> bool {
-        super::skip_search(
-            c as u32,
-            &SHORT_OFFSET_RUNS,
-            &OFFSETS,
-        )
+        const {
+            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
+            let mut i = 0;
+            while i < SHORT_OFFSET_RUNS.len() {
+                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
+                i += 1;
+            }
+        }
+        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
+        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
+        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
     }
 }
 
diff --git a/library/coretests/Cargo.toml b/library/coretests/Cargo.toml
index e44f01d347b..7656388d24b 100644
--- a/library/coretests/Cargo.toml
+++ b/library/coretests/Cargo.toml
@@ -12,6 +12,7 @@ edition = "2024"
 path = "lib.rs"
 test = false
 bench = false
+doc = false
 
 [[test]]
 name = "coretests"
diff --git a/library/coretests/tests/cell.rs b/library/coretests/tests/cell.rs
index d6a401c2b4d..781a46c3744 100644
--- a/library/coretests/tests/cell.rs
+++ b/library/coretests/tests/cell.rs
@@ -50,10 +50,10 @@ fn smoketest_cell() {
 fn cell_update() {
     let x = Cell::new(10);
 
-    assert_eq!(x.update(|x| x + 5), 15);
+    x.update(|x| x + 5);
     assert_eq!(x.get(), 15);
 
-    assert_eq!(x.update(|x| x / 3), 5);
+    x.update(|x| x / 3);
     assert_eq!(x.get(), 5);
 }
 
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 79022fec8a2..7ad154796f6 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -39,7 +39,6 @@
 #![feature(generic_assert_internals)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
-#![feature(inline_const_pat)]
 #![feature(int_roundings)]
 #![feature(ip)]
 #![feature(ip_from)]
@@ -95,16 +94,17 @@
 
 /// Version of `assert_matches` that ignores fancy runtime printing in const context and uses structural equality.
 macro_rules! assert_eq_const_safe {
-    ($left:expr, $right:expr) => {
-        assert_eq_const_safe!($left, $right, concat!(stringify!($left), " == ", stringify!($right)));
+    ($t:ty: $left:expr, $right:expr) => {
+        assert_eq_const_safe!($t: $left, $right, concat!(stringify!($left), " == ", stringify!($right)));
     };
-    ($left:expr, $right:expr$(, $($arg:tt)+)?) => {
+    ($t:ty: $left:expr, $right:expr$(, $($arg:tt)+)?) => {
         {
             fn runtime() {
                 assert_eq!($left, $right, $($($arg)*),*);
             }
             const fn compiletime() {
-                assert!(matches!($left, const { $right }));
+                const PAT: $t = $right;
+                assert!(matches!($left, PAT), $($($arg)*),*);
             }
             core::intrinsics::const_eval_select((), compiletime, runtime)
         }
diff --git a/library/coretests/tests/num/int_macros.rs b/library/coretests/tests/num/int_macros.rs
index bbf19d2b444..0d9fb9e797e 100644
--- a/library/coretests/tests/num/int_macros.rs
+++ b/library/coretests/tests/num/int_macros.rs
@@ -1,5 +1,6 @@
 macro_rules! int_module {
     ($T:ident, $U:ident) => {
+        use core::num::ParseIntError;
         use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
         use core::$T::*;
 
@@ -32,20 +33,20 @@ macro_rules! int_module {
         test_runtime_and_compiletime! {
 
             fn test_rem_euclid() {
-                assert_eq_const_safe!((-1 as $T).rem_euclid(MIN), MAX);
+                assert_eq_const_safe!($T: (-1 as $T).rem_euclid(MIN), MAX);
             }
 
             fn test_abs() {
-                assert_eq_const_safe!((1 as $T).abs(), 1 as $T);
-                assert_eq_const_safe!((0 as $T).abs(), 0 as $T);
-                assert_eq_const_safe!((-1 as $T).abs(), 1 as $T);
+                assert_eq_const_safe!($T: (1 as $T).abs(), 1 as $T);
+                assert_eq_const_safe!($T: (0 as $T).abs(), 0 as $T);
+                assert_eq_const_safe!($T: (-1 as $T).abs(), 1 as $T);
             }
 
             fn test_signum() {
-                assert_eq_const_safe!((1 as $T).signum(), 1 as $T);
-                assert_eq_const_safe!((0 as $T).signum(), 0 as $T);
-                assert_eq_const_safe!((-0 as $T).signum(), 0 as $T);
-                assert_eq_const_safe!((-1 as $T).signum(), -1 as $T);
+                assert_eq_const_safe!($T: (1 as $T).signum(), 1 as $T);
+                assert_eq_const_safe!($T: (0 as $T).signum(), 0 as $T);
+                assert_eq_const_safe!($T: (-0 as $T).signum(), 0 as $T);
+                assert_eq_const_safe!($T: (-1 as $T).signum(), -1 as $T);
             }
 
             fn test_is_positive() {
@@ -72,123 +73,123 @@ macro_rules! int_module {
 
         test_runtime_and_compiletime! {
             fn test_count_ones() {
-                assert_eq_const_safe!(A.count_ones(), 3);
-                assert_eq_const_safe!(B.count_ones(), 2);
-                assert_eq_const_safe!(C.count_ones(), 5);
+                assert_eq_const_safe!(u32: A.count_ones(), 3);
+                assert_eq_const_safe!(u32: B.count_ones(), 2);
+                assert_eq_const_safe!(u32: C.count_ones(), 5);
             }
 
             fn test_count_zeros() {
-                assert_eq_const_safe!(A.count_zeros(), $T::BITS - 3);
-                assert_eq_const_safe!(B.count_zeros(), $T::BITS - 2);
-                assert_eq_const_safe!(C.count_zeros(), $T::BITS - 5);
+                assert_eq_const_safe!(u32: A.count_zeros(), $T::BITS - 3);
+                assert_eq_const_safe!(u32: B.count_zeros(), $T::BITS - 2);
+                assert_eq_const_safe!(u32: C.count_zeros(), $T::BITS - 5);
             }
 
             fn test_leading_trailing_ones() {
                 const A: $T = 0b0101_1111;
-                assert_eq_const_safe!(A.trailing_ones(), 5);
-                assert_eq_const_safe!((!A).leading_ones(), $T::BITS - 7);
+                assert_eq_const_safe!(u32: A.trailing_ones(), 5);
+                assert_eq_const_safe!(u32: (!A).leading_ones(), $T::BITS - 7);
 
-                assert_eq_const_safe!(A.reverse_bits().leading_ones(), 5);
+                assert_eq_const_safe!(u32: A.reverse_bits().leading_ones(), 5);
 
-                assert_eq_const_safe!(_1.leading_ones(), $T::BITS);
-                assert_eq_const_safe!(_1.trailing_ones(), $T::BITS);
+                assert_eq_const_safe!(u32: _1.leading_ones(), $T::BITS);
+                assert_eq_const_safe!(u32: _1.trailing_ones(), $T::BITS);
 
-                assert_eq_const_safe!((_1 << 1).trailing_ones(), 0);
-                assert_eq_const_safe!(MAX.leading_ones(), 0);
+                assert_eq_const_safe!(u32: (_1 << 1).trailing_ones(), 0);
+                assert_eq_const_safe!(u32: MAX.leading_ones(), 0);
 
-                assert_eq_const_safe!((_1 << 1).leading_ones(), $T::BITS - 1);
-                assert_eq_const_safe!(MAX.trailing_ones(), $T::BITS - 1);
+                assert_eq_const_safe!(u32: (_1 << 1).leading_ones(), $T::BITS - 1);
+                assert_eq_const_safe!(u32: MAX.trailing_ones(), $T::BITS - 1);
 
-                assert_eq_const_safe!(_0.leading_ones(), 0);
-                assert_eq_const_safe!(_0.trailing_ones(), 0);
+                assert_eq_const_safe!(u32: _0.leading_ones(), 0);
+                assert_eq_const_safe!(u32: _0.trailing_ones(), 0);
 
                 const X: $T = 0b0010_1100;
-                assert_eq_const_safe!(X.leading_ones(), 0);
-                assert_eq_const_safe!(X.trailing_ones(), 0);
+                assert_eq_const_safe!(u32: X.leading_ones(), 0);
+                assert_eq_const_safe!(u32: X.trailing_ones(), 0);
             }
 
             fn test_rotate() {
-                assert_eq_const_safe!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-                assert_eq_const_safe!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
-                assert_eq_const_safe!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+                assert_eq_const_safe!($T: A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+                assert_eq_const_safe!($T: B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+                assert_eq_const_safe!($T: C.rotate_left(6).rotate_right(2).rotate_right(4), C);
 
                 // Rotating these should make no difference
                 //
                 // We test using 124 bits because to ensure that overlong bit shifts do
                 // not cause undefined behavior. See #10183.
-                assert_eq_const_safe!(_0.rotate_left(124), _0);
-                assert_eq_const_safe!(_1.rotate_left(124), _1);
-                assert_eq_const_safe!(_0.rotate_right(124), _0);
-                assert_eq_const_safe!(_1.rotate_right(124), _1);
+                assert_eq_const_safe!($T: _0.rotate_left(124), _0);
+                assert_eq_const_safe!($T: _1.rotate_left(124), _1);
+                assert_eq_const_safe!($T: _0.rotate_right(124), _0);
+                assert_eq_const_safe!($T: _1.rotate_right(124), _1);
 
                 // Rotating by 0 should have no effect
-                assert_eq_const_safe!(A.rotate_left(0), A);
-                assert_eq_const_safe!(B.rotate_left(0), B);
-                assert_eq_const_safe!(C.rotate_left(0), C);
+                assert_eq_const_safe!($T: A.rotate_left(0), A);
+                assert_eq_const_safe!($T: B.rotate_left(0), B);
+                assert_eq_const_safe!($T: C.rotate_left(0), C);
                 // Rotating by a multiple of word size should also have no effect
-                assert_eq_const_safe!(A.rotate_left(128), A);
-                assert_eq_const_safe!(B.rotate_left(128), B);
-                assert_eq_const_safe!(C.rotate_left(128), C);
+                assert_eq_const_safe!($T: A.rotate_left(128), A);
+                assert_eq_const_safe!($T: B.rotate_left(128), B);
+                assert_eq_const_safe!($T: C.rotate_left(128), C);
             }
 
             fn test_swap_bytes() {
-                assert_eq_const_safe!(A.swap_bytes().swap_bytes(), A);
-                assert_eq_const_safe!(B.swap_bytes().swap_bytes(), B);
-                assert_eq_const_safe!(C.swap_bytes().swap_bytes(), C);
+                assert_eq_const_safe!($T: A.swap_bytes().swap_bytes(), A);
+                assert_eq_const_safe!($T: B.swap_bytes().swap_bytes(), B);
+                assert_eq_const_safe!($T: C.swap_bytes().swap_bytes(), C);
 
                 // Swapping these should make no difference
-                assert_eq_const_safe!(_0.swap_bytes(), _0);
-                assert_eq_const_safe!(_1.swap_bytes(), _1);
+                assert_eq_const_safe!($T: _0.swap_bytes(), _0);
+                assert_eq_const_safe!($T: _1.swap_bytes(), _1);
             }
 
             fn test_le() {
-                assert_eq_const_safe!($T::from_le(A.to_le()), A);
-                assert_eq_const_safe!($T::from_le(B.to_le()), B);
-                assert_eq_const_safe!($T::from_le(C.to_le()), C);
-                assert_eq_const_safe!($T::from_le(_0), _0);
-                assert_eq_const_safe!($T::from_le(_1), _1);
-                assert_eq_const_safe!(_0.to_le(), _0);
-                assert_eq_const_safe!(_1.to_le(), _1);
+                assert_eq_const_safe!($T: $T::from_le(A.to_le()), A);
+                assert_eq_const_safe!($T: $T::from_le(B.to_le()), B);
+                assert_eq_const_safe!($T: $T::from_le(C.to_le()), C);
+                assert_eq_const_safe!($T: $T::from_le(_0), _0);
+                assert_eq_const_safe!($T: $T::from_le(_1), _1);
+                assert_eq_const_safe!($T: _0.to_le(), _0);
+                assert_eq_const_safe!($T: _1.to_le(), _1);
             }
 
             fn test_be() {
-                assert_eq_const_safe!($T::from_be(A.to_be()), A);
-                assert_eq_const_safe!($T::from_be(B.to_be()), B);
-                assert_eq_const_safe!($T::from_be(C.to_be()), C);
-                assert_eq_const_safe!($T::from_be(_0), _0);
-                assert_eq_const_safe!($T::from_be(_1), _1);
-                assert_eq_const_safe!(_0.to_be(), _0);
-                assert_eq_const_safe!(_1.to_be(), _1);
+                assert_eq_const_safe!($T: $T::from_be(A.to_be()), A);
+                assert_eq_const_safe!($T: $T::from_be(B.to_be()), B);
+                assert_eq_const_safe!($T: $T::from_be(C.to_be()), C);
+                assert_eq_const_safe!($T: $T::from_be(_0), _0);
+                assert_eq_const_safe!($T: $T::from_be(_1), _1);
+                assert_eq_const_safe!($T: _0.to_be(), _0);
+                assert_eq_const_safe!($T: _1.to_be(), _1);
             }
 
             fn test_signed_checked_div() {
-                assert_eq_const_safe!((10 as $T).checked_div(2), Some(5));
-                assert_eq_const_safe!((5 as $T).checked_div(0), None);
-                assert_eq_const_safe!(isize::MIN.checked_div(-1), None);
+                assert_eq_const_safe!(Option<$T>: (10 as $T).checked_div(2), Some(5));
+                assert_eq_const_safe!(Option<$T>: (5 as $T).checked_div(0), None);
+                assert_eq_const_safe!(Option<$T>: $T::MIN.checked_div(-1), None);
             }
 
             fn test_saturating_abs() {
-                assert_eq_const_safe!((0 as $T).saturating_abs(), 0);
-                assert_eq_const_safe!((123 as $T).saturating_abs(), 123);
-                assert_eq_const_safe!((-123 as $T).saturating_abs(), 123);
-                assert_eq_const_safe!((MAX - 2).saturating_abs(), MAX - 2);
-                assert_eq_const_safe!((MAX - 1).saturating_abs(), MAX - 1);
-                assert_eq_const_safe!(MAX.saturating_abs(), MAX);
-                assert_eq_const_safe!((MIN + 2).saturating_abs(), MAX - 1);
-                assert_eq_const_safe!((MIN + 1).saturating_abs(), MAX);
-                assert_eq_const_safe!(MIN.saturating_abs(), MAX);
+                assert_eq_const_safe!($T: (0 as $T).saturating_abs(), 0);
+                assert_eq_const_safe!($T: (123 as $T).saturating_abs(), 123);
+                assert_eq_const_safe!($T: (-123 as $T).saturating_abs(), 123);
+                assert_eq_const_safe!($T: (MAX - 2).saturating_abs(), MAX - 2);
+                assert_eq_const_safe!($T: (MAX - 1).saturating_abs(), MAX - 1);
+                assert_eq_const_safe!($T: MAX.saturating_abs(), MAX);
+                assert_eq_const_safe!($T: (MIN + 2).saturating_abs(), MAX - 1);
+                assert_eq_const_safe!($T: (MIN + 1).saturating_abs(), MAX);
+                assert_eq_const_safe!($T: MIN.saturating_abs(), MAX);
             }
 
             fn test_saturating_neg() {
-                assert_eq_const_safe!((0 as $T).saturating_neg(), 0);
-                assert_eq_const_safe!((123 as $T).saturating_neg(), -123);
-                assert_eq_const_safe!((-123 as $T).saturating_neg(), 123);
-                assert_eq_const_safe!((MAX - 2).saturating_neg(), MIN + 3);
-                assert_eq_const_safe!((MAX - 1).saturating_neg(), MIN + 2);
-                assert_eq_const_safe!(MAX.saturating_neg(), MIN + 1);
-                assert_eq_const_safe!((MIN + 2).saturating_neg(), MAX - 1);
-                assert_eq_const_safe!((MIN + 1).saturating_neg(), MAX);
-                assert_eq_const_safe!(MIN.saturating_neg(), MAX);
+                assert_eq_const_safe!($T: (0 as $T).saturating_neg(), 0);
+                assert_eq_const_safe!($T: (123 as $T).saturating_neg(), -123);
+                assert_eq_const_safe!($T: (-123 as $T).saturating_neg(), 123);
+                assert_eq_const_safe!($T: (MAX - 2).saturating_neg(), MIN + 3);
+                assert_eq_const_safe!($T: (MAX - 1).saturating_neg(), MIN + 2);
+                assert_eq_const_safe!($T: MAX.saturating_neg(), MIN + 1);
+                assert_eq_const_safe!($T: (MIN + 2).saturating_neg(), MAX - 1);
+                assert_eq_const_safe!($T: (MIN + 1).saturating_neg(), MAX);
+                assert_eq_const_safe!($T: MIN.saturating_neg(), MAX);
             }
         }
 
@@ -250,23 +251,23 @@ macro_rules! int_module {
 
         test_runtime_and_compiletime! {
             fn test_from_str_radix() {
-                assert_eq_const_safe!($T::from_str_radix("123", 10), Ok(123 as $T));
-                assert_eq_const_safe!($T::from_str_radix("1001", 2), Ok(9 as $T));
-                assert_eq_const_safe!($T::from_str_radix("123", 8), Ok(83 as $T));
-                assert_eq_const_safe!(i32::from_str_radix("123", 16), Ok(291 as i32));
-                assert_eq_const_safe!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
-                assert_eq_const_safe!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
-                assert_eq_const_safe!($T::from_str_radix("z", 36), Ok(35 as $T));
-                assert_eq_const_safe!($T::from_str_radix("Z", 36), Ok(35 as $T));
-
-                assert_eq_const_safe!($T::from_str_radix("-123", 10), Ok(-123 as $T));
-                assert_eq_const_safe!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
-                assert_eq_const_safe!($T::from_str_radix("-123", 8), Ok(-83 as $T));
-                assert_eq_const_safe!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
-                assert_eq_const_safe!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
-                assert_eq_const_safe!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
-                assert_eq_const_safe!($T::from_str_radix("-z", 36), Ok(-35 as $T));
-                assert_eq_const_safe!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 10), Ok(123 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("1001", 2), Ok(9 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 8), Ok(83 as $T));
+                assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("123", 16), Ok(291 as i32));
+                assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("ffff", 16), Ok(65535 as i32));
+                assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("z", 36), Ok(35 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("Z", 36), Ok(35 as $T));
+
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-123", 10), Ok(-123 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-1001", 2), Ok(-9 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-123", 8), Ok(-83 as $T));
+                assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("-123", 16), Ok(-291 as i32));
+                assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
+                assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-z", 36), Ok(-35 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-Z", 36), Ok(-35 as $T));
 
                 assert!($T::from_str_radix("Z", 35).is_err());
                 assert!($T::from_str_radix("-9", 2).is_err());
@@ -277,16 +278,16 @@ macro_rules! int_module {
             fn test_pow() {
                 {
                     const R: $T = 2;
-                    assert_eq_const_safe!(R.pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.pow(0), 1 as $T);
-                    assert_eq_const_safe!(R.wrapping_pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.wrapping_pow(0), 1 as $T);
-                    assert_eq_const_safe!(R.checked_pow(2), Some(4 as $T));
-                    assert_eq_const_safe!(R.checked_pow(0), Some(1 as $T));
-                    assert_eq_const_safe!(R.overflowing_pow(2), (4 as $T, false));
-                    assert_eq_const_safe!(R.overflowing_pow(0), (1 as $T, false));
-                    assert_eq_const_safe!(R.saturating_pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.saturating_pow(0), 1 as $T);
+                    assert_eq_const_safe!($T: R.pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.pow(0), 1 as $T);
+                    assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
+                    assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
                 }
 
                 {
@@ -295,221 +296,227 @@ macro_rules! int_module {
                     // if itest::MAX == 2^j-1, then itest is a `j` bit int,
                     // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
                     // thussaturating_pow the overflowing result is exactly 1.
-                    assert_eq_const_safe!(R.wrapping_pow(2), 1 as $T);
-                    assert_eq_const_safe!(R.checked_pow(2), None);
-                    assert_eq_const_safe!(R.overflowing_pow(2), (1 as $T, true));
-                    assert_eq_const_safe!(R.saturating_pow(2), MAX);
+                    assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T);
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None);
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, true));
+                    assert_eq_const_safe!($T: R.saturating_pow(2), MAX);
                 }
 
                 {
                     // test for negative exponent.
                     const R: $T = -2;
-                    assert_eq_const_safe!(R.pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.pow(3), -8 as $T);
-                    assert_eq_const_safe!(R.pow(0), 1 as $T);
-                    assert_eq_const_safe!(R.wrapping_pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.wrapping_pow(3), -8 as $T);
-                    assert_eq_const_safe!(R.wrapping_pow(0), 1 as $T);
-                    assert_eq_const_safe!(R.checked_pow(2), Some(4 as $T));
-                    assert_eq_const_safe!(R.checked_pow(3), Some(-8 as $T));
-                    assert_eq_const_safe!(R.checked_pow(0), Some(1 as $T));
-                    assert_eq_const_safe!(R.overflowing_pow(2), (4 as $T, false));
-                    assert_eq_const_safe!(R.overflowing_pow(3), (-8 as $T, false));
-                    assert_eq_const_safe!(R.overflowing_pow(0), (1 as $T, false));
-                    assert_eq_const_safe!(R.saturating_pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.saturating_pow(3), -8 as $T);
-                    assert_eq_const_safe!(R.saturating_pow(0), 1 as $T);
+                    assert_eq_const_safe!($T: R.pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.pow(3), -8 as $T);
+                    assert_eq_const_safe!($T: R.pow(0), 1 as $T);
+                    assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.wrapping_pow(3), -8 as $T);
+                    assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(3), Some(-8 as $T));
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(3), (-8 as $T, false));
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
+                    assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.saturating_pow(3), -8 as $T);
+                    assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
                 }
             }
 
             fn test_div_floor() {
                 const A: $T = 8;
                 const B: $T = 3;
-                assert_eq_const_safe!(A.div_floor(B), 2);
-                assert_eq_const_safe!(A.div_floor(-B), -3);
-                assert_eq_const_safe!((-A).div_floor(B), -3);
-                assert_eq_const_safe!((-A).div_floor(-B), 2);
+                assert_eq_const_safe!($T: A.div_floor(B), 2);
+                assert_eq_const_safe!($T: A.div_floor(-B), -3);
+                assert_eq_const_safe!($T: (-A).div_floor(B), -3);
+                assert_eq_const_safe!($T: (-A).div_floor(-B), 2);
             }
 
             fn test_div_ceil() {
                 const A: $T = 8;
                 const B: $T = 3;
-                assert_eq_const_safe!(A.div_ceil(B), 3);
-                assert_eq_const_safe!(A.div_ceil(-B), -2);
-                assert_eq_const_safe!((-A).div_ceil(B), -2);
-                assert_eq_const_safe!((-A).div_ceil(-B), 3);
+                assert_eq_const_safe!($T: A.div_ceil(B), 3);
+                assert_eq_const_safe!($T: A.div_ceil(-B), -2);
+                assert_eq_const_safe!($T: (-A).div_ceil(B), -2);
+                assert_eq_const_safe!($T: (-A).div_ceil(-B), 3);
             }
 
             fn test_next_multiple_of() {
-                assert_eq_const_safe!((16 as $T).next_multiple_of(8), 16);
-                assert_eq_const_safe!((23 as $T).next_multiple_of(8), 24);
-                assert_eq_const_safe!((16 as $T).next_multiple_of(-8), 16);
-                assert_eq_const_safe!((23 as $T).next_multiple_of(-8), 16);
-                assert_eq_const_safe!((-16 as $T).next_multiple_of(8), -16);
-                assert_eq_const_safe!((-23 as $T).next_multiple_of(8), -16);
-                assert_eq_const_safe!((-16 as $T).next_multiple_of(-8), -16);
-                assert_eq_const_safe!((-23 as $T).next_multiple_of(-8), -24);
-                assert_eq_const_safe!(MIN.next_multiple_of(-1), MIN);
+                assert_eq_const_safe!($T: (16 as $T).next_multiple_of(8), 16);
+                assert_eq_const_safe!($T: (23 as $T).next_multiple_of(8), 24);
+                assert_eq_const_safe!($T: (16 as $T).next_multiple_of(-8), 16);
+                assert_eq_const_safe!($T: (23 as $T).next_multiple_of(-8), 16);
+                assert_eq_const_safe!($T: (-16 as $T).next_multiple_of(8), -16);
+                assert_eq_const_safe!($T: (-23 as $T).next_multiple_of(8), -16);
+                assert_eq_const_safe!($T: (-16 as $T).next_multiple_of(-8), -16);
+                assert_eq_const_safe!($T: (-23 as $T).next_multiple_of(-8), -24);
+                assert_eq_const_safe!($T: MIN.next_multiple_of(-1), MIN);
             }
 
             fn test_checked_next_multiple_of() {
-                assert_eq_const_safe!((16 as $T).checked_next_multiple_of(8), Some(16));
-                assert_eq_const_safe!((23 as $T).checked_next_multiple_of(8), Some(24));
-                assert_eq_const_safe!((16 as $T).checked_next_multiple_of(-8), Some(16));
-                assert_eq_const_safe!((23 as $T).checked_next_multiple_of(-8), Some(16));
-                assert_eq_const_safe!((-16 as $T).checked_next_multiple_of(8), Some(-16));
-                assert_eq_const_safe!((-23 as $T).checked_next_multiple_of(8), Some(-16));
-                assert_eq_const_safe!((-16 as $T).checked_next_multiple_of(-8), Some(-16));
-                assert_eq_const_safe!((-23 as $T).checked_next_multiple_of(-8), Some(-24));
-                assert_eq_const_safe!((1 as $T).checked_next_multiple_of(0), None);
-                assert_eq_const_safe!(MAX.checked_next_multiple_of(2), None);
-                assert_eq_const_safe!(MIN.checked_next_multiple_of(-3), None);
-                assert_eq_const_safe!(MIN.checked_next_multiple_of(-1), Some(MIN));
+                assert_eq_const_safe!(Option<$T>: (16 as $T).checked_next_multiple_of(8), Some(16));
+                assert_eq_const_safe!(Option<$T>: (23 as $T).checked_next_multiple_of(8), Some(24));
+                assert_eq_const_safe!(Option<$T>: (16 as $T).checked_next_multiple_of(-8), Some(16));
+                assert_eq_const_safe!(Option<$T>: (23 as $T).checked_next_multiple_of(-8), Some(16));
+                assert_eq_const_safe!(Option<$T>: (-16 as $T).checked_next_multiple_of(8), Some(-16));
+                assert_eq_const_safe!(Option<$T>: (-23 as $T).checked_next_multiple_of(8), Some(-16));
+                assert_eq_const_safe!(Option<$T>: (-16 as $T).checked_next_multiple_of(-8), Some(-16));
+                assert_eq_const_safe!(Option<$T>: (-23 as $T).checked_next_multiple_of(-8), Some(-24));
+                assert_eq_const_safe!(Option<$T>: (1 as $T).checked_next_multiple_of(0), None);
+                assert_eq_const_safe!(Option<$T>: MAX.checked_next_multiple_of(2), None);
+                assert_eq_const_safe!(Option<$T>: MIN.checked_next_multiple_of(-3), None);
+                assert_eq_const_safe!(Option<$T>: MIN.checked_next_multiple_of(-1), Some(MIN));
             }
 
             fn test_carrying_add() {
-                assert_eq_const_safe!(MAX.carrying_add(1, false), (MIN, true));
-                assert_eq_const_safe!(MAX.carrying_add(0, true), (MIN, true));
-                assert_eq_const_safe!(MAX.carrying_add(1, true), (MIN + 1, true));
-                assert_eq_const_safe!(MAX.carrying_add(-1, false), (MAX - 1, false));
-                assert_eq_const_safe!(MAX.carrying_add(-1, true), (MAX, false)); // no intermediate overflow
-                assert_eq_const_safe!(MIN.carrying_add(-1, false), (MAX, true));
-                assert_eq_const_safe!(MIN.carrying_add(-1, true), (MIN, false)); // no intermediate overflow
-                assert_eq_const_safe!((0 as $T).carrying_add(MAX, true), (MIN, true));
-                assert_eq_const_safe!((0 as $T).carrying_add(MIN, true), (MIN + 1, false));
+                assert_eq_const_safe!(($T, bool): MAX.carrying_add(1, false), (MIN, true));
+                assert_eq_const_safe!(($T, bool): MAX.carrying_add(0, true), (MIN, true));
+                assert_eq_const_safe!(($T, bool): MAX.carrying_add(1, true), (MIN + 1, true));
+                assert_eq_const_safe!(($T, bool): MAX.carrying_add(-1, false), (MAX - 1, false));
+                assert_eq_const_safe!(($T, bool): MAX.carrying_add(-1, true), (MAX, false)); // no intermediate overflow
+                assert_eq_const_safe!(($T, bool): MIN.carrying_add(-1, false), (MAX, true));
+                assert_eq_const_safe!(($T, bool): MIN.carrying_add(-1, true), (MIN, false)); // no intermediate overflow
+                assert_eq_const_safe!(($T, bool): (0 as $T).carrying_add(MAX, true), (MIN, true));
+                assert_eq_const_safe!(($T, bool): (0 as $T).carrying_add(MIN, true), (MIN + 1, false));
             }
 
             fn test_borrowing_sub() {
-                assert_eq_const_safe!(MIN.borrowing_sub(1, false), (MAX, true));
-                assert_eq_const_safe!(MIN.borrowing_sub(0, true), (MAX, true));
-                assert_eq_const_safe!(MIN.borrowing_sub(1, true), (MAX - 1, true));
-                assert_eq_const_safe!(MIN.borrowing_sub(-1, false), (MIN + 1, false));
-                assert_eq_const_safe!(MIN.borrowing_sub(-1, true), (MIN, false)); // no intermediate overflow
-                assert_eq_const_safe!(MAX.borrowing_sub(-1, false), (MIN, true));
-                assert_eq_const_safe!(MAX.borrowing_sub(-1, true), (MAX, false)); // no intermediate overflow
-                assert_eq_const_safe!((0 as $T).borrowing_sub(MIN, false), (MIN, true));
-                assert_eq_const_safe!((0 as $T).borrowing_sub(MIN, true), (MAX, false));
+                assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(1, false), (MAX, true));
+                assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(0, true), (MAX, true));
+                assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(1, true), (MAX - 1, true));
+                assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(-1, false), (MIN + 1, false));
+                assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(-1, true), (MIN, false)); // no intermediate overflow
+                assert_eq_const_safe!(($T, bool): MAX.borrowing_sub(-1, false), (MIN, true));
+                assert_eq_const_safe!(($T, bool): MAX.borrowing_sub(-1, true), (MAX, false)); // no intermediate overflow
+                assert_eq_const_safe!(($T, bool): (0 as $T).borrowing_sub(MIN, false), (MIN, true));
+                assert_eq_const_safe!(($T, bool): (0 as $T).borrowing_sub(MIN, true), (MAX, false));
             }
 
             fn test_widening_mul() {
-                assert_eq_const_safe!(MAX.widening_mul(MAX), (1, MAX / 2));
-                assert_eq_const_safe!(MIN.widening_mul(MAX), (MIN as $U, MIN / 2));
-                assert_eq_const_safe!(MIN.widening_mul(MIN), (0, MAX / 2 + 1));
+                assert_eq_const_safe!(($U, $T): MAX.widening_mul(MAX), (1, MAX / 2));
+                assert_eq_const_safe!(($U, $T): MIN.widening_mul(MAX), (MIN as $U, MIN / 2));
+                assert_eq_const_safe!(($U, $T): MIN.widening_mul(MIN), (0, MAX / 2 + 1));
             }
 
             fn test_carrying_mul() {
-                assert_eq_const_safe!(MAX.carrying_mul(MAX, 0), (1, MAX / 2));
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T): MAX.carrying_mul(MAX, 0), (1, MAX / 2));
+                assert_eq_const_safe!(($U, $T):
                     MAX.carrying_mul(MAX, MAX),
                     (UMAX / 2 + 1, MAX / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MAX.carrying_mul(MAX, MIN),
                     (UMAX / 2 + 2, MAX / 2 - 1)
                 );
-                assert_eq_const_safe!(MIN.carrying_mul(MAX, 0), (MIN as $U, MIN / 2));
-                assert_eq_const_safe!(MIN.carrying_mul(MAX, MAX), (UMAX, MIN / 2));
-                assert_eq_const_safe!(MIN.carrying_mul(MAX, MIN), (0, MIN / 2));
-                assert_eq_const_safe!(MIN.carrying_mul(MIN, 0), (0, MAX / 2 + 1));
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MAX, 0), (MIN as $U, MIN / 2));
+                assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MAX, MAX), (UMAX, MIN / 2));
+                assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MAX, MIN), (0, MIN / 2));
+                assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MIN, 0), (0, MAX / 2 + 1));
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul(MIN, MAX),
                     (UMAX / 2, MAX / 2 + 1)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul(MIN, MIN),
                     (UMAX / 2 + 1, MAX / 2)
                 );
             }
 
             fn test_carrying_mul_add() {
-                assert_eq_const_safe!(MAX.carrying_mul_add(MAX, 0, 0), (1, MAX / 2));
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T): MAX.carrying_mul_add(MAX, 0, 0), (1, MAX / 2));
+                assert_eq_const_safe!(($U, $T):
                     MAX.carrying_mul_add(MAX, MAX, 0),
                     (UMAX / 2 + 1, MAX / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MAX.carrying_mul_add(MAX, MIN, 0),
                     (UMAX / 2 + 2, MAX / 2 - 1)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MAX.carrying_mul_add(MAX, MAX, MAX),
                     (UMAX, MAX / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MAX.carrying_mul_add(MAX, MAX, MIN),
                     (0, MAX / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MAX.carrying_mul_add(MAX, MIN, MIN),
                     (1, MAX / 2 - 1)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MAX, 0, 0),
                     (MIN as $U, MIN / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MAX, MAX, 0),
                     (UMAX, MIN / 2)
                 );
-                assert_eq_const_safe!(MIN.carrying_mul_add(MAX, MIN, 0), (0, MIN / 2));
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
+                    MIN.carrying_mul_add(MAX, MIN, 0),
+                    (0, MIN / 2)
+                );
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MAX, MAX, MAX),
                     (UMAX / 2 - 1, MIN / 2 + 1)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MAX, MAX, MIN),
                     (UMAX / 2, MIN / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MAX, MIN, MIN),
                     (UMAX / 2 + 1, MIN / 2 - 1)
                 );
-                assert_eq_const_safe!(MIN.carrying_mul_add(MIN, 0, 0), (0, MAX / 2 + 1));
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
+                    MIN.carrying_mul_add(MIN, 0, 0),
+                    (0, MAX / 2 + 1)
+                );
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MIN, MAX, 0),
                     (UMAX / 2, MAX / 2 + 1)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MIN, MIN, 0),
                     (UMAX / 2 + 1, MAX / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MIN, MAX, MAX),
                     (UMAX - 1, MAX / 2 + 1)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MIN, MAX, MIN),
                     (UMAX, MAX / 2)
                 );
-                assert_eq_const_safe!(
+                assert_eq_const_safe!(($U, $T):
                     MIN.carrying_mul_add(MIN, MIN, MIN),
                     (0, MAX / 2)
                 );
             }
 
             fn test_midpoint() {
-                assert_eq_const_safe!(<$T>::midpoint(1, 3), 2);
-                assert_eq_const_safe!(<$T>::midpoint(3, 1), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(1, 3), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(3, 1), 2);
 
-                assert_eq_const_safe!(<$T>::midpoint(0, 0), 0);
-                assert_eq_const_safe!(<$T>::midpoint(0, 2), 1);
-                assert_eq_const_safe!(<$T>::midpoint(2, 0), 1);
-                assert_eq_const_safe!(<$T>::midpoint(2, 2), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(0, 0), 0);
+                assert_eq_const_safe!($T: <$T>::midpoint(0, 2), 1);
+                assert_eq_const_safe!($T: <$T>::midpoint(2, 0), 1);
+                assert_eq_const_safe!($T: <$T>::midpoint(2, 2), 2);
 
-                assert_eq_const_safe!(<$T>::midpoint(1, 4), 2);
-                assert_eq_const_safe!(<$T>::midpoint(4, 1), 2);
-                assert_eq_const_safe!(<$T>::midpoint(3, 4), 3);
-                assert_eq_const_safe!(<$T>::midpoint(4, 3), 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(1, 4), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(4, 1), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(3, 4), 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(4, 3), 3);
 
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), 0);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), 0);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MAX), 0);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MIN), 0);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
 
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
-                assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3);
-                assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3);
             }
         }
 
@@ -526,154 +533,154 @@ macro_rules! int_module {
         test_runtime_and_compiletime! {
             fn test_unbounded_shl() {
                 // <$T>::MIN
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // <$T>::MAX
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 1
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, 1), (1 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, 3), (1 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, 5), (1 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 1), (1 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 3), (1 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 5), (1 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // -1
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_ONE), (-1 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_TWO), (-1 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_THREE), (-1 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, 1), (-1 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, 3), (-1 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, 5), (-1 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_ONE), (-1 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_TWO), (-1 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_THREE), (-1 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, 1), (-1 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, 3), (-1 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, 5), (-1 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 8
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, 1), (8 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, 3), (8 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, 5), (8 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 1), (8 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 3), (8 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 5), (8 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 17
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, 1), (17 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, 3), (17 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, 5), (17 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 1), (17 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 3), (17 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 5), (17 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
             }
 
             fn test_unbounded_shr() {
                 // <$T>::MIN
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), -1);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), -1);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), -1);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), -1);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), -1);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), -1);
 
                 // <$T>::MAX
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 1
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, 1), (1 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, 3), (1 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, 5), (1 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 1), (1 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 3), (1 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 5), (1 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // -1
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_ONE), (-1 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_TWO), (-1 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_THREE), (-1 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, 1), (-1 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, 3), (-1 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, 5), (-1 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW2), -1);
-                assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW3), -1);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_ONE), (-1 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_TWO), (-1 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_THREE), (-1 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, 1), (-1 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, 3), (-1 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, 5), (-1 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW2), -1);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW3), -1);
 
                 // 8
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, 1), (8 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, 3), (8 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, 5), (8 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 1), (8 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 3), (8 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 5), (8 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 17
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, 1), (17 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, 3), (17 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, 5), (17 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 1), (17 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 3), (17 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 5), (17 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
             }
         }
     };
diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs
index d09eb97b17e..2e35e8bf534 100644
--- a/library/coretests/tests/num/uint_macros.rs
+++ b/library/coretests/tests/num/uint_macros.rs
@@ -1,5 +1,6 @@
 macro_rules! uint_module {
     ($T:ident) => {
+        use core::num::ParseIntError;
         use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
         use core::$T::*;
 
@@ -49,95 +50,95 @@ macro_rules! uint_module {
 
             fn test_leading_trailing_ones() {
                 const A: $T = 0b0101_1111;
-                assert_eq_const_safe!(A.trailing_ones(), 5);
-                assert_eq_const_safe!((!A).leading_ones(), $T::BITS - 7);
+                assert_eq_const_safe!(u32: A.trailing_ones(), 5);
+                assert_eq_const_safe!(u32: (!A).leading_ones(), $T::BITS - 7);
 
-                assert_eq_const_safe!(A.reverse_bits().leading_ones(), 5);
+                assert_eq_const_safe!(u32: A.reverse_bits().leading_ones(), 5);
 
-                assert_eq_const_safe!(_1.leading_ones(), $T::BITS);
-                assert_eq_const_safe!(_1.trailing_ones(), $T::BITS);
+                assert_eq_const_safe!(u32: _1.leading_ones(), $T::BITS);
+                assert_eq_const_safe!(u32: _1.trailing_ones(), $T::BITS);
 
-                assert_eq_const_safe!((_1 << 1).trailing_ones(), 0);
-                assert_eq_const_safe!((_1 >> 1).leading_ones(), 0);
+                assert_eq_const_safe!(u32: (_1 << 1).trailing_ones(), 0);
+                assert_eq_const_safe!(u32: (_1 >> 1).leading_ones(), 0);
 
-                assert_eq_const_safe!((_1 << 1).leading_ones(), $T::BITS - 1);
-                assert_eq_const_safe!((_1 >> 1).trailing_ones(), $T::BITS - 1);
+                assert_eq_const_safe!(u32: (_1 << 1).leading_ones(), $T::BITS - 1);
+                assert_eq_const_safe!(u32: (_1 >> 1).trailing_ones(), $T::BITS - 1);
 
-                assert_eq_const_safe!(_0.leading_ones(), 0);
-                assert_eq_const_safe!(_0.trailing_ones(), 0);
+                assert_eq_const_safe!(u32: _0.leading_ones(), 0);
+                assert_eq_const_safe!(u32: _0.trailing_ones(), 0);
 
                 const X: $T = 0b0010_1100;
-                assert_eq_const_safe!(X.leading_ones(), 0);
-                assert_eq_const_safe!(X.trailing_ones(), 0);
+                assert_eq_const_safe!(u32: X.leading_ones(), 0);
+                assert_eq_const_safe!(u32: X.trailing_ones(), 0);
             }
 
             fn test_rotate() {
-                assert_eq_const_safe!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-                assert_eq_const_safe!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
-                assert_eq_const_safe!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+                assert_eq_const_safe!($T: A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+                assert_eq_const_safe!($T: B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+                assert_eq_const_safe!($T: C.rotate_left(6).rotate_right(2).rotate_right(4), C);
 
                 // Rotating these should make no difference
                 //
                 // We test using 124 bits because to ensure that overlong bit shifts do
                 // not cause undefined behavior. See #10183.
-                assert_eq_const_safe!(_0.rotate_left(124), _0);
-                assert_eq_const_safe!(_1.rotate_left(124), _1);
-                assert_eq_const_safe!(_0.rotate_right(124), _0);
-                assert_eq_const_safe!(_1.rotate_right(124), _1);
+                assert_eq_const_safe!($T: _0.rotate_left(124), _0);
+                assert_eq_const_safe!($T: _1.rotate_left(124), _1);
+                assert_eq_const_safe!($T: _0.rotate_right(124), _0);
+                assert_eq_const_safe!($T: _1.rotate_right(124), _1);
 
                 // Rotating by 0 should have no effect
-                assert_eq_const_safe!(A.rotate_left(0), A);
-                assert_eq_const_safe!(B.rotate_left(0), B);
-                assert_eq_const_safe!(C.rotate_left(0), C);
+                assert_eq_const_safe!($T: A.rotate_left(0), A);
+                assert_eq_const_safe!($T: B.rotate_left(0), B);
+                assert_eq_const_safe!($T: C.rotate_left(0), C);
                 // Rotating by a multiple of word size should also have no effect
-                assert_eq_const_safe!(A.rotate_left(128), A);
-                assert_eq_const_safe!(B.rotate_left(128), B);
-                assert_eq_const_safe!(C.rotate_left(128), C);
+                assert_eq_const_safe!($T: A.rotate_left(128), A);
+                assert_eq_const_safe!($T: B.rotate_left(128), B);
+                assert_eq_const_safe!($T: C.rotate_left(128), C);
             }
 
             fn test_swap_bytes() {
-                assert_eq_const_safe!(A.swap_bytes().swap_bytes(), A);
-                assert_eq_const_safe!(B.swap_bytes().swap_bytes(), B);
-                assert_eq_const_safe!(C.swap_bytes().swap_bytes(), C);
+                assert_eq_const_safe!($T: A.swap_bytes().swap_bytes(), A);
+                assert_eq_const_safe!($T: B.swap_bytes().swap_bytes(), B);
+                assert_eq_const_safe!($T: C.swap_bytes().swap_bytes(), C);
 
                 // Swapping these should make no difference
-                assert_eq_const_safe!(_0.swap_bytes(), _0);
-                assert_eq_const_safe!(_1.swap_bytes(), _1);
+                assert_eq_const_safe!($T: _0.swap_bytes(), _0);
+                assert_eq_const_safe!($T: _1.swap_bytes(), _1);
             }
 
             fn test_reverse_bits() {
-                assert_eq_const_safe!(A.reverse_bits().reverse_bits(), A);
-                assert_eq_const_safe!(B.reverse_bits().reverse_bits(), B);
-                assert_eq_const_safe!(C.reverse_bits().reverse_bits(), C);
+                assert_eq_const_safe!($T: A.reverse_bits().reverse_bits(), A);
+                assert_eq_const_safe!($T: B.reverse_bits().reverse_bits(), B);
+                assert_eq_const_safe!($T: C.reverse_bits().reverse_bits(), C);
 
                 // Swapping these should make no difference
-                assert_eq_const_safe!(_0.reverse_bits(), _0);
-                assert_eq_const_safe!(_1.reverse_bits(), _1);
+                assert_eq_const_safe!($T: _0.reverse_bits(), _0);
+                assert_eq_const_safe!($T: _1.reverse_bits(), _1);
             }
 
             fn test_le() {
-                assert_eq_const_safe!($T::from_le(A.to_le()), A);
-                assert_eq_const_safe!($T::from_le(B.to_le()), B);
-                assert_eq_const_safe!($T::from_le(C.to_le()), C);
-                assert_eq_const_safe!($T::from_le(_0), _0);
-                assert_eq_const_safe!($T::from_le(_1), _1);
-                assert_eq_const_safe!(_0.to_le(), _0);
-                assert_eq_const_safe!(_1.to_le(), _1);
+                assert_eq_const_safe!($T: $T::from_le(A.to_le()), A);
+                assert_eq_const_safe!($T: $T::from_le(B.to_le()), B);
+                assert_eq_const_safe!($T: $T::from_le(C.to_le()), C);
+                assert_eq_const_safe!($T: $T::from_le(_0), _0);
+                assert_eq_const_safe!($T: $T::from_le(_1), _1);
+                assert_eq_const_safe!($T: _0.to_le(), _0);
+                assert_eq_const_safe!($T: _1.to_le(), _1);
             }
 
             fn test_be() {
-                assert_eq_const_safe!($T::from_be(A.to_be()), A);
-                assert_eq_const_safe!($T::from_be(B.to_be()), B);
-                assert_eq_const_safe!($T::from_be(C.to_be()), C);
-                assert_eq_const_safe!($T::from_be(_0), _0);
-                assert_eq_const_safe!($T::from_be(_1), _1);
-                assert_eq_const_safe!(_0.to_be(), _0);
-                assert_eq_const_safe!(_1.to_be(), _1);
+                assert_eq_const_safe!($T: $T::from_be(A.to_be()), A);
+                assert_eq_const_safe!($T: $T::from_be(B.to_be()), B);
+                assert_eq_const_safe!($T: $T::from_be(C.to_be()), C);
+                assert_eq_const_safe!($T: $T::from_be(_0), _0);
+                assert_eq_const_safe!($T: $T::from_be(_1), _1);
+                assert_eq_const_safe!($T: _0.to_be(), _0);
+                assert_eq_const_safe!($T: _1.to_be(), _1);
             }
 
             fn test_unsigned_checked_div() {
-                assert_eq_const_safe!((10 as $T).checked_div(2), Some(5));
-                assert_eq_const_safe!((5 as $T).checked_div(0), None);
+                assert_eq_const_safe!(Option<$T>: (10 as $T).checked_div(2), Some(5));
+                assert_eq_const_safe!(Option<$T>: (5 as $T).checked_div(0), None);
             }
         }
 
@@ -194,12 +195,12 @@ macro_rules! uint_module {
 
         test_runtime_and_compiletime! {
             fn test_parse_bytes() {
-                assert_eq_const_safe!($T::from_str_radix("123", 10), Ok(123 as $T));
-                assert_eq_const_safe!($T::from_str_radix("1001", 2), Ok(9 as $T));
-                assert_eq_const_safe!($T::from_str_radix("123", 8), Ok(83 as $T));
-                assert_eq_const_safe!(u16::from_str_radix("123", 16), Ok(291 as u16));
-                assert_eq_const_safe!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
-                assert_eq_const_safe!($T::from_str_radix("z", 36), Ok(35 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 10), Ok(123 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("1001", 2), Ok(9 as $T));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 8), Ok(83 as $T));
+                assert_eq_const_safe!(Result<u16, ParseIntError>: u16::from_str_radix("123", 16), Ok(291 as u16));
+                assert_eq_const_safe!(Result<u16, ParseIntError>: u16::from_str_radix("ffff", 16), Ok(65535 as u16));
+                assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("z", 36), Ok(35 as $T));
 
                 assert!($T::from_str_radix("Z", 10).is_err());
                 assert!($T::from_str_radix("_", 2).is_err());
@@ -208,16 +209,16 @@ macro_rules! uint_module {
             fn test_pow() {
                 {
                     const R: $T = 2;
-                    assert_eq_const_safe!(R.pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.pow(0), 1 as $T);
-                    assert_eq_const_safe!(R.wrapping_pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.wrapping_pow(0), 1 as $T);
-                    assert_eq_const_safe!(R.checked_pow(2), Some(4 as $T));
-                    assert_eq_const_safe!(R.checked_pow(0), Some(1 as $T));
-                    assert_eq_const_safe!(R.overflowing_pow(2), (4 as $T, false));
-                    assert_eq_const_safe!(R.overflowing_pow(0), (1 as $T, false));
-                    assert_eq_const_safe!(R.saturating_pow(2), 4 as $T);
-                    assert_eq_const_safe!(R.saturating_pow(0), 1 as $T);
+                    assert_eq_const_safe!($T: R.pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.pow(0), 1 as $T);
+                    assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
+                    assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
+                    assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
                 }
 
                 {
@@ -226,20 +227,20 @@ macro_rules! uint_module {
                     // if itest::MAX == 2^j-1, then itest is a `j` bit int,
                     // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
                     // thussaturating_pow the overflowing result is exactly 1.
-                    assert_eq_const_safe!(R.wrapping_pow(2), 1 as $T);
-                    assert_eq_const_safe!(R.checked_pow(2), None);
-                    assert_eq_const_safe!(R.overflowing_pow(2), (1 as $T, true));
-                    assert_eq_const_safe!(R.saturating_pow(2), MAX);
+                    assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T);
+                    assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None);
+                    assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, true));
+                    assert_eq_const_safe!($T: R.saturating_pow(2), MAX);
                 }
             }
 
             fn test_isqrt() {
-                assert_eq_const_safe!((0 as $T).isqrt(), 0 as $T);
-                assert_eq_const_safe!((1 as $T).isqrt(), 1 as $T);
-                assert_eq_const_safe!((2 as $T).isqrt(), 1 as $T);
-                assert_eq_const_safe!((99 as $T).isqrt(), 9 as $T);
-                assert_eq_const_safe!((100 as $T).isqrt(), 10 as $T);
-                assert_eq_const_safe!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1);
+                assert_eq_const_safe!($T: (0 as $T).isqrt(), 0 as $T);
+                assert_eq_const_safe!($T: (1 as $T).isqrt(), 1 as $T);
+                assert_eq_const_safe!($T: (2 as $T).isqrt(), 1 as $T);
+                assert_eq_const_safe!($T: (99 as $T).isqrt(), 9 as $T);
+                assert_eq_const_safe!($T: (100 as $T).isqrt(), 10 as $T);
+                assert_eq_const_safe!($T: $T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1);
             }
         }
 
@@ -264,24 +265,24 @@ macro_rules! uint_module {
 
         test_runtime_and_compiletime! {
             fn test_div_floor() {
-                assert_eq_const_safe!((8 as $T).div_floor(3), 2);
+                assert_eq_const_safe!($T: (8 as $T).div_floor(3), 2);
             }
 
             fn test_div_ceil() {
-                assert_eq_const_safe!((8 as $T).div_ceil(3), 3);
+                assert_eq_const_safe!($T: (8 as $T).div_ceil(3), 3);
             }
 
             fn test_next_multiple_of() {
-                assert_eq_const_safe!((16 as $T).next_multiple_of(8), 16);
-                assert_eq_const_safe!((23 as $T).next_multiple_of(8), 24);
-                assert_eq_const_safe!(MAX.next_multiple_of(1), MAX);
+                assert_eq_const_safe!($T: (16 as $T).next_multiple_of(8), 16);
+                assert_eq_const_safe!($T: (23 as $T).next_multiple_of(8), 24);
+                assert_eq_const_safe!($T: MAX.next_multiple_of(1), MAX);
             }
 
             fn test_checked_next_multiple_of() {
-                assert_eq_const_safe!((16 as $T).checked_next_multiple_of(8), Some(16));
-                assert_eq_const_safe!((23 as $T).checked_next_multiple_of(8), Some(24));
-                assert_eq_const_safe!((1 as $T).checked_next_multiple_of(0), None);
-                assert_eq_const_safe!(MAX.checked_next_multiple_of(2), None);
+                assert_eq_const_safe!(Option<$T>: (16 as $T).checked_next_multiple_of(8), Some(16));
+                assert_eq_const_safe!(Option<$T>: (23 as $T).checked_next_multiple_of(8), Some(24));
+                assert_eq_const_safe!(Option<$T>: (1 as $T).checked_next_multiple_of(0), None);
+                assert_eq_const_safe!(Option<$T>: MAX.checked_next_multiple_of(2), None);
             }
 
             fn test_is_next_multiple_of() {
@@ -292,63 +293,63 @@ macro_rules! uint_module {
             }
 
             fn test_carrying_add() {
-                assert_eq_const_safe!($T::MAX.carrying_add(1, false), (0, true));
-                assert_eq_const_safe!($T::MAX.carrying_add(0, true), (0, true));
-                assert_eq_const_safe!($T::MAX.carrying_add(1, true), (1, true));
+                assert_eq_const_safe!(($T, bool): $T::MAX.carrying_add(1, false), (0, true));
+                assert_eq_const_safe!(($T, bool): $T::MAX.carrying_add(0, true), (0, true));
+                assert_eq_const_safe!(($T, bool): $T::MAX.carrying_add(1, true), (1, true));
 
-                assert_eq_const_safe!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false));
-                assert_eq_const_safe!($T::MIN.carrying_add(0, true), (1, false));
-                assert_eq_const_safe!($T::MIN.carrying_add($T::MAX, true), (0, true));
+                assert_eq_const_safe!(($T, bool): $T::MIN.carrying_add($T::MAX, false), ($T::MAX, false));
+                assert_eq_const_safe!(($T, bool): $T::MIN.carrying_add(0, true), (1, false));
+                assert_eq_const_safe!(($T, bool): $T::MIN.carrying_add($T::MAX, true), (0, true));
             }
 
             fn test_borrowing_sub() {
-                assert_eq_const_safe!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
-                assert_eq_const_safe!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
-                assert_eq_const_safe!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
+                assert_eq_const_safe!(($T, bool): $T::MIN.borrowing_sub(1, false), ($T::MAX, true));
+                assert_eq_const_safe!(($T, bool): $T::MIN.borrowing_sub(0, true), ($T::MAX, true));
+                assert_eq_const_safe!(($T, bool): $T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
 
-                assert_eq_const_safe!($T::MAX.borrowing_sub($T::MAX, false), (0, false));
-                assert_eq_const_safe!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
-                assert_eq_const_safe!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
+                assert_eq_const_safe!(($T, bool): $T::MAX.borrowing_sub($T::MAX, false), (0, false));
+                assert_eq_const_safe!(($T, bool): $T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
+                assert_eq_const_safe!(($T, bool): $T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
             }
 
             fn test_widening_mul() {
-                assert_eq_const_safe!($T::MAX.widening_mul($T::MAX), (1, $T::MAX - 1));
+                assert_eq_const_safe!(($T, $T): $T::MAX.widening_mul($T::MAX), (1, $T::MAX - 1));
             }
 
             fn test_carrying_mul() {
-                assert_eq_const_safe!($T::MAX.carrying_mul($T::MAX, 0), (1, $T::MAX - 1));
-                assert_eq_const_safe!($T::MAX.carrying_mul($T::MAX, $T::MAX), (0, $T::MAX));
+                assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul($T::MAX, 0), (1, $T::MAX - 1));
+                assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul($T::MAX, $T::MAX), (0, $T::MAX));
             }
 
             fn test_carrying_mul_add() {
-                assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, 0, 0), (1, $T::MAX - 1));
-                assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, $T::MAX, 0), (0, $T::MAX));
-                assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, $T::MAX, $T::MAX), ($T::MAX, $T::MAX));
+                assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul_add($T::MAX, 0, 0), (1, $T::MAX - 1));
+                assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul_add($T::MAX, $T::MAX, 0), (0, $T::MAX));
+                assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul_add($T::MAX, $T::MAX, $T::MAX), ($T::MAX, $T::MAX));
             }
 
             fn test_midpoint() {
-                assert_eq_const_safe!(<$T>::midpoint(1, 3), 2);
-                assert_eq_const_safe!(<$T>::midpoint(3, 1), 2);
-
-                assert_eq_const_safe!(<$T>::midpoint(0, 0), 0);
-                assert_eq_const_safe!(<$T>::midpoint(0, 2), 1);
-                assert_eq_const_safe!(<$T>::midpoint(2, 0), 1);
-                assert_eq_const_safe!(<$T>::midpoint(2, 2), 2);
-
-                assert_eq_const_safe!(<$T>::midpoint(1, 4), 2);
-                assert_eq_const_safe!(<$T>::midpoint(4, 1), 2);
-                assert_eq_const_safe!(<$T>::midpoint(3, 4), 3);
-                assert_eq_const_safe!(<$T>::midpoint(4, 3), 3);
-
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
-
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
-                assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
-                assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3);
-                assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(1, 3), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(3, 1), 2);
+
+                assert_eq_const_safe!($T: <$T>::midpoint(0, 0), 0);
+                assert_eq_const_safe!($T: <$T>::midpoint(0, 2), 1);
+                assert_eq_const_safe!($T: <$T>::midpoint(2, 0), 1);
+                assert_eq_const_safe!($T: <$T>::midpoint(2, 2), 2);
+
+                assert_eq_const_safe!($T: <$T>::midpoint(1, 4), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(4, 1), 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(3, 4), 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(4, 3), 3);
+
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
+
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3);
+                assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3);
             }
         }
 
@@ -365,154 +366,154 @@ macro_rules! uint_module {
         test_runtime_and_compiletime! {
             fn test_unbounded_shl() {
                 // <$T>::MIN
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // <$T>::MAX
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 1
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, 1), (1 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, 3), (1 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, 5), (1 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 1), (1 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 3), (1 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 5), (1 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // !0
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_ONE), (!0 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_TWO), (!0 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_THREE), (!0 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, 1), (!0 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, 3), (!0 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, 5), (!0 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_ONE), (!0 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_TWO), (!0 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_THREE), (!0 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, 1), (!0 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, 3), (!0 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, 5), (!0 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 8
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, 1), (8 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, 3), (8 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, 5), (8 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 1), (8 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 3), (8 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 5), (8 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 17
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, 1), (17 << 1));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, 3), (17 << 3));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, 5), (17 << 5));
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 1), (17 << 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 3), (17 << 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 5), (17 << 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
             }
 
             fn test_unbounded_shr() {
                 // <$T>::MIN
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // <$T>::MAX
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 1
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, 1), (1 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, 3), (1 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, 5), (1 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 1), (1 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 3), (1 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 5), (1 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // !0
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_ONE), (!0 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_TWO), (!0 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_THREE), (!0 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, 1), (!0 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, 3), (!0 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, 5), (!0 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_ONE), (!0 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_TWO), (!0 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_THREE), (!0 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, 1), (!0 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, 3), (!0 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, 5), (!0 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 8
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, 1), (8 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, 3), (8 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, 5), (8 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 1), (8 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 3), (8 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 5), (8 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
 
                 // 17
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, 1), (17 >> 1));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, 3), (17 >> 3));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, 5), (17 >> 5));
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
-                assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 1), (17 >> 1));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 3), (17 >> 3));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 5), (17 >> 5));
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
+                assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
             }
         }
     };
diff --git a/library/coretests/tests/pin.rs b/library/coretests/tests/pin.rs
index a866cf12a3b..b3fb06e710d 100644
--- a/library/coretests/tests/pin.rs
+++ b/library/coretests/tests/pin.rs
@@ -34,9 +34,6 @@ fn pin_const() {
     }
 
     pin_mut_const();
-
-    // Check that we accept a Rust 2024 $expr.
-    std::pin::pin!(const { 1 });
 }
 
 #[allow(unused)]
@@ -84,14 +81,3 @@ mod pin_coerce_unsized {
         arg
     }
 }
-
-#[test]
-#[cfg(not(bootstrap))]
-fn temp_lifetime() {
-    // Check that temporary lifetimes work as in Rust 2021.
-    // Regression test for https://github.com/rust-lang/rust/issues/138596
-    match std::pin::pin!(foo(&mut 0)) {
-        _ => {}
-    }
-    async fn foo(_: &mut usize) {}
-}
diff --git a/library/coretests/tests/pin_macro.rs b/library/coretests/tests/pin_macro.rs
index 43542397a61..3174c91a649 100644
--- a/library/coretests/tests/pin_macro.rs
+++ b/library/coretests/tests/pin_macro.rs
@@ -30,3 +30,31 @@ fn unsize_coercion() {
     let dyn_obj: Pin<&mut dyn Send> = pin!([PhantomPinned; 2]);
     stuff(dyn_obj);
 }
+
+#[test]
+fn rust_2024_expr() {
+    // Check that we accept a Rust 2024 $expr.
+    std::pin::pin!(const { 1 });
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn temp_lifetime() {
+    // Check that temporary lifetimes work as in Rust 2021.
+    // Regression test for https://github.com/rust-lang/rust/issues/138596
+    match std::pin::pin!(foo(&mut 0)) {
+        _ => {}
+    }
+    async fn foo(_: &mut usize) {}
+}
+
+#[test]
+fn transitive_extension() {
+    async fn temporary() {}
+
+    // `pin!` witnessed in the wild being used like this, even if it yields
+    // a `Pin<&mut &mut impl Unpin>`; it does work because `pin!`
+    // happens to transitively extend the lifespan of `temporary()`.
+    let p = pin!(&mut temporary());
+    let _use = p;
+}
diff --git a/library/coretests/tests/str.rs b/library/coretests/tests/str.rs
index f5066343af2..5e23e910f0a 100644
--- a/library/coretests/tests/str.rs
+++ b/library/coretests/tests/str.rs
@@ -1 +1 @@
-// All `str` tests live in library/alloc/tests/str.rs
+// All `str` tests live in library/alloctests/tests/str.rs
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index fa98db69306..801baf3d990 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2370,7 +2370,7 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 #[doc(alias = "rm", alias = "unlink", alias = "DeleteFile")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
-    fs_imp::unlink(path.as_ref())
+    fs_imp::remove_file(path.as_ref())
 }
 
 /// Given a path, queries the file system to get information about a file,
@@ -2409,7 +2409,7 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
 #[doc(alias = "stat")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
-    fs_imp::stat(path.as_ref()).map(Metadata)
+    fs_imp::metadata(path.as_ref()).map(Metadata)
 }
 
 /// Queries the metadata about a file without following symlinks.
@@ -2444,7 +2444,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 #[doc(alias = "lstat")]
 #[stable(feature = "symlink_metadata", since = "1.1.0")]
 pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
-    fs_imp::lstat(path.as_ref()).map(Metadata)
+    fs_imp::symlink_metadata(path.as_ref()).map(Metadata)
 }
 
 /// Renames a file or directory to a new name, replacing the original file if
@@ -2598,7 +2598,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
 #[doc(alias = "CreateHardLink", alias = "linkat")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
-    fs_imp::link(original.as_ref(), link.as_ref())
+    fs_imp::hard_link(original.as_ref(), link.as_ref())
 }
 
 /// Creates a new symbolic link on the filesystem.
@@ -2664,7 +2664,7 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Re
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
-    fs_imp::readlink(path.as_ref())
+    fs_imp::read_link(path.as_ref())
 }
 
 /// Returns the canonical, absolute form of a path with all intermediate
@@ -2840,7 +2840,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 #[doc(alias = "rmdir", alias = "RemoveDirectory")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
-    fs_imp::rmdir(path.as_ref())
+    fs_imp::remove_dir(path.as_ref())
 }
 
 /// Removes a directory at this path, after removing all its contents. Use
@@ -2967,7 +2967,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 #[doc(alias = "ls", alias = "opendir", alias = "FindFirstFile", alias = "FindNextFile")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
-    fs_imp::readdir(path.as_ref()).map(ReadDir)
+    fs_imp::read_dir(path.as_ref()).map(ReadDir)
 }
 
 /// Changes the permissions found on a file or a directory.
@@ -3003,7 +3003,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
 #[doc(alias = "chmod", alias = "SetFileAttributes")]
 #[stable(feature = "set_permissions", since = "1.1.0")]
 pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
-    fs_imp::set_perm(path.as_ref(), perm.0)
+    fs_imp::set_permissions(path.as_ref(), perm.0)
 }
 
 impl DirBuilder {
diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs
index 9fd2472ebdf..574288e579e 100644
--- a/library/std/src/io/buffered/bufreader/buffer.rs
+++ b/library/std/src/io/buffered/bufreader/buffer.rs
@@ -123,7 +123,6 @@ impl Buffer {
     /// Remove bytes that have already been read from the buffer.
     pub fn backshift(&mut self) {
         self.buf.copy_within(self.pos.., 0);
-        self.initialized -= self.pos;
         self.filled -= self.pos;
         self.pos = 0;
     }
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index 8d733325b3b..15e962924ac 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -248,8 +248,11 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
                     Err(e) => return Err(e),
                 }
             } else {
+                // All the bytes that were already in the buffer are initialized,
+                // treat them as such when the buffer is flushed.
+                init += buf.len();
+
                 self.flush_buf()?;
-                init = 0;
             }
         }
     }
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 6579b6887aa..314cbb45d49 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2989,11 +2989,11 @@ impl<T: Read> Read for Take<T> {
             return Ok(());
         }
 
-        if self.limit <= buf.capacity() as u64 {
-            // if we just use an as cast to convert, limit may wrap around on a 32 bit target
-            let limit = cmp::min(self.limit, usize::MAX as u64) as usize;
+        if self.limit < buf.capacity() as u64 {
+            // The condition above guarantees that `self.limit` fits in `usize`.
+            let limit = self.limit as usize;
 
-            let extra_init = cmp::min(limit as usize, buf.init_ref().len());
+            let extra_init = cmp::min(limit, buf.init_ref().len());
 
             // SAFETY: no uninit data is written to ibuf
             let ibuf = unsafe { &mut buf.as_mut()[..limit] };
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index ad005833ad5..5c381181218 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -297,6 +297,7 @@
 #![feature(extended_varargs_abi_support)]
 #![feature(f128)]
 #![feature(f16)]
+#![feature(ffi_const)]
 #![feature(formatting_options)]
 #![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
@@ -340,6 +341,7 @@
 #![feature(exact_size_is_empty)]
 #![feature(exclusive_wrapper)]
 #![feature(extend_one)]
+#![feature(float_algebraic)]
 #![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
 #![feature(fmt_internals)]
diff --git a/library/std/src/net/socket_addr.rs b/library/std/src/net/socket_addr.rs
index 4c8905c0d46..41e623e79ce 100644
--- a/library/std/src/net/socket_addr.rs
+++ b/library/std/src/net/socket_addr.rs
@@ -101,7 +101,7 @@ use crate::{io, iter, option, slice, vec};
 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
 /// ```
 ///
-/// [`TcpStream::connect`] is an example of an function that utilizes
+/// [`TcpStream::connect`] is an example of a function that utilizes
 /// `ToSocketAddrs` as a trait bound on its parameter in order to accept
 /// different types:
 ///
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index f81ce8e1a1a..3b765a9537b 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1836,7 +1836,7 @@ impl crate::sealed::Sealed for ExitStatusError {}
 /// # if cfg!(unix) {
 /// use std::process::{Command, ExitStatusError};
 ///
-/// fn run(cmd: &str) -> Result<(),ExitStatusError> {
+/// fn run(cmd: &str) -> Result<(), ExitStatusError> {
 ///     Command::new(cmd).status().unwrap().exit_ok()?;
 ///     Ok(())
 /// }
diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs
index 5b50a3c6ccf..e67b4f6f22f 100644
--- a/library/std/src/sync/mod.rs
+++ b/library/std/src/sync/mod.rs
@@ -176,6 +176,8 @@ pub use core::sync::Exclusive;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::sync::atomic;
 
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+pub use alloc_crate::sync::UniqueArc;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::sync::{Arc, Weak};
 
diff --git a/library/std/src/sys/pal/hermit/fd.rs b/library/std/src/sys/fd/hermit.rs
index edd984d920a..7e8ba065f1b 100644
--- a/library/std/src/sys/pal/hermit/fd.rs
+++ b/library/std/src/sys/fd/hermit.rs
@@ -1,8 +1,8 @@
 #![unstable(reason = "not public", issue = "none", feature = "fd")]
 
-use super::hermit_abi;
 use crate::cmp;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, SeekFrom};
+use crate::os::hermit::hermit_abi;
 use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
 use crate::sys::{cvt, unsupported};
 use crate::sys_common::{AsInner, FromInner, IntoInner};
diff --git a/library/std/src/sys/fd/mod.rs b/library/std/src/sys/fd/mod.rs
new file mode 100644
index 00000000000..e0f5eab6951
--- /dev/null
+++ b/library/std/src/sys/fd/mod.rs
@@ -0,0 +1,19 @@
+//! Platform-dependent file descriptor abstraction.
+
+#![forbid(unsafe_op_in_unsafe_fn)]
+
+cfg_if::cfg_if! {
+    if #[cfg(target_family = "unix")] {
+        mod unix;
+        pub use unix::*;
+    } else if #[cfg(target_os = "hermit")] {
+        mod hermit;
+        pub use hermit::*;
+    } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
+        mod sgx;
+        pub use sgx::*;
+    } else if #[cfg(target_os = "wasi")] {
+        mod wasi;
+        pub use wasi::*;
+    }
+}
diff --git a/library/std/src/sys/pal/sgx/fd.rs b/library/std/src/sys/fd/sgx.rs
index 399f6a16489..1ef768db64c 100644
--- a/library/std/src/sys/pal/sgx/fd.rs
+++ b/library/std/src/sys/fd/sgx.rs
@@ -1,8 +1,8 @@
 use fortanix_sgx_abi::Fd;
 
-use super::abi::usercalls;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
+use crate::sys::pal::abi::usercalls;
 use crate::sys::{AsInner, FromInner, IntoInner};
 
 #[derive(Debug)]
diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/fd/unix.rs
index f03c440e30e..2042ea2c73d 100644
--- a/library/std/src/sys/pal/unix/fd.rs
+++ b/library/std/src/sys/fd/unix.rs
@@ -22,6 +22,10 @@ use crate::cmp;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read};
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
 use crate::sys::cvt;
+#[cfg(all(target_os = "android", target_pointer_width = "64"))]
+use crate::sys::pal::weak::syscall;
+#[cfg(any(all(target_os = "android", target_pointer_width = "32"), target_vendor = "apple"))]
+use crate::sys::pal::weak::weak;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 
 #[derive(Debug)]
@@ -232,14 +236,14 @@ impl FileDesc {
     // implementation if `preadv` is not available.
     #[cfg(all(target_os = "android", target_pointer_width = "64"))]
     pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::syscall! {
+        syscall!(
             fn preadv(
                 fd: libc::c_int,
                 iovec: *const libc::iovec,
                 n_iovec: libc::c_int,
-                offset: off64_t
-            ) -> isize
-        }
+                offset: off64_t,
+            ) -> isize;
+        );
 
         let ret = cvt(unsafe {
             preadv(
@@ -257,7 +261,14 @@ impl FileDesc {
     // and its metadata from LLVM IR.
     #[no_sanitize(cfi)]
     pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        weak!(
+            fn preadv64(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match preadv64.get() {
             Some(preadv) => {
@@ -286,7 +297,14 @@ impl FileDesc {
     // use "weak" linking.
     #[cfg(target_vendor = "apple")]
     pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn preadv(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        weak!(
+            fn preadv(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match preadv.get() {
             Some(preadv) => {
@@ -428,14 +446,14 @@ impl FileDesc {
     // implementation if `pwritev` is not available.
     #[cfg(all(target_os = "android", target_pointer_width = "64"))]
     pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::syscall! {
+        syscall!(
             fn pwritev(
                 fd: libc::c_int,
                 iovec: *const libc::iovec,
                 n_iovec: libc::c_int,
-                offset: off64_t
-            ) -> isize
-        }
+                offset: off64_t,
+            ) -> isize;
+        );
 
         let ret = cvt(unsafe {
             pwritev(
@@ -450,7 +468,14 @@ impl FileDesc {
 
     #[cfg(all(target_os = "android", target_pointer_width = "32"))]
     pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        weak!(
+            fn pwritev64(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match pwritev64.get() {
             Some(pwritev) => {
@@ -479,7 +504,14 @@ impl FileDesc {
     // use "weak" linking.
     #[cfg(target_vendor = "apple")]
     pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn pwritev(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        weak!(
+            fn pwritev(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match pwritev.get() {
             Some(pwritev) => {
@@ -641,6 +673,6 @@ impl IntoRawFd for FileDesc {
 
 impl FromRawFd for FileDesc {
     unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
-        Self(FromRawFd::from_raw_fd(raw_fd))
+        Self(unsafe { FromRawFd::from_raw_fd(raw_fd) })
     }
 }
diff --git a/library/std/src/sys/pal/unix/fd/tests.rs b/library/std/src/sys/fd/unix/tests.rs
index c5301ce6557..fcd66c71707 100644
--- a/library/std/src/sys/pal/unix/fd/tests.rs
+++ b/library/std/src/sys/fd/unix/tests.rs
@@ -1,6 +1,7 @@
 use core::mem::ManuallyDrop;
 
-use super::{FileDesc, IoSlice};
+use super::FileDesc;
+use crate::io::IoSlice;
 use crate::os::unix::io::FromRawFd;
 
 #[test]
diff --git a/library/std/src/sys/pal/wasi/fd.rs b/library/std/src/sys/fd/wasi.rs
index 4b3dd1ce49e..80a5143ff0b 100644
--- a/library/std/src/sys/pal/wasi/fd.rs
+++ b/library/std/src/sys/fd/wasi.rs
@@ -1,11 +1,10 @@
-#![forbid(unsafe_op_in_unsafe_fn)]
-#![allow(dead_code)]
+#![expect(dead_code)]
 
-use super::err2io;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem;
 use crate::net::Shutdown;
 use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
+use crate::sys::pal::err2io;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
 #[derive(Debug)]
diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs
index f83a2f90ed2..99690abe8ed 100644
--- a/library/std/src/sys/fs/hermit.rs
+++ b/library/std/src/sys/fs/hermit.rs
@@ -9,8 +9,8 @@ use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Raw
 use crate::path::{Path, PathBuf};
 use crate::sync::Arc;
 use crate::sys::common::small_c_string::run_path_with_cstr;
+use crate::sys::fd::FileDesc;
 pub use crate::sys::fs::common::{copy, exists};
-use crate::sys::pal::fd::FileDesc;
 use crate::sys::time::SystemTime;
 use crate::sys::{cvt, unsupported};
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs
index c2e19eb393a..3b176d0d16c 100644
--- a/library/std/src/sys/fs/mod.rs
+++ b/library/std/src/sys/fs/mod.rs
@@ -1,28 +1,115 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
+use crate::io;
+use crate::path::{Path, PathBuf};
+
 pub mod common;
 
 cfg_if::cfg_if! {
     if #[cfg(target_family = "unix")] {
         mod unix;
-        pub use unix::*;
+        use unix as imp;
+        pub use unix::{chown, fchown, lchown};
+        #[cfg(not(target_os = "fuchsia"))]
+        pub use unix::chroot;
+        pub(crate) use unix::debug_assert_fd_is_open;
+        #[cfg(any(target_os = "linux", target_os = "android"))]
+        pub(crate) use unix::CachedFileMetadata;
+        use crate::sys::common::small_c_string::run_path_with_cstr as with_native_path;
     } else if #[cfg(target_os = "windows")] {
         mod windows;
-        pub use windows::*;
+        use windows as imp;
+        pub use windows::{symlink_inner, junction_point};
     } else if #[cfg(target_os = "hermit")] {
         mod hermit;
-        pub use hermit::*;
+        use hermit as imp;
     } else if #[cfg(target_os = "solid_asp3")] {
         mod solid;
-        pub use solid::*;
+        use solid as imp;
     } else if #[cfg(target_os = "uefi")] {
         mod uefi;
-        pub use uefi::*;
+        use uefi as imp;
     } else if #[cfg(target_os = "wasi")] {
         mod wasi;
-        pub use wasi::*;
+        use wasi as imp;
     } else {
         mod unsupported;
-        pub use unsupported::*;
+        use unsupported as imp;
     }
 }
+
+// FIXME: Replace this with platform-specific path conversion functions.
+#[cfg(not(target_family = "unix"))]
+#[inline]
+pub fn with_native_path<T>(path: &Path, f: &dyn Fn(&Path) -> io::Result<T>) -> io::Result<T> {
+    f(path)
+}
+
+pub use imp::{
+    DirBuilder, DirEntry, File, FileAttr, FilePermissions, FileTimes, FileType, OpenOptions,
+    ReadDir,
+};
+
+pub fn read_dir(path: &Path) -> io::Result<ReadDir> {
+    // FIXME: use with_native_path
+    imp::readdir(path)
+}
+
+pub fn remove_file(path: &Path) -> io::Result<()> {
+    with_native_path(path, &imp::unlink)
+}
+
+pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
+    with_native_path(old, &|old| with_native_path(new, &|new| imp::rename(old, new)))
+}
+
+pub fn remove_dir(path: &Path) -> io::Result<()> {
+    with_native_path(path, &imp::rmdir)
+}
+
+pub fn remove_dir_all(path: &Path) -> io::Result<()> {
+    // FIXME: use with_native_path
+    imp::remove_dir_all(path)
+}
+
+pub fn read_link(path: &Path) -> io::Result<PathBuf> {
+    with_native_path(path, &imp::readlink)
+}
+
+pub fn symlink(original: &Path, link: &Path) -> io::Result<()> {
+    with_native_path(original, &|original| {
+        with_native_path(link, &|link| imp::symlink(original, link))
+    })
+}
+
+pub fn hard_link(original: &Path, link: &Path) -> io::Result<()> {
+    with_native_path(original, &|original| {
+        with_native_path(link, &|link| imp::link(original, link))
+    })
+}
+
+pub fn metadata(path: &Path) -> io::Result<FileAttr> {
+    with_native_path(path, &imp::stat)
+}
+
+pub fn symlink_metadata(path: &Path) -> io::Result<FileAttr> {
+    with_native_path(path, &imp::lstat)
+}
+
+pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> {
+    with_native_path(path, &|path| imp::set_perm(path, perm.clone()))
+}
+
+pub fn canonicalize(path: &Path) -> io::Result<PathBuf> {
+    with_native_path(path, &imp::canonicalize)
+}
+
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+    // FIXME: use with_native_path
+    imp::copy(from, to)
+}
+
+pub fn exists(path: &Path) -> io::Result<bool> {
+    // FIXME: use with_native_path
+    imp::exists(path)
+}
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index 7c3ed8029f7..87865be0387 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -155,15 +155,15 @@ cfg_has_statx! {{
         enum STATX_STATE{ Unknown = 0, Present, Unavailable }
         static STATX_SAVED_STATE: AtomicU8 = AtomicU8::new(STATX_STATE::Unknown as u8);
 
-        syscall! {
+        syscall!(
             fn statx(
                 fd: c_int,
                 pathname: *const c_char,
                 flags: c_int,
                 mask: libc::c_uint,
-                statxbuf: *mut libc::statx
-            ) -> c_int
-        }
+                statxbuf: *mut libc::statx,
+            ) -> c_int;
+        );
 
         let statx_availability = STATX_SAVED_STATE.load(Ordering::Relaxed);
         if statx_availability == STATX_STATE::Unavailable as u8 {
@@ -926,7 +926,7 @@ impl DirEntry {
         miri
     ))]
     pub fn metadata(&self) -> io::Result<FileAttr> {
-        lstat(&self.path())
+        run_path_with_cstr(&self.path(), &lstat)
     }
 
     #[cfg(any(
@@ -1540,7 +1540,9 @@ impl File {
                 let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
                 // futimens requires Android API level 19
                 cvt(unsafe {
-                    weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
+                    weak!(
+                        fn futimens(fd: c_int, times: *const libc::timespec) -> c_int;
+                    );
                     match futimens.get() {
                         Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()),
                         None => return Err(io::const_error!(
@@ -1556,7 +1558,9 @@ impl File {
                     use crate::sys::{time::__timespec64, weak::weak};
 
                     // Added in glibc 2.34
-                    weak!(fn __futimens64(libc::c_int, *const __timespec64) -> libc::c_int);
+                    weak!(
+                        fn __futimens64(fd: c_int, times: *const __timespec64) -> c_int;
+                    );
 
                     if let Some(futimens64) = __futimens64.get() {
                         let to_timespec = |time: Option<SystemTime>| time.map(|time| time.t.to_timespec64())
@@ -1653,7 +1657,7 @@ impl fmt::Debug for File {
         fn get_path(fd: c_int) -> Option<PathBuf> {
             let mut p = PathBuf::from("/proc/self/fd");
             p.push(&fd.to_string());
-            readlink(&p).ok()
+            run_path_with_cstr(&p, &readlink).ok()
         }
 
         #[cfg(any(target_vendor = "apple", target_os = "netbsd"))]
@@ -1671,7 +1675,7 @@ impl fmt::Debug for File {
                         // fallback to procfs as last resort
                         let mut p = PathBuf::from("/proc/self/fd");
                         p.push(&fd.to_string());
-                        return readlink(&p).ok();
+                        return run_path_with_cstr(&p, &readlink).ok()
                     } else {
                         return None;
                     }
@@ -1826,127 +1830,106 @@ pub fn readdir(path: &Path) -> io::Result<ReadDir> {
     }
 }
 
-pub fn unlink(p: &Path) -> io::Result<()> {
-    run_path_with_cstr(p, &|p| cvt(unsafe { libc::unlink(p.as_ptr()) }).map(|_| ()))
+pub fn unlink(p: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::unlink(p.as_ptr()) }).map(|_| ())
 }
 
-pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    run_path_with_cstr(old, &|old| {
-        run_path_with_cstr(new, &|new| {
-            cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }).map(|_| ())
-        })
-    })
+pub fn rename(old: &CStr, new: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }).map(|_| ())
 }
 
-pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
-    run_path_with_cstr(p, &|p| cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ()))
+pub fn set_perm(p: &CStr, perm: FilePermissions) -> io::Result<()> {
+    cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ())
 }
 
-pub fn rmdir(p: &Path) -> io::Result<()> {
-    run_path_with_cstr(p, &|p| cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ()))
+pub fn rmdir(p: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ())
 }
 
-pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    run_path_with_cstr(p, &|c_path| {
-        let p = c_path.as_ptr();
+pub fn readlink(c_path: &CStr) -> io::Result<PathBuf> {
+    let p = c_path.as_ptr();
 
-        let mut buf = Vec::with_capacity(256);
+    let mut buf = Vec::with_capacity(256);
 
-        loop {
-            let buf_read =
-                cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })?
-                    as usize;
-
-            unsafe {
-                buf.set_len(buf_read);
-            }
+    loop {
+        let buf_read =
+            cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize;
 
-            if buf_read != buf.capacity() {
-                buf.shrink_to_fit();
+        unsafe {
+            buf.set_len(buf_read);
+        }
 
-                return Ok(PathBuf::from(OsString::from_vec(buf)));
-            }
+        if buf_read != buf.capacity() {
+            buf.shrink_to_fit();
 
-            // Trigger the internal buffer resizing logic of `Vec` by requiring
-            // more space than the current capacity. The length is guaranteed to be
-            // the same as the capacity due to the if statement above.
-            buf.reserve(1);
+            return Ok(PathBuf::from(OsString::from_vec(buf)));
         }
-    })
+
+        // Trigger the internal buffer resizing logic of `Vec` by requiring
+        // more space than the current capacity. The length is guaranteed to be
+        // the same as the capacity due to the if statement above.
+        buf.reserve(1);
+    }
 }
 
-pub fn symlink(original: &Path, link: &Path) -> io::Result<()> {
-    run_path_with_cstr(original, &|original| {
-        run_path_with_cstr(link, &|link| {
-            cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) }).map(|_| ())
-        })
-    })
+pub fn symlink(original: &CStr, link: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) }).map(|_| ())
 }
 
-pub fn link(original: &Path, link: &Path) -> io::Result<()> {
-    run_path_with_cstr(original, &|original| {
-        run_path_with_cstr(link, &|link| {
-            cfg_if::cfg_if! {
-                if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] {
-                    // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
-                    // it implementation-defined whether `link` follows symlinks, so rely on the
-                    // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
-                    // Android has `linkat` on newer versions, but we happen to know `link`
-                    // always has the correct behavior, so it's here as well.
-                    cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
-                } else {
-                    // Where we can, use `linkat` instead of `link`; see the comment above
-                    // this one for details on why.
-                    cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
-                }
-            }
-            Ok(())
-        })
-    })
+pub fn link(original: &CStr, link: &CStr) -> io::Result<()> {
+    cfg_if::cfg_if! {
+        if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] {
+            // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
+            // it implementation-defined whether `link` follows symlinks, so rely on the
+            // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
+            // Android has `linkat` on newer versions, but we happen to know `link`
+            // always has the correct behavior, so it's here as well.
+            cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
+        } else {
+            // Where we can, use `linkat` instead of `link`; see the comment above
+            // this one for details on why.
+            cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
+        }
+    }
+    Ok(())
 }
 
-pub fn stat(p: &Path) -> io::Result<FileAttr> {
-    run_path_with_cstr(p, &|p| {
-        cfg_has_statx! {
-            if let Some(ret) = unsafe { try_statx(
-                libc::AT_FDCWD,
-                p.as_ptr(),
-                libc::AT_STATX_SYNC_AS_STAT,
-                libc::STATX_BASIC_STATS | libc::STATX_BTIME,
-            ) } {
-                return ret;
-            }
+pub fn stat(p: &CStr) -> io::Result<FileAttr> {
+    cfg_has_statx! {
+        if let Some(ret) = unsafe { try_statx(
+            libc::AT_FDCWD,
+            p.as_ptr(),
+            libc::AT_STATX_SYNC_AS_STAT,
+            libc::STATX_BASIC_STATS | libc::STATX_BTIME,
+        ) } {
+            return ret;
         }
+    }
 
-        let mut stat: stat64 = unsafe { mem::zeroed() };
-        cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?;
-        Ok(FileAttr::from_stat64(stat))
-    })
+    let mut stat: stat64 = unsafe { mem::zeroed() };
+    cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?;
+    Ok(FileAttr::from_stat64(stat))
 }
 
-pub fn lstat(p: &Path) -> io::Result<FileAttr> {
-    run_path_with_cstr(p, &|p| {
-        cfg_has_statx! {
-            if let Some(ret) = unsafe { try_statx(
-                libc::AT_FDCWD,
-                p.as_ptr(),
-                libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT,
-                libc::STATX_BASIC_STATS | libc::STATX_BTIME,
-            ) } {
-                return ret;
-            }
+pub fn lstat(p: &CStr) -> io::Result<FileAttr> {
+    cfg_has_statx! {
+        if let Some(ret) = unsafe { try_statx(
+            libc::AT_FDCWD,
+            p.as_ptr(),
+            libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT,
+            libc::STATX_BASIC_STATS | libc::STATX_BTIME,
+        ) } {
+            return ret;
         }
+    }
 
-        let mut stat: stat64 = unsafe { mem::zeroed() };
-        cvt(unsafe { lstat64(p.as_ptr(), &mut stat) })?;
-        Ok(FileAttr::from_stat64(stat))
-    })
+    let mut stat: stat64 = unsafe { mem::zeroed() };
+    cvt(unsafe { lstat64(p.as_ptr(), &mut stat) })?;
+    Ok(FileAttr::from_stat64(stat))
 }
 
-pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
-    let r = run_path_with_cstr(p, &|path| unsafe {
-        Ok(libc::realpath(path.as_ptr(), ptr::null_mut()))
-    })?;
+pub fn canonicalize(path: &CStr) -> io::Result<PathBuf> {
+    let r = unsafe { libc::realpath(path.as_ptr(), ptr::null_mut()) };
     if r.is_null() {
         return Err(io::Error::last_os_error());
     }
@@ -2324,19 +2307,19 @@ mod remove_dir_impl {
         Ok(())
     }
 
-    fn remove_dir_all_modern(p: &Path) -> io::Result<()> {
+    fn remove_dir_all_modern(p: &CStr) -> io::Result<()> {
         // We cannot just call remove_dir_all_recursive() here because that would not delete a passed
         // symlink. No need to worry about races, because remove_dir_all_recursive() does not recurse
         // into symlinks.
         let attr = lstat(p)?;
         if attr.file_type().is_symlink() {
-            crate::fs::remove_file(p)
+            super::unlink(p)
         } else {
-            run_path_with_cstr(p, &|p| remove_dir_all_recursive(None, &p))
+            remove_dir_all_recursive(None, &p)
         }
     }
 
     pub fn remove_dir_all(p: &Path) -> io::Result<()> {
-        remove_dir_all_modern(p)
+        run_path_with_cstr(p, &remove_dir_all_modern)
     }
 }
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs
index 06bba019393..15727c99683 100644
--- a/library/std/src/sys/fs/windows.rs
+++ b/library/std/src/sys/fs/windows.rs
@@ -547,7 +547,7 @@ impl File {
             ))?;
             attr.file_size = info.AllocationSize as u64;
             attr.number_of_links = Some(info.NumberOfLinks);
-            if attr.file_type().is_reparse_point() {
+            if attr.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
                 let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed();
                 cvt(c::GetFileInformationByHandleEx(
                     self.handle.as_raw_handle(),
diff --git a/library/std/src/sys/io/io_slice/iovec.rs b/library/std/src/sys/io/io_slice/iovec.rs
index 072191315f7..df56358969a 100644
--- a/library/std/src/sys/io/io_slice/iovec.rs
+++ b/library/std/src/sys/io/io_slice/iovec.rs
@@ -1,6 +1,6 @@
 #[cfg(target_os = "hermit")]
 use hermit_abi::iovec;
-#[cfg(target_family = "unix")]
+#[cfg(any(target_family = "unix", target_os = "trusty"))]
 use libc::iovec;
 
 use crate::ffi::c_void;
diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs
index e00b479109f..4d0365d42fd 100644
--- a/library/std/src/sys/io/mod.rs
+++ b/library/std/src/sys/io/mod.rs
@@ -2,7 +2,7 @@
 
 mod io_slice {
     cfg_if::cfg_if! {
-        if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3"))] {
+        if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty"))] {
             mod iovec;
             pub use iovec::*;
         } else if #[cfg(target_os = "windows")] {
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index f0cfb9b2773..f8f220fafd1 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -12,6 +12,7 @@ pub mod anonymous_pipe;
 pub mod backtrace;
 pub mod cmath;
 pub mod exit_guard;
+pub mod fd;
 pub mod fs;
 pub mod io;
 pub mod net;
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index 67eab96fa40..26211bcb152 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -20,7 +20,6 @@ use crate::os::raw::c_char;
 
 pub mod args;
 pub mod env;
-pub mod fd;
 pub mod futex;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index fe43cfd2caf..52684e18ac2 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -11,7 +11,6 @@ use crate::sync::atomic::{AtomicBool, Ordering};
 pub mod abi;
 pub mod args;
 pub mod env;
-pub mod fd;
 mod libunwind_integration;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs
index bbf29f32523..d42a7e2a7fc 100644
--- a/library/std/src/sys/pal/unix/kernel_copy.rs
+++ b/library/std/src/sys/pal/unix/kernel_copy.rs
@@ -604,16 +604,16 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
         _ => true,
     };
 
-    syscall! {
+    syscall!(
         fn copy_file_range(
             fd_in: libc::c_int,
             off_in: *mut libc::loff_t,
             fd_out: libc::c_int,
             off_out: *mut libc::loff_t,
             len: libc::size_t,
-            flags: libc::c_uint
-        ) -> libc::ssize_t
-    }
+            flags: libc::c_uint,
+        ) -> libc::ssize_t;
+    );
 
     fn probe_copy_file_range_support() -> u8 {
         // In some cases, we cannot determine availability from the first
@@ -727,16 +727,16 @@ fn sendfile_splice(mode: SpliceMode, reader: RawFd, writer: RawFd, len: u64) ->
     // Android builds use feature level 14, but the libc wrapper for splice is
     // gated on feature level 21+, so we have to invoke the syscall directly.
     #[cfg(target_os = "android")]
-    syscall! {
+    syscall!(
         fn splice(
             srcfd: libc::c_int,
             src_offset: *const i64,
             dstfd: libc::c_int,
             dst_offset: *const i64,
             len: libc::size_t,
-            flags: libc::c_int
-        ) -> libc::ssize_t
-    }
+            flags: libc::c_int,
+        ) -> libc::ssize_t;
+    );
 
     #[cfg(target_os = "linux")]
     use libc::splice;
diff --git a/library/std/src/sys/pal/unix/linux/pidfd.rs b/library/std/src/sys/pal/unix/linux/pidfd.rs
index 78744430f3b..2d949ec9e91 100644
--- a/library/std/src/sys/pal/unix/linux/pidfd.rs
+++ b/library/std/src/sys/pal/unix/linux/pidfd.rs
@@ -1,7 +1,7 @@
 use crate::io;
 use crate::os::fd::{AsRawFd, FromRawFd, RawFd};
 use crate::sys::cvt;
-use crate::sys::pal::unix::fd::FileDesc;
+use crate::sys::fd::FileDesc;
 use crate::sys::process::ExitStatus;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 413fda1d8d8..d7106c33974 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -8,7 +8,6 @@ pub mod weak;
 
 pub mod args;
 pub mod env;
-pub mod fd;
 #[cfg(target_os = "fuchsia")]
 pub mod fuchsia;
 pub mod futex;
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 30282fbf655..f47421c6705 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -59,11 +59,14 @@ unsafe extern "C" {
     #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
     #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
     #[cfg_attr(target_os = "aix", link_name = "_Errno")]
+    // SAFETY: this will always return the same pointer on a given thread.
+    #[unsafe(ffi_const)]
     fn errno_location() -> *mut c_int;
 }
 
 /// Returns the platform-specific value of errno
 #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
+#[inline]
 pub fn errno() -> i32 {
     unsafe { (*errno_location()) as i32 }
 }
@@ -72,16 +75,19 @@ pub fn errno() -> i32 {
 // needed for readdir and syscall!
 #[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
 #[allow(dead_code)] // but not all target cfgs actually end up using it
+#[inline]
 pub fn set_errno(e: i32) {
     unsafe { *errno_location() = e as c_int }
 }
 
 #[cfg(target_os = "vxworks")]
+#[inline]
 pub fn errno() -> i32 {
     unsafe { libc::errnoGet() }
 }
 
 #[cfg(target_os = "rtems")]
+#[inline]
 pub fn errno() -> i32 {
     unsafe extern "C" {
         #[thread_local]
@@ -92,6 +98,7 @@ pub fn errno() -> i32 {
 }
 
 #[cfg(target_os = "dragonfly")]
+#[inline]
 pub fn errno() -> i32 {
     unsafe extern "C" {
         #[thread_local]
@@ -103,6 +110,7 @@ pub fn errno() -> i32 {
 
 #[cfg(target_os = "dragonfly")]
 #[allow(dead_code)]
+#[inline]
 pub fn set_errno(e: i32) {
     unsafe extern "C" {
         #[thread_local]
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index 4bd0cedd44c..34b3948e3f6 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -424,18 +424,32 @@ mod imp {
 
         let pages = PAGES.get_or_init(|| {
             use crate::sys::weak::dlsym;
-            dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int);
+            dlsym!(
+                fn sysctlbyname(
+                    name: *const libc::c_char,
+                    oldp: *mut libc::c_void,
+                    oldlenp: *mut libc::size_t,
+                    newp: *const libc::c_void,
+                    newlen: libc::size_t,
+                ) -> libc::c_int;
+            );
             let mut guard: usize = 0;
             let mut size = size_of_val(&guard);
             let oid = c"security.bsd.stack_guard_page";
             match sysctlbyname.get() {
-                Some(fcn) if unsafe {
-                    fcn(oid.as_ptr(),
-                        (&raw mut guard).cast(),
-                        &raw mut size,
-                        ptr::null_mut(),
-                        0) == 0
-                } => guard,
+                Some(fcn)
+                    if unsafe {
+                        fcn(
+                            oid.as_ptr(),
+                            (&raw mut guard).cast(),
+                            &raw mut size,
+                            ptr::null_mut(),
+                            0,
+                        ) == 0
+                    } =>
+                {
+                    guard
+                }
                 _ => 1,
             }
         });
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index bb34c2fabe5..9078dd1c231 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -193,11 +193,12 @@ impl Thread {
     // and its metadata from LLVM IR.
     #[no_sanitize(cfi)]
     pub fn set_name(name: &CStr) {
-        weak! {
+        weak!(
             fn pthread_setname_np(
-                libc::pthread_t, *const libc::c_char
-            ) -> libc::c_int
-        }
+                thread: libc::pthread_t,
+                name: *const libc::c_char,
+            ) -> libc::c_int;
+        );
 
         if let Some(f) = pthread_setname_np.get() {
             #[cfg(target_os = "nto")]
@@ -762,7 +763,9 @@ unsafe fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
     // We use dlsym to avoid an ELF version dependency on GLIBC_PRIVATE. (#23628)
     // We shouldn't really be using such an internal symbol, but there's currently
     // no other way to account for the TLS size.
-    dlsym!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t);
+    dlsym!(
+        fn __pthread_get_minstack(attr: *const libc::pthread_attr_t) -> libc::size_t;
+    );
 
     match __pthread_get_minstack.get() {
         None => libc::PTHREAD_STACK_MIN,
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index c0a3044660b..b8469b1681f 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -123,7 +123,12 @@ impl Timespec {
 
             // __clock_gettime64 was added to 32-bit arches in glibc 2.34,
             // and it handles both vDSO calls and ENOSYS fallbacks itself.
-            weak!(fn __clock_gettime64(libc::clockid_t, *mut __timespec64) -> libc::c_int);
+            weak!(
+                fn __clock_gettime64(
+                    clockid: libc::clockid_t,
+                    tp: *mut __timespec64,
+                ) -> libc::c_int;
+            );
 
             if let Some(clock_gettime64) = __clock_gettime64.get() {
                 let mut t = MaybeUninit::uninit();
diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs
index ce3f66a8374..e4c814fba8c 100644
--- a/library/std/src/sys/pal/unix/weak.rs
+++ b/library/std/src/sys/pal/unix/weak.rs
@@ -20,6 +20,7 @@
 // each instance of `weak!` and `syscall!`. Rather than trying to unify all of
 // that, we'll just allow that some unix targets don't use this module at all.
 #![allow(dead_code, unused_macros)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use crate::ffi::CStr;
 use crate::marker::PhantomData;
@@ -29,7 +30,7 @@ use crate::{mem, ptr};
 // We can use true weak linkage on ELF targets.
 #[cfg(all(unix, not(target_vendor = "apple")))]
 pub(crate) macro weak {
-    (fn $name:ident($($t:ty),*) -> $ret:ty) => (
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
         let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
             unsafe extern "C" {
                 #[linkage = "extern_weak"]
@@ -62,10 +63,16 @@ impl<F: Copy> ExternWeak<F> {
 }
 
 pub(crate) macro dlsym {
-    (fn $name:ident($($t:ty),*) -> $ret:ty) => (
-         dlsym!(fn $name($($t),*) -> $ret, stringify!($name));
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
+         dlsym!(
+            #[link_name = stringify!($name)]
+            fn $name($($param : $t),*) -> $ret;
+        );
     ),
-    (fn $name:ident($($t:ty),*) -> $ret:ty, $sym:expr) => (
+    (
+        #[link_name = $sym:expr]
+        fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;
+    ) => (
         static DLSYM: DlsymWeak<unsafe extern "C" fn($($t),*) -> $ret> =
             DlsymWeak::new(concat!($sym, '\0'));
         let $name = &DLSYM;
@@ -125,11 +132,15 @@ impl<F> DlsymWeak<F> {
     unsafe fn initialize(&self) -> Option<F> {
         assert_eq!(size_of::<F>(), size_of::<*mut libc::c_void>());
 
-        let val = fetch(self.name);
+        let val = unsafe { fetch(self.name) };
         // This synchronizes with the acquire fence in `get`.
         self.func.store(val, Ordering::Release);
 
-        if val.is_null() { None } else { Some(mem::transmute_copy::<*mut libc::c_void, F>(&val)) }
+        if val.is_null() {
+            None
+        } else {
+            Some(unsafe { mem::transmute_copy::<*mut libc::c_void, F>(&val) })
+        }
     }
 }
 
@@ -138,20 +149,20 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void {
         Ok(cstr) => cstr,
         Err(..) => return ptr::null_mut(),
     };
-    libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr())
+    unsafe { libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) }
 }
 
 #[cfg(not(any(target_os = "linux", target_os = "android")))]
 pub(crate) macro syscall {
-    (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
         // FIXME(#115199): Rust currently omits weak function definitions
         // and its metadata from LLVM IR.
         #[no_sanitize(cfi)]
-        unsafe fn $name($($arg_name: $t),*) -> $ret {
-            weak! { fn $name($($t),*) -> $ret }
+        unsafe fn $name($($param: $t),*) -> $ret {
+            weak!(fn $name($($param: $t),*) -> $ret;);
 
             if let Some(fun) = $name.get() {
-                fun($($arg_name),*)
+                unsafe { fun($($param),*) }
             } else {
                 super::os::set_errno(libc::ENOSYS);
                 -1
@@ -162,16 +173,18 @@ pub(crate) macro syscall {
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub(crate) macro syscall {
-    (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
-        unsafe fn $name($($arg_name:$t),*) -> $ret {
-            weak! { fn $name($($t),*) -> $ret }
+    (
+        fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;
+    ) => (
+        unsafe fn $name($($param: $t),*) -> $ret {
+            weak!(fn $name($($param: $t),*) -> $ret;);
 
             // Use a weak symbol from libc when possible, allowing `LD_PRELOAD`
             // interposition, but if it's not found just use a raw syscall.
             if let Some(fun) = $name.get() {
-                fun($($arg_name),*)
+                unsafe { fun($($param),*) }
             } else {
-                libc::syscall(libc::${concat(SYS_, $name)}, $($arg_name),*) as $ret
+                unsafe { libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret }
             }
         }
     )
@@ -179,9 +192,9 @@ pub(crate) macro syscall {
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub(crate) macro raw_syscall {
-    (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
-        unsafe fn $name($($arg_name:$t),*) -> $ret {
-            libc::syscall(libc::${concat(SYS_, $name)}, $($arg_name),*) as $ret
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
+        unsafe fn $name($($param: $t),*) -> $ret {
+            unsafe { libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret }
         }
     )
 }
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index cdd613f76b6..80853e7b5a2 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -15,7 +15,6 @@
 
 pub mod args;
 pub mod env;
-pub mod fd;
 #[allow(unused)]
 #[path = "../wasm/atomics/futex.rs"]
 pub mod futex;
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index c85b03d4a89..cc569bb3daf 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -67,7 +67,7 @@ cfg_if::cfg_if! {
     }
 }
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index 6ac28f1bf4f..504b947d09e 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -10,8 +10,6 @@
 pub mod args;
 #[path = "../wasi/env.rs"]
 pub mod env;
-#[path = "../wasi/fd.rs"]
-pub mod fd;
 #[allow(unused)]
 #[path = "../wasm/atomics/futex.rs"]
 pub mod futex;
@@ -39,7 +37,6 @@ mod helpers;
 // import conflict rules. If we glob export `helpers` and `common` together,
 // then the compiler complains about conflicts.
 
-use helpers::err2io;
-pub use helpers::{abort_internal, decode_error_kind, is_interrupted};
+pub(crate) use helpers::{abort_internal, decode_error_kind, err2io, is_interrupted};
 
 mod cabi_realloc;
diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs
index afdb159fe6f..dd5aff391fd 100644
--- a/library/std/src/sys/pal/wasm/atomics/thread.rs
+++ b/library/std/src/sys/pal/wasm/atomics/thread.rs
@@ -6,7 +6,7 @@ use crate::time::Duration;
 
 pub struct Thread(!);
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs
index c7852464922..7fd62339619 100644
--- a/library/std/src/sys/pal/windows/pipe.rs
+++ b/library/std/src/sys/pal/windows/pipe.rs
@@ -143,7 +143,6 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
         };
         opts.security_attributes(&mut sa);
         let theirs = File::open(Path::new(&name), &opts)?;
-        let theirs = AnonPipe { inner: theirs.into_inner() };
 
         Ok(Pipes {
             ours: AnonPipe { inner: ours },
diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs
index 42542f81b65..191a09c8da9 100644
--- a/library/std/src/sys/process/unix/unix.rs
+++ b/library/std/src/sys/process/unix/unix.rs
@@ -461,18 +461,20 @@ impl Command {
             if #[cfg(target_os = "linux")] {
                 use crate::sys::weak::weak;
 
-                weak! {
+                weak!(
                     fn pidfd_spawnp(
-                        *mut libc::c_int,
-                        *const libc::c_char,
-                        *const libc::posix_spawn_file_actions_t,
-                        *const libc::posix_spawnattr_t,
-                        *const *mut libc::c_char,
-                        *const *mut libc::c_char
-                    ) -> libc::c_int
-                }
+                        pidfd: *mut libc::c_int,
+                        path: *const libc::c_char,
+                        file_actions: *const libc::posix_spawn_file_actions_t,
+                        attrp: *const libc::posix_spawnattr_t,
+                        argv: *const *mut libc::c_char,
+                        envp: *const *mut libc::c_char,
+                    ) -> libc::c_int;
+                );
 
-                weak! { fn pidfd_getpid(libc::c_int) -> libc::c_int }
+                weak!(
+                    fn pidfd_getpid(pidfd: libc::c_int) -> libc::c_int;
+                );
 
                 static PIDFD_SUPPORTED: AtomicU8 = AtomicU8::new(0);
                 const UNKNOWN: u8 = 0;
@@ -593,19 +595,19 @@ impl Command {
             // https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addchdir.html.
             // The _np version is more widely available, though, so try that first.
 
-            weak! {
+            weak!(
                 fn posix_spawn_file_actions_addchdir_np(
-                    *mut libc::posix_spawn_file_actions_t,
-                    *const libc::c_char
-                ) -> libc::c_int
-            }
+                    file_actions: *mut libc::posix_spawn_file_actions_t,
+                    path: *const libc::c_char,
+                ) -> libc::c_int;
+            );
 
-            weak! {
+            weak!(
                 fn posix_spawn_file_actions_addchdir(
-                    *mut libc::posix_spawn_file_actions_t,
-                    *const libc::c_char
-                ) -> libc::c_int
-            }
+                    file_actions: *mut libc::posix_spawn_file_actions_t,
+                    path: *const libc::c_char,
+                ) -> libc::c_int;
+            );
 
             posix_spawn_file_actions_addchdir_np
                 .get()
diff --git a/library/std/src/sys/random/linux.rs b/library/std/src/sys/random/linux.rs
index e3cb79285cd..c0591ec0c15 100644
--- a/library/std/src/sys/random/linux.rs
+++ b/library/std/src/sys/random/linux.rs
@@ -73,13 +73,13 @@ fn getrandom(mut bytes: &mut [u8], insecure: bool) {
     // A weak symbol allows interposition, e.g. for perf measurements that want to
     // disable randomness for consistency. Otherwise, we'll try a raw syscall.
     // (`getrandom` was added in glibc 2.25, musl 1.1.20, android API level 28)
-    syscall! {
+    syscall!(
         fn getrandom(
             buffer: *mut libc::c_void,
             length: libc::size_t,
-            flags: libc::c_uint
-        ) -> libc::ssize_t
-    }
+            flags: libc::c_uint,
+        ) -> libc::ssize_t;
+    );
 
     static GETRANDOM_AVAILABLE: AtomicBool = AtomicBool::new(true);
     static GRND_INSECURE_AVAILABLE: AtomicBool = AtomicBool::new(true);
diff --git a/library/std/src/sys/stdio/trusty.rs b/library/std/src/sys/stdio/trusty.rs
index d393e95394d..e05461aa44a 100644
--- a/library/std/src/sys/stdio/trusty.rs
+++ b/library/std/src/sys/stdio/trusty.rs
@@ -1,21 +1,14 @@
-use crate::io;
+#[expect(dead_code)]
+#[path = "unsupported.rs"]
+mod unsupported_stdio;
 
-pub struct Stdin;
+use crate::cmp;
+use crate::io::{self, IoSlice};
+
+pub type Stdin = unsupported_stdio::Stdin;
 pub struct Stdout;
 pub struct Stderr;
 
-impl Stdin {
-    pub const fn new() -> Stdin {
-        Stdin
-    }
-}
-
-impl io::Read for Stdin {
-    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
-        Ok(0)
-    }
-}
-
 impl Stdout {
     pub const fn new() -> Stdout {
         Stdout
@@ -24,7 +17,16 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        _write(libc::STDOUT_FILENO, buf)
+        write(libc::STDOUT_FILENO, buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        write_vectored(libc::STDOUT_FILENO, bufs)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
     }
 
     fn flush(&mut self) -> io::Result<()> {
@@ -40,7 +42,16 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        _write(libc::STDERR_FILENO, buf)
+        write(libc::STDERR_FILENO, buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        write_vectored(libc::STDERR_FILENO, bufs)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
     }
 
     fn flush(&mut self) -> io::Result<()> {
@@ -48,7 +59,7 @@ impl io::Write for Stderr {
     }
 }
 
-pub const STDIN_BUF_SIZE: usize = 0;
+pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
 
 pub fn is_ebadf(_err: &io::Error) -> bool {
     true
@@ -58,24 +69,24 @@ pub fn panic_output() -> Option<impl io::Write> {
     Some(Stderr)
 }
 
-fn _write(fd: i32, message: &[u8]) -> io::Result<usize> {
-    let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() };
-    loop {
-        // SAFETY: syscall, safe arguments.
-        let ret = unsafe { libc::writev(fd, &iov, 1) };
-        if ret < 0 {
-            return Err(io::Error::last_os_error());
-        }
-        let ret = ret as usize;
-        if ret > iov.iov_len {
-            return Err(io::Error::last_os_error());
-        }
-        if ret == iov.iov_len {
-            return Ok(message.len());
-        }
-        // SAFETY: ret has been checked to be less than the length of
-        // the buffer
-        iov.iov_base = unsafe { iov.iov_base.add(ret) };
-        iov.iov_len -= ret;
+fn write(fd: i32, buf: &[u8]) -> io::Result<usize> {
+    let iov = libc::iovec { iov_base: buf.as_ptr() as *mut _, iov_len: buf.len() };
+    // SAFETY: syscall, safe arguments.
+    let ret = unsafe { libc::writev(fd, &iov, 1) };
+    // This check includes ret < 0, since the length is at most isize::MAX.
+    if ret as usize > iov.iov_len {
+        return Err(io::Error::last_os_error());
+    }
+    Ok(ret as usize)
+}
+
+fn write_vectored(fd: i32, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+    let iov = bufs.as_ptr() as *const libc::iovec;
+    let len = cmp::min(bufs.len(), libc::c_int::MAX as usize) as libc::c_int;
+    // SAFETY: syscall, safe arguments.
+    let ret = unsafe { libc::writev(fd, iov, len) };
+    if ret < 0 {
+        return Err(io::Error::last_os_error());
     }
+    Ok(ret as usize)
 }
diff --git a/library/std/src/sys/stdio/wasi.rs b/library/std/src/sys/stdio/wasi.rs
index 8105b0cfa2f..b70efd026f9 100644
--- a/library/std/src/sys/stdio/wasi.rs
+++ b/library/std/src/sys/stdio/wasi.rs
@@ -4,7 +4,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
 use crate::os::raw;
 use crate::os::wasi::io::{AsRawFd, FromRawFd};
-use crate::sys::pal::fd::WasiFd;
+use crate::sys::fd::WasiFd;
 
 pub struct Stdin;
 pub struct Stdout;
diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs
index 1ff13154b7b..9fafac3aa5b 100644
--- a/library/std/src/sys/thread_local/mod.rs
+++ b/library/std/src/sys/thread_local/mod.rs
@@ -30,9 +30,9 @@ cfg_if::cfg_if! {
         target_os = "zkvm",
         target_os = "trusty",
     ))] {
-        mod statik;
-        pub use statik::{EagerStorage, LazyStorage, thread_local_inner};
-        pub(crate) use statik::{LocalPointer, local_pointer};
+        mod no_threads;
+        pub use no_threads::{EagerStorage, LazyStorage, thread_local_inner};
+        pub(crate) use no_threads::{LocalPointer, local_pointer};
     } else if #[cfg(target_thread_local)] {
         mod native;
         pub use native::{EagerStorage, LazyStorage, thread_local_inner};
@@ -138,6 +138,7 @@ pub(crate) mod key {
                 not(target_family = "wasm"),
                 target_family = "unix",
             ),
+            all(not(target_thread_local), target_vendor = "apple"),
             target_os = "teeos",
             all(target_os = "wasi", target_env = "p1", target_feature = "atomics"),
         ))] {
diff --git a/library/std/src/sys/thread_local/statik.rs b/library/std/src/sys/thread_local/no_threads.rs
index 4da01a84acf..4da01a84acf 100644
--- a/library/std/src/sys/thread_local/statik.rs
+++ b/library/std/src/sys/thread_local/no_threads.rs
diff --git a/library/std/tests/floats/f128.rs b/library/std/tests/floats/f128.rs
index b4a6c672bf0..df28e8129dd 100644
--- a/library/std/tests/floats/f128.rs
+++ b/library/std/tests/floats/f128.rs
@@ -985,6 +985,25 @@ fn test_total_cmp() {
 }
 
 #[test]
+fn test_algebraic() {
+    let a: f128 = 123.0;
+    let b: f128 = 456.0;
+
+    // Check that individual operations match their primitive counterparts.
+    //
+    // This is a check of current implementations and does NOT imply any form of
+    // guarantee about future behavior. The compiler reserves the right to make
+    // these operations inexact matches in the future.
+    let eps = if cfg!(miri) { 1e-6 } else { 0.0 };
+
+    assert_approx_eq!(a.algebraic_add(b), a + b, eps);
+    assert_approx_eq!(a.algebraic_sub(b), a - b, eps);
+    assert_approx_eq!(a.algebraic_mul(b), a * b, eps);
+    assert_approx_eq!(a.algebraic_div(b), a / b, eps);
+    assert_approx_eq!(a.algebraic_rem(b), a % b, eps);
+}
+
+#[test]
 fn test_from() {
     assert_eq!(f128::from(false), 0.0);
     assert_eq!(f128::from(true), 1.0);
diff --git a/library/std/tests/floats/f16.rs b/library/std/tests/floats/f16.rs
index ca0b8efbe83..1a90f00aecc 100644
--- a/library/std/tests/floats/f16.rs
+++ b/library/std/tests/floats/f16.rs
@@ -955,6 +955,27 @@ fn test_total_cmp() {
 }
 
 #[test]
+fn test_algebraic() {
+    let a: f16 = 123.0;
+    let b: f16 = 456.0;
+
+    // Check that individual operations match their primitive counterparts.
+    //
+    // This is a check of current implementations and does NOT imply any form of
+    // guarantee about future behavior. The compiler reserves the right to make
+    // these operations inexact matches in the future.
+    let eps_add = if cfg!(miri) { 1e1 } else { 0.0 };
+    let eps_mul = if cfg!(miri) { 1e3 } else { 0.0 };
+    let eps_div = if cfg!(miri) { 1e0 } else { 0.0 };
+
+    assert_approx_eq!(a.algebraic_add(b), a + b, eps_add);
+    assert_approx_eq!(a.algebraic_sub(b), a - b, eps_add);
+    assert_approx_eq!(a.algebraic_mul(b), a * b, eps_mul);
+    assert_approx_eq!(a.algebraic_div(b), a / b, eps_div);
+    assert_approx_eq!(a.algebraic_rem(b), a % b, eps_div);
+}
+
+#[test]
 fn test_from() {
     assert_eq!(f16::from(false), 0.0);
     assert_eq!(f16::from(true), 1.0);
diff --git a/library/std/tests/floats/f32.rs b/library/std/tests/floats/f32.rs
index bf7641986ad..d99b03cb255 100644
--- a/library/std/tests/floats/f32.rs
+++ b/library/std/tests/floats/f32.rs
@@ -915,3 +915,24 @@ fn test_total_cmp() {
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY));
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
 }
+
+#[test]
+fn test_algebraic() {
+    let a: f32 = 123.0;
+    let b: f32 = 456.0;
+
+    // Check that individual operations match their primitive counterparts.
+    //
+    // This is a check of current implementations and does NOT imply any form of
+    // guarantee about future behavior. The compiler reserves the right to make
+    // these operations inexact matches in the future.
+    let eps_add = if cfg!(miri) { 1e-3 } else { 0.0 };
+    let eps_mul = if cfg!(miri) { 1e-1 } else { 0.0 };
+    let eps_div = if cfg!(miri) { 1e-4 } else { 0.0 };
+
+    assert_approx_eq!(a.algebraic_add(b), a + b, eps_add);
+    assert_approx_eq!(a.algebraic_sub(b), a - b, eps_add);
+    assert_approx_eq!(a.algebraic_mul(b), a * b, eps_mul);
+    assert_approx_eq!(a.algebraic_div(b), a / b, eps_div);
+    assert_approx_eq!(a.algebraic_rem(b), a % b, eps_div);
+}
diff --git a/library/std/tests/floats/f64.rs b/library/std/tests/floats/f64.rs
index cbbfcd15efd..611670751bb 100644
--- a/library/std/tests/floats/f64.rs
+++ b/library/std/tests/floats/f64.rs
@@ -894,3 +894,22 @@ fn test_total_cmp() {
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY));
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
 }
+
+#[test]
+fn test_algebraic() {
+    let a: f64 = 123.0;
+    let b: f64 = 456.0;
+
+    // Check that individual operations match their primitive counterparts.
+    //
+    // This is a check of current implementations and does NOT imply any form of
+    // guarantee about future behavior. The compiler reserves the right to make
+    // these operations inexact matches in the future.
+    let eps = if cfg!(miri) { 1e-6 } else { 0.0 };
+
+    assert_approx_eq!(a.algebraic_add(b), a + b, eps);
+    assert_approx_eq!(a.algebraic_sub(b), a - b, eps);
+    assert_approx_eq!(a.algebraic_mul(b), a * b, eps);
+    assert_approx_eq!(a.algebraic_div(b), a / b, eps);
+    assert_approx_eq!(a.algebraic_rem(b), a % b, eps);
+}
diff --git a/library/std/tests/floats/lib.rs b/library/std/tests/floats/lib.rs
index ad82f1a44e7..de5a3cdbd0f 100644
--- a/library/std/tests/floats/lib.rs
+++ b/library/std/tests/floats/lib.rs
@@ -1,4 +1,4 @@
-#![feature(f16, f128, float_gamma, float_minimum_maximum)]
+#![feature(f16, f128, float_algebraic, float_gamma, float_minimum_maximum)]
 
 use std::fmt;
 use std::ops::{Add, Div, Mul, Rem, Sub};
@@ -10,7 +10,7 @@ macro_rules! assert_approx_eq {
         let (a, b) = (&$a, &$b);
         let diff = (*a - *b).abs();
         assert!(
-            diff < $lim,
+            diff <= $lim,
             "{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
             lim = $lim
         );
diff --git a/library/std/tests/thread_local/lib.rs b/library/std/tests/thread_local/lib.rs
index c5291435425..26af5f1eb0a 100644
--- a/library/std/tests/thread_local/lib.rs
+++ b/library/std/tests/thread_local/lib.rs
@@ -1,3 +1,5 @@
+#![feature(cfg_target_thread_local)]
+
 #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
 mod tests;
 
diff --git a/library/std/tests/thread_local/tests.rs b/library/std/tests/thread_local/tests.rs
index aa020c2559c..e8278361d93 100644
--- a/library/std/tests/thread_local/tests.rs
+++ b/library/std/tests/thread_local/tests.rs
@@ -1,7 +1,7 @@
 use std::cell::{Cell, UnsafeCell};
 use std::sync::atomic::{AtomicU8, Ordering};
 use std::sync::{Arc, Condvar, Mutex};
-use std::thread::{self, Builder, LocalKey};
+use std::thread::{self, LocalKey};
 use std::thread_local;
 
 #[derive(Clone, Default)]
@@ -345,8 +345,27 @@ fn join_orders_after_tls_destructors() {
 }
 
 // Test that thread::current is still available in TLS destructors.
+//
+// The test won't currently work without target_thread_local, aka with slow tls.
+// The runtime tries very hard to drop last the TLS variable that keeps the information about the
+// current thread, by using several tricks like deffering the drop to a later round of TLS destruction.
+// However, this only seems to work with fast tls.
+//
+// With slow TLS, it seems that multiple libc implementations will just set the value to null the first
+// time they encounter it, regardless of it having a destructor or not. This means that trying to
+// retrieve it later in a drop impl of another TLS variable will not work.
+//
+// ** Apple libc: https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread_tsd.c#L293
+// Sets the variable to null if it has a destructor and the value is not null. However, all variables
+// created with pthread_key_create are marked as having a destructor, even if the fn ptr called with
+// it is null.
+// ** glibc: https://github.com/bminor/glibc/blob/e5893e6349541d871e8a25120bca014551d13ff5/nptl/nptl_deallocate_tsd.c#L59
+// ** musl: https://github.com/kraj/musl/blob/1880359b54ff7dd9f5016002bfdae4b136007dde/src/thread/pthread_key_create.c#L87
+#[cfg(target_thread_local)]
 #[test]
 fn thread_current_in_dtor() {
+    use std::thread::Builder;
+
     // Go through one round of TLS destruction first.
     struct Defer;
     impl Drop for Defer {
diff --git a/rustfmt.toml b/rustfmt.toml
index 8feeb60ca12..c884a33729c 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -49,7 +49,6 @@ ignore = [
 
     # These are ignored by a standard cargo fmt run.
     "compiler/rustc_codegen_cranelift/scripts",
-    "compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs", # uses edition 2024
     "compiler/rustc_codegen_gcc/tests",
     # Code automatically generated and included.
     "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs",
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 890e64e2bab..17ee4d610f9 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -88,9 +88,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.1.22"
+version = "1.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
+checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
 dependencies = [
  "shlex",
 ]
@@ -150,9 +150,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
 
 [[package]]
 name = "cmake"
-version = "0.1.48"
+version = "0.1.54"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
+checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
 dependencies = [
  "cc",
 ]
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index d3e2b9e05e9..23aa87a7407 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -32,10 +32,8 @@ test = false
 # Most of the time updating these dependencies requires modifications to the
 # bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565);
 # otherwise, some targets will fail. That's why these dependencies are explicitly pinned.
-#
-# Do not upgrade this crate unless https://github.com/rust-lang/cc-rs/issues/1317 is fixed.
-cc = "=1.1.22"
-cmake = "=0.1.48"
+cc = "=1.2.17"
+cmake = "=0.1.54"
 
 build_helper = { path = "../build_helper" }
 clap = { version = "4.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] }
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 68400ba0ea0..140f601253c 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1162,6 +1162,30 @@ class RustBuild(object):
         config = self.get_toml("build")
         return config or default_build_triple(self.verbose)
 
+    def is_git_repository(self, repo_path):
+        return os.path.isdir(os.path.join(repo_path, ".git"))
+
+    def get_latest_commit(self):
+        repo_path = self.rust_root
+        author_email = self.stage0_data.get("git_merge_commit_email")
+        if not self.is_git_repository(repo_path):
+            return "<commit>"
+        cmd = [
+            "git",
+            "-C",
+            repo_path,
+            "rev-list",
+            "--author",
+            author_email,
+            "-n1",
+            "HEAD",
+        ]
+        try:
+            commit = subprocess.check_output(cmd, universal_newlines=True).strip()
+            return commit or "<commit>"
+        except subprocess.CalledProcessError:
+            return "<commit>"
+
     def check_vendored_status(self):
         """Check that vendoring is configured properly"""
         # keep this consistent with the equivalent check in bootstrap:
@@ -1174,7 +1198,8 @@ class RustBuild(object):
                 eprint("      use vendored sources by default.")
 
         cargo_dir = os.path.join(self.rust_root, ".cargo")
-        url = "https://ci-artifacts.rust-lang.org/rustc-builds/<commit>/rustc-nightly-src.tar.xz"
+        commit = self.get_latest_commit()
+        url = f"https://ci-artifacts.rust-lang.org/rustc-builds/{commit}/rustc-nightly-src.tar.xz"
         if self.use_vendored_sources:
             vendor_dir = os.path.join(self.rust_root, "vendor")
             if not os.path.exists(vendor_dir):
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index d2c0d380fb4..e157ff233bb 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/134740
+Last change is for: https://github.com/rust-lang/rust/pull/138784
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 6cb0b19d763..08a288170fa 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -73,12 +73,12 @@ check-aux:
 		$(BOOTSTRAP) miri --stage 2 library/std \
 		$(BOOTSTRAP_ARGS) \
 		--no-doc -- \
-		--skip fs:: --skip net:: --skip process:: --skip sys::pal::
+		--skip fs:: --skip net:: --skip process:: --skip sys::fd:: --skip sys::pal::
 	$(Q)MIRIFLAGS="-Zmiri-disable-isolation" \
 		$(BOOTSTRAP) miri --stage 2 library/std \
 		$(BOOTSTRAP_ARGS) \
 		--doc -- \
-		--skip fs:: --skip net:: --skip process:: --skip sys::pal::
+		--skip fs:: --skip net:: --skip process:: --skip sys::fd:: --skip sys::pal::
 	# Also test some very target-specific modules on other targets
 	# (making sure to cover an i686 target as well).
 	$(Q)MIRIFLAGS="-Zmiri-disable-isolation" BOOTSTRAP_SKIP_TARGET_SANITY=1 \
@@ -120,10 +120,6 @@ ci-msvc: ci-msvc-py ci-msvc-ps1
 # Set of tests that should represent half of the time of the test suite.
 # Used to split tests across multiple CI runners.
 # Test both x and bootstrap entrypoints.
-ci-mingw-x-1:
-	$(Q)$(CFG_SRC_DIR)/x test --stage 2 $(SKIP_COMPILER) $(TEST_SET2)
-ci-mingw-x-2:
-	$(Q)$(CFG_SRC_DIR)/x test --stage 2 $(SKIP_SRC) $(TEST_SET2)
 ci-mingw-x:
 	$(Q)$(CFG_SRC_DIR)/x test --stage 2 $(TEST_SET1)
 ci-mingw-bootstrap:
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index 443131dc7f3..cbfe00a757c 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -11,8 +11,8 @@ use std::str::FromStr;
 use std::{env, process};
 
 use bootstrap::{
-    Build, CONFIG_CHANGE_HISTORY, Config, Flags, Subcommand, debug, find_recent_config_change_ids,
-    human_readable_changes, t,
+    Build, CONFIG_CHANGE_HISTORY, ChangeId, Config, Flags, Subcommand, debug,
+    find_recent_config_change_ids, human_readable_changes, t,
 };
 #[cfg(feature = "tracing")]
 use tracing::instrument;
@@ -155,50 +155,52 @@ fn check_version(config: &Config) -> Option<String> {
     let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id;
     let warned_id_path = config.out.join("bootstrap").join(".last-warned-change-id");
 
-    if let Some(mut id) = config.change_id {
-        if id == latest_change_id {
-            return None;
+    let mut id = match config.change_id {
+        Some(ChangeId::Id(id)) if id == latest_change_id => return None,
+        Some(ChangeId::Ignore) => return None,
+        Some(ChangeId::Id(id)) => id,
+        None => {
+            msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
+            msg.push_str("NOTE: to silence this warning, ");
+            msg.push_str(&format!(
+                "add `change-id = {latest_change_id}` or change-id = \"ignore\" at the top of `bootstrap.toml`"
+            ));
+            return Some(msg);
         }
+    };
 
-        // Always try to use `change-id` from .last-warned-change-id first. If it doesn't exist,
-        // then use the one from the bootstrap.toml. This way we never show the same warnings
-        // more than once.
-        if let Ok(t) = fs::read_to_string(&warned_id_path) {
-            let last_warned_id = usize::from_str(&t)
-                .unwrap_or_else(|_| panic!("{} is corrupted.", warned_id_path.display()));
-
-            // We only use the last_warned_id if it exists in `CONFIG_CHANGE_HISTORY`.
-            // Otherwise, we may retrieve all the changes if it's not the highest value.
-            // For better understanding, refer to `change_tracker::find_recent_config_change_ids`.
-            if CONFIG_CHANGE_HISTORY.iter().any(|config| config.change_id == last_warned_id) {
-                id = last_warned_id;
-            }
-        };
+    // Always try to use `change-id` from .last-warned-change-id first. If it doesn't exist,
+    // then use the one from the bootstrap.toml. This way we never show the same warnings
+    // more than once.
+    if let Ok(t) = fs::read_to_string(&warned_id_path) {
+        let last_warned_id = usize::from_str(&t)
+            .unwrap_or_else(|_| panic!("{} is corrupted.", warned_id_path.display()));
+
+        // We only use the last_warned_id if it exists in `CONFIG_CHANGE_HISTORY`.
+        // Otherwise, we may retrieve all the changes if it's not the highest value.
+        // For better understanding, refer to `change_tracker::find_recent_config_change_ids`.
+        if CONFIG_CHANGE_HISTORY.iter().any(|config| config.change_id == last_warned_id) {
+            id = last_warned_id;
+        }
+    };
 
-        let changes = find_recent_config_change_ids(id);
+    let changes = find_recent_config_change_ids(id);
 
-        if changes.is_empty() {
-            return None;
-        }
+    if changes.is_empty() {
+        return None;
+    }
 
-        msg.push_str("There have been changes to x.py since you last updated:\n");
-        msg.push_str(&human_readable_changes(&changes));
+    msg.push_str("There have been changes to x.py since you last updated:\n");
+    msg.push_str(&human_readable_changes(changes));
 
-        msg.push_str("NOTE: to silence this warning, ");
-        msg.push_str(&format!(
-            "update `bootstrap.toml` to use `change-id = {latest_change_id}` instead"
-        ));
+    msg.push_str("NOTE: to silence this warning, ");
+    msg.push_str(&format!(
+        "update `bootstrap.toml` to use `change-id = {latest_change_id}` or change-id = \"ignore\" instead"
+    ));
 
-        if io::stdout().is_terminal() {
-            t!(fs::write(warned_id_path, latest_change_id.to_string()));
-        }
-    } else {
-        msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
-        msg.push_str("NOTE: to silence this warning, ");
-        msg.push_str(&format!(
-            "add `change-id = {latest_change_id}` at the top of `bootstrap.toml`"
-        ));
-    };
+    if io::stdout().is_terminal() {
+        t!(fs::write(warned_id_path, latest_change_id.to_string()));
+    }
 
     Some(msg)
 }
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 7aa5cb2b6e5..b1a97bde97b 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -31,7 +31,7 @@ fn rustfmt(
     // Avoid the submodule config paths from coming into play. We only allow a single global config
     // for the workspace for now.
     cmd.arg("--config-path").arg(src.canonicalize().unwrap());
-    cmd.arg("--edition").arg("2021");
+    cmd.arg("--edition").arg("2024");
     cmd.arg("--unstable-features");
     cmd.arg("--skip-children");
     if check {
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 9ae1825fae8..69a8bd59f16 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -346,8 +346,6 @@ impl Step for Llvm {
             .define("LLVM_INCLUDE_DOCS", "OFF")
             .define("LLVM_INCLUDE_BENCHMARKS", "OFF")
             .define("LLVM_INCLUDE_TESTS", enable_tests)
-            // FIXME: remove this when minimal llvm is 19
-            .define("LLVM_ENABLE_TERMINFO", "OFF")
             .define("LLVM_ENABLE_LIBEDIT", "OFF")
             .define("LLVM_ENABLE_BINDINGS", "OFF")
             .define("LLVM_ENABLE_Z3_SOLVER", "OFF")
@@ -385,9 +383,6 @@ impl Step for Llvm {
             || target.contains("apple-watchos")
             || target.contains("apple-visionos")
         {
-            // These two defines prevent CMake from automatically trying to add a MacOSX sysroot, which leads to a compiler error.
-            cfg.define("CMAKE_OSX_SYSROOT", "/");
-            cfg.define("CMAKE_OSX_DEPLOYMENT_TARGET", "");
             // Prevent cmake from adding -bundle to CFLAGS automatically, which leads to a compiler error because "-bitcode_bundle" also gets added.
             cfg.define("LLVM_ENABLE_PLUGINS", "OFF");
             // Zlib fails to link properly, leading to a compiler error.
@@ -613,11 +608,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
     let version = get_llvm_version(builder, llvm_config);
     let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok());
     if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) {
-        if major >= 18 {
+        if major >= 19 {
             return;
         }
     }
-    panic!("\n\nbad LLVM version: {version}, need >=18\n\n")
+    panic!("\n\nbad LLVM version: {version}, need >=19\n\n")
 }
 
 fn configure_cmake(
@@ -645,10 +640,17 @@ fn configure_cmake(
     if !builder.is_builder_target(target) {
         cfg.define("CMAKE_CROSSCOMPILING", "True");
 
+        // NOTE: Ideally, we wouldn't have to do this, and `cmake-rs` would just handle it for us.
+        // But it currently determines this based on the `CARGO_CFG_TARGET_OS` environment variable,
+        // which isn't set when compiling outside `build.rs` (like bootstrap is).
+        //
+        // So for now, we define `CMAKE_SYSTEM_NAME` ourselves, to panicking in `cmake-rs`.
         if target.contains("netbsd") {
             cfg.define("CMAKE_SYSTEM_NAME", "NetBSD");
         } else if target.contains("dragonfly") {
             cfg.define("CMAKE_SYSTEM_NAME", "DragonFly");
+        } else if target.contains("openbsd") {
+            cfg.define("CMAKE_SYSTEM_NAME", "OpenBSD");
         } else if target.contains("freebsd") {
             cfg.define("CMAKE_SYSTEM_NAME", "FreeBSD");
         } else if target.is_windows() {
@@ -659,10 +661,27 @@ fn configure_cmake(
             cfg.define("CMAKE_SYSTEM_NAME", "SunOS");
         } else if target.contains("linux") {
             cfg.define("CMAKE_SYSTEM_NAME", "Linux");
+        } else if target.contains("darwin") {
+            // macOS
+            cfg.define("CMAKE_SYSTEM_NAME", "Darwin");
+        } else if target.contains("ios") {
+            cfg.define("CMAKE_SYSTEM_NAME", "iOS");
+        } else if target.contains("tvos") {
+            cfg.define("CMAKE_SYSTEM_NAME", "tvOS");
+        } else if target.contains("visionos") {
+            cfg.define("CMAKE_SYSTEM_NAME", "visionOS");
+        } else if target.contains("watchos") {
+            cfg.define("CMAKE_SYSTEM_NAME", "watchOS");
+        } else if target.contains("none") {
+            // "none" should be the last branch
+            cfg.define("CMAKE_SYSTEM_NAME", "Generic");
         } else {
             builder.info(&format!(
                 "could not determine CMAKE_SYSTEM_NAME from the target `{target}`, build may fail",
             ));
+            // Fallback, set `CMAKE_SYSTEM_NAME` anyhow to avoid the logic `cmake-rs` tries, and
+            // to avoid CMAKE_SYSTEM_NAME being inferred from the host.
+            cfg.define("CMAKE_SYSTEM_NAME", "Generic");
         }
 
         // When cross-compiling we should also set CMAKE_SYSTEM_VERSION, but in
@@ -672,7 +691,19 @@ fn configure_cmake(
         // CMakeFiles (and then only in tests), and so far no issues have been
         // reported, the system version is currently left unset.
 
-        if target.contains("darwin") {
+        if target.contains("apple") {
+            if !target.contains("darwin") {
+                // FIXME(madsmtm): compiler-rt's CMake setup is kinda weird, it seems like they do
+                // version testing etc. for macOS (i.e. Darwin), even while building for iOS?
+                //
+                // So for now we set it to "Darwin" on all Apple platforms.
+                cfg.define("CMAKE_SYSTEM_NAME", "Darwin");
+
+                // These two defines prevent CMake from automatically trying to add a MacOSX sysroot, which leads to a compiler error.
+                cfg.define("CMAKE_OSX_SYSROOT", "/");
+                cfg.define("CMAKE_OSX_DEPLOYMENT_TARGET", "");
+            }
+
             // Make sure that CMake does not build universal binaries on macOS.
             // Explicitly specify the one single target architecture.
             if target.starts_with("aarch64") {
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 81f6b473c45..8e42e845a8c 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1624,9 +1624,6 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             builder.tool_exe(Tool::RunMakeSupport);
         }
 
-        // Also provide `rust_test_helpers` for the host.
-        builder.ensure(TestHelpers { target: compiler.host });
-
         // ensure that `libproc_macro` is available on the host.
         if suite == "mir-opt" {
             builder.ensure(compile::Std::new(compiler, compiler.host).is_for_mir_opt_tests(true));
@@ -1634,11 +1631,6 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             builder.ensure(compile::Std::new(compiler, compiler.host));
         }
 
-        // As well as the target
-        if suite != "mir-opt" {
-            builder.ensure(TestHelpers { target });
-        }
-
         let mut cmd = builder.tool_cmd(Tool::Compiletest);
 
         if suite == "mir-opt" {
@@ -1804,11 +1796,18 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         }
 
         let mut hostflags = flags.clone();
-        hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
         hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No, compiler.stage));
 
         let mut targetflags = flags;
-        targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
+
+        // Provide `rust_test_helpers` for both host and target.
+        if suite == "ui" || suite == "incremental" {
+            builder.ensure(TestHelpers { target: compiler.host });
+            builder.ensure(TestHelpers { target });
+            hostflags
+                .push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
+            targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
+        }
 
         for flag in hostflags {
             cmd.arg("--host-rustcflags").arg(flag);
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index cf4ef4ee310..1712be7f947 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -193,7 +193,7 @@ pub enum GccCiMode {
 /// `bootstrap.example.toml`.
 #[derive(Default, Clone)]
 pub struct Config {
-    pub change_id: Option<usize>,
+    pub change_id: Option<ChangeId>,
     pub bypass_bootstrap_lock: bool,
     pub ccache: Option<String>,
     /// Call Build::ninja() instead of this.
@@ -700,14 +700,36 @@ pub(crate) struct TomlConfig {
     profile: Option<String>,
 }
 
+/// This enum is used for deserializing change IDs from TOML, allowing both numeric values and the string `"ignore"`.
+#[derive(Clone, Debug, PartialEq)]
+pub enum ChangeId {
+    Ignore,
+    Id(usize),
+}
+
 /// Since we use `#[serde(deny_unknown_fields)]` on `TomlConfig`, we need a wrapper type
 /// for the "change-id" field to parse it even if other fields are invalid. This ensures
 /// that if deserialization fails due to other fields, we can still provide the changelogs
 /// to allow developers to potentially find the reason for the failure in the logs..
 #[derive(Deserialize, Default)]
 pub(crate) struct ChangeIdWrapper {
-    #[serde(alias = "change-id")]
-    pub(crate) inner: Option<usize>,
+    #[serde(alias = "change-id", default, deserialize_with = "deserialize_change_id")]
+    pub(crate) inner: Option<ChangeId>,
+}
+
+fn deserialize_change_id<'de, D: Deserializer<'de>>(
+    deserializer: D,
+) -> Result<Option<ChangeId>, D::Error> {
+    let value = toml::Value::deserialize(deserializer)?;
+    Ok(match value {
+        toml::Value::String(s) if s == "ignore" => Some(ChangeId::Ignore),
+        toml::Value::Integer(i) => Some(ChangeId::Id(i as usize)),
+        _ => {
+            return Err(serde::de::Error::custom(
+                "expected \"ignore\" or an integer for change-id",
+            ));
+        }
+    })
 }
 
 /// Describes how to handle conflicts in merging two [`TomlConfig`]
@@ -1351,14 +1373,15 @@ impl Config {
         toml::from_str(&contents)
             .and_then(|table: toml::Value| TomlConfig::deserialize(table))
             .inspect_err(|_| {
-                if let Ok(Some(changes)) = toml::from_str(&contents)
-                    .and_then(|table: toml::Value| ChangeIdWrapper::deserialize(table))
-                    .map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
+                if let Ok(ChangeIdWrapper { inner: Some(ChangeId::Id(id)) }) =
+                    toml::from_str::<toml::Value>(&contents)
+                        .and_then(|table: toml::Value| ChangeIdWrapper::deserialize(table))
                 {
+                    let changes = crate::find_recent_config_change_ids(id);
                     if !changes.is_empty() {
                         println!(
                             "WARNING: There have been changes to x.py since you last updated:\n{}",
-                            crate::human_readable_changes(&changes)
+                            crate::human_readable_changes(changes)
                         );
                     }
                 }
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index 6d63709f474..d8002ba8467 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -10,6 +10,7 @@ use serde::Deserialize;
 
 use super::flags::Flags;
 use super::{ChangeIdWrapper, Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS};
+use crate::ChangeId;
 use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
 use crate::core::build_steps::llvm;
 use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
@@ -151,7 +152,7 @@ runner = "x86_64-runner"
             )
         },
     );
-    assert_eq!(config.change_id, Some(1), "setting top-level value");
+    assert_eq!(config.change_id, Some(ChangeId::Id(1)), "setting top-level value");
     assert_eq!(
         config.rust_lto,
         crate::core::config::RustcLto::Fat,
@@ -291,7 +292,7 @@ fn parse_change_id_with_unknown_field() {
     "#;
 
     let change_id_wrapper: ChangeIdWrapper = toml::from_str(config).unwrap();
-    assert_eq!(change_id_wrapper.inner, Some(3461));
+    assert_eq!(change_id_wrapper.inner, Some(ChangeId::Id(3461)));
 }
 
 #[test]
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index c47cd8b452f..843d474f92d 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -45,8 +45,8 @@ mod core;
 mod utils;
 
 pub use core::builder::PathSet;
-pub use core::config::Config;
 pub use core::config::flags::{Flags, Subcommand};
+pub use core::config::{ChangeId, Config};
 
 #[cfg(feature = "tracing")]
 use tracing::{instrument, span};
diff --git a/src/bootstrap/src/utils/cc_detect/tests.rs b/src/bootstrap/src/utils/cc_detect/tests.rs
index c97529cbe9e..b4a1b52dd23 100644
--- a/src/bootstrap/src/utils/cc_detect/tests.rs
+++ b/src/bootstrap/src/utils/cc_detect/tests.rs
@@ -264,7 +264,7 @@ fn test_find_target_without_config() {
 fn test_find() {
     let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
     let target1 = TargetSelection::from_user("x86_64-unknown-linux-gnu");
-    let target2 = TargetSelection::from_user("arm-linux-androideabi");
+    let target2 = TargetSelection::from_user("x86_64-unknown-openbsd");
     build.targets.push(target1.clone());
     build.hosts.push(target2.clone());
     find(&build);
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 1a101b02f70..244391739f3 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -35,29 +35,25 @@ impl Display for ChangeSeverity {
     }
 }
 
-pub fn find_recent_config_change_ids(current_id: usize) -> Vec<ChangeInfo> {
-    if !CONFIG_CHANGE_HISTORY.iter().any(|config| config.change_id == current_id) {
+pub fn find_recent_config_change_ids(current_id: usize) -> &'static [ChangeInfo] {
+    if let Some(index) =
+        CONFIG_CHANGE_HISTORY.iter().position(|config| config.change_id == current_id)
+    {
+        // Skip the current_id and IDs before it
+        &CONFIG_CHANGE_HISTORY[index + 1..]
+    } else {
         // If the current change-id is greater than the most recent one, return
         // an empty list (it may be due to switching from a recent branch to an
         // older one); otherwise, return the full list (assuming the user provided
         // the incorrect change-id by accident).
         if let Some(config) = CONFIG_CHANGE_HISTORY.iter().max_by_key(|config| config.change_id) {
             if current_id > config.change_id {
-                return Vec::new();
+                return &[];
             }
         }
 
-        return CONFIG_CHANGE_HISTORY.to_vec();
+        CONFIG_CHANGE_HISTORY
     }
-
-    let index =
-        CONFIG_CHANGE_HISTORY.iter().position(|config| config.change_id == current_id).unwrap();
-
-    CONFIG_CHANGE_HISTORY
-        .iter()
-        .skip(index + 1) // Skip the current_id and IDs before it
-        .cloned()
-        .collect()
 }
 
 pub fn human_readable_changes(changes: &[ChangeInfo]) -> String {
@@ -390,4 +386,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "The default configuration filename has changed from `config.toml` to `bootstrap.toml`. `config.toml` is deprecated but remains supported for backward compatibility.",
     },
+    ChangeInfo {
+        change_id: 138986,
+        severity: ChangeSeverity::Info,
+        summary: "You can now use `change-id = \"ignore\"` to suppress `change-id ` warnings in the console.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index f8e4d4e0471..78dcdcbd187 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -474,13 +474,13 @@ pub fn linker_flags(
                 if stage == 0 && target.is_windows() {
                     args.push("-Clink-arg=-fuse-ld=lld".to_string());
                 } else {
-                    args.push("-Clinker-flavor=gnu-lld-cc".to_string());
+                    args.push("-Zlinker-features=+lld".to_string());
                 }
                 // FIXME(kobzol): remove this flag once MCP510 gets stabilized
                 args.push("-Zunstable-options".to_string());
             }
             LldMode::SelfContained => {
-                args.push("-Clinker-flavor=gnu-lld-cc".to_string());
+                args.push("-Zlinker-features=+lld".to_string());
                 args.push("-Clink-self-contained=+linker".to_string());
                 // FIXME(kobzol): remove this flag once MCP510 gets stabilized
                 args.push("-Zunstable-options".to_string());
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index 20b6f7d10ef..488a6a2bce1 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -14,9 +14,9 @@ To run a specific CI job locally, you can use the `citool` Rust crate:
 cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
 ```
 
-For example, to run the `x86_64-gnu-llvm-18-1` job:
+For example, to run the `x86_64-gnu-llvm-19-1` job:
 ```
-cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-llvm-18-1
+cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-llvm-19-1
 ```
 
 The job will output artifacts in an `obj/<image-name>` dir at the root of a repository. Note
@@ -27,10 +27,10 @@ Docker image executed in the given CI job.
 while locally, to the `obj/<image-name>` directory. This is primarily to prevent
 strange linker errors when using multiple Docker images.
 
-For some Linux workflows (for example `x86_64-gnu-llvm-18-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-18-3` workflow, you can run the following script:
+For some Linux workflows (for example `x86_64-gnu-llvm-19-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-19-3` workflow, you can run the following script:
 
 ```
-DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-18
+DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-19
 ```
 
 ## Local Development
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index b32fa6c8e4e..8bb7116c3ec 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -47,7 +47,7 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 ENV SCRIPT \
            python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
            /scripts/check-default-config-profiles.sh && \
-           python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
+           python3 ../x.py check --target=x86_64-pc-windows-gnu --host=x86_64-pc-windows-gnu && \
            python3 ../x.py clippy ci && \
            python3 ../x.py build --stage 0 src/tools/build-manifest && \
            python3 ../x.py test --stage 0 src/tools/compiletest && \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
deleted file mode 100644
index aefc0f376f6..00000000000
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
+++ /dev/null
@@ -1,69 +0,0 @@
-FROM ubuntu:24.04
-
-ARG DEBIAN_FRONTEND=noninteractive
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-  bzip2 \
-  g++ \
-  gcc-multilib \
-  make \
-  ninja-build \
-  file \
-  curl \
-  ca-certificates \
-  python3 \
-  git \
-  cmake \
-  sudo \
-  gdb \
-  llvm-18-tools \
-  llvm-18-dev \
-  libedit-dev \
-  libssl-dev \
-  pkg-config \
-  zlib1g-dev \
-  xz-utils \
-  nodejs \
-  mingw-w64 \
-  # libgccjit dependencies
-  flex \
-  libmpfr-dev \
-  libgmp-dev \
-  libmpc3 \
-  libmpc-dev \
-  && rm -rf /var/lib/apt/lists/*
-
-# Install powershell (universal package) so we can test x.ps1 on Linux
-# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep.
-RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \
-    dpkg --ignore-depends=libicu72 -i powershell.deb && \
-    rm -f powershell.deb
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-# We are disabling CI LLVM since this builder is intentionally using a host
-# LLVM, rather than the typical src/llvm-project LLVM.
-ENV NO_DOWNLOAD_CI_LLVM 1
-ENV EXTERNAL_LLVM 1
-
-# Using llvm-link-shared due to libffi issues -- see #34486
-ENV RUST_CONFIGURE_ARGS \
-      --build=x86_64-unknown-linux-gnu \
-      --llvm-root=/usr/lib/llvm-18 \
-      --enable-llvm-link-shared \
-      --set rust.randomize-layout=true \
-      --set rust.thin-lto-import-instr-limit=10
-
-COPY scripts/shared.sh /scripts/
-
-ARG SCRIPT_ARG
-
-COPY scripts/add_dummy_commit.sh /tmp/
-COPY scripts/x86_64-gnu-llvm.sh /tmp/
-COPY scripts/x86_64-gnu-llvm2.sh /tmp/
-COPY scripts/x86_64-gnu-llvm3.sh /tmp/
-COPY scripts/stage_2_test_set1.sh /tmp/
-COPY scripts/stage_2_test_set2.sh /tmp/
-
-ENV SCRIPT "/tmp/add_dummy_commit.sh && /tmp/${SCRIPT_ARG}"
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
index e0ed2e227f8..be235f648b5 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
@@ -3,6 +3,7 @@ FROM ubuntu:24.10
 ARG DEBIAN_FRONTEND=noninteractive
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
+  bzip2 \
   g++ \
   gcc-multilib \
   make \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index 8324d1ec586..28c035daa5d 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -62,7 +62,6 @@ case $HOST_TARGET in
     # See <https://github.com/rust-lang/rust/issues/127883>
     # For now, these tests are moved to `x86_64-msvc-ext2` in `src/ci/github-actions/jobs.yml`.
     #python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass
-    #python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-gnu --test-args pass
     ;;
   *)
     echo "FATAL: unexpected host $HOST_TARGET"
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index f62ed23d038..68e680a1b1b 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -105,7 +105,7 @@ pr:
   - name: mingw-check-tidy
     continue_on_error: true
     <<: *job-linux-4c
-  - name: x86_64-gnu-llvm-18
+  - name: x86_64-gnu-llvm-19
     env:
       ENABLE_GCC_CODEGEN: "1"
       # We are adding (temporarily) a dummy commit on the compiler
@@ -329,34 +329,6 @@ auto:
       DOCKER_SCRIPT: x86_64-gnu-llvm3.sh
     <<: *job-linux-4c
 
-  # The x86_64-gnu-llvm-18 job is split into multiple jobs to run tests in parallel.
-  # x86_64-gnu-llvm-18-1 skips tests that run in x86_64-gnu-llvm-18-{2,3}.
-  - name: x86_64-gnu-llvm-18-1
-    env:
-      RUST_BACKTRACE: 1
-      READ_ONLY_SRC: "0"
-      IMAGE: x86_64-gnu-llvm-18
-      DOCKER_SCRIPT: stage_2_test_set1.sh
-    <<: *job-linux-4c
-
-  # Skip tests that run in x86_64-gnu-llvm-18-{1,3}
-  - name: x86_64-gnu-llvm-18-2
-    env:
-      RUST_BACKTRACE: 1
-      READ_ONLY_SRC: "0"
-      IMAGE: x86_64-gnu-llvm-18
-      DOCKER_SCRIPT: x86_64-gnu-llvm2.sh
-    <<: *job-linux-4c
-
-  # Skip tests that run in x86_64-gnu-llvm-18-{1,2}
-  - name: x86_64-gnu-llvm-18-3
-    env:
-      RUST_BACKTRACE: 1
-      READ_ONLY_SRC: "0"
-      IMAGE: x86_64-gnu-llvm-18
-      DOCKER_SCRIPT: x86_64-gnu-llvm3.sh
-    <<: *job-linux-4c
-
   - name: x86_64-gnu-nopt
     <<: *job-linux-4c
 
@@ -501,7 +473,7 @@ auto:
     env:
       SCRIPT: >
         python x.py test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass &&
-        python x.py test --stage 2 src/tools/miri --target i686-pc-windows-gnu --test-args pass &&
+        python x.py test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass &&
         python x.py miri --stage 2 library/core --test-args notest &&
         python x.py miri --stage 2 library/alloc --test-args notest &&
         python x.py miri --stage 2 library/std --test-args notest
@@ -533,31 +505,6 @@ auto:
   # came from the mingw-w64 SourceForge download site. Unfortunately
   # SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
 
-  # i686-mingw is split into three jobs to run tests in parallel.
-  - name: i686-mingw-1
-    env:
-      RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-      SCRIPT: make ci-mingw-x-1
-      # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions
-      NO_DOWNLOAD_CI_LLVM: 1
-    <<: *job-windows-25
-
-  - name: i686-mingw-2
-    env:
-      RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-      SCRIPT: make ci-mingw-x-2
-      # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions
-      NO_DOWNLOAD_CI_LLVM: 1
-    <<: *job-windows-25
-
-  - name: i686-mingw-3
-    env:
-      RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-      SCRIPT: make ci-mingw-bootstrap
-      # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions
-      NO_DOWNLOAD_CI_LLVM: 1
-    <<: *job-windows-25
-
   # x86_64-mingw is split into two jobs to run tests in parallel.
   - name: x86_64-mingw-1
     env:
diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
index 22a4fb1901a..415d0dc397d 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
@@ -18,6 +18,7 @@ jobs:
       MDBOOK_LINKCHECK2_VERSION: 0.9.1
       MDBOOK_MERMAID_VERSION: 0.12.6
       MDBOOK_TOC_VERSION: 0.11.2
+      MDBOOK_OUTPUT__LINKCHECK__FOLLOW_WEB_LINKS: ${{ github.event_name != 'pull_request' }}
       DEPLOY_DIR: book/html
       BASE_SHA: ${{ github.event.pull_request.base.sha }}
       GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml
index 67069d9930f..eb2f6806b96 100644
--- a/src/doc/rustc-dev-guide/book.toml
+++ b/src/doc/rustc-dev-guide/book.toml
@@ -62,5 +62,7 @@ warning-policy = "error"
 "/diagnostics/sessiondiagnostic.html" = "diagnostic-structs.html"
 "/diagnostics/diagnostic-codes.html" = "error-codes.html"
 "/miri.html" = "const-eval/interpret.html"
-"/tests/integration.html" = "ecosystem.html"
+"/tests/fuchsia.html" = "ecosystem-test-jobs/fuchsia.html"
 "/tests/headers.html" = "directives.html"
+"/tests/integration.html" = "ecosystem.html"
+"/tests/rust-for-linux.html" = "ecosystem-test-jobs/rust-for-linux.html"
diff --git a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
index 5ab3e6c8b65..9af69dbbf3f 100644
--- a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
+++ b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
@@ -1,11 +1,8 @@
-use std::{
-    collections::BTreeMap,
-    convert::TryInto as _,
-    env, fmt, fs,
-    path::{Path, PathBuf},
-    process,
-    str::FromStr,
-};
+use std::collections::BTreeMap;
+use std::convert::TryInto as _;
+use std::path::{Path, PathBuf};
+use std::str::FromStr;
+use std::{env, fmt, fs, process};
 
 use chrono::{Datelike as _, Month, TimeZone as _, Utc};
 use glob::glob;
@@ -19,19 +16,13 @@ struct Date {
 
 impl Date {
     fn months_since(self, other: Date) -> Option<u32> {
-        let self_chrono = Utc
-            .with_ymd_and_hms(self.year.try_into().unwrap(), self.month, 1, 0, 0, 0)
-            .unwrap();
-        let other_chrono = Utc
-            .with_ymd_and_hms(other.year.try_into().unwrap(), other.month, 1, 0, 0, 0)
-            .unwrap();
+        let self_chrono =
+            Utc.with_ymd_and_hms(self.year.try_into().unwrap(), self.month, 1, 0, 0, 0).unwrap();
+        let other_chrono =
+            Utc.with_ymd_and_hms(other.year.try_into().unwrap(), other.month, 1, 0, 0, 0).unwrap();
         let duration_since = self_chrono.signed_duration_since(other_chrono);
         let months_since = duration_since.num_days() / 30;
-        if months_since < 0 {
-            None
-        } else {
-            Some(months_since.try_into().unwrap())
-        }
+        if months_since < 0 { None } else { Some(months_since.try_into().unwrap()) }
     }
 }
 
@@ -66,26 +57,18 @@ fn collect_dates_from_file(date_regex: &Regex, text: &str) -> Vec<(usize, Date)>
     date_regex
         .captures_iter(text)
         .filter_map(|cap| {
-            if let (Some(month), Some(year), None, None) | (None, None, Some(month), Some(year)) = (
-                cap.name("m1"),
-                cap.name("y1"),
-                cap.name("m2"),
-                cap.name("y2"),
-            ) {
+            if let (Some(month), Some(year), None, None) | (None, None, Some(month), Some(year)) =
+                (cap.name("m1"), cap.name("y1"), cap.name("m2"), cap.name("y2"))
+            {
                 let year = year.as_str().parse().expect("year");
-                let month = Month::from_str(month.as_str())
-                    .expect("month")
-                    .number_from_month();
+                let month = Month::from_str(month.as_str()).expect("month").number_from_month();
                 Some((cap.get(0).expect("all").range(), Date { year, month }))
             } else {
                 None
             }
         })
         .map(|(byte_range, date)| {
-            line += text[end_of_last_cap..byte_range.end]
-                .chars()
-                .filter(|c| *c == '\n')
-                .count();
+            line += text[end_of_last_cap..byte_range.end].chars().filter(|c| *c == '\n').count();
             end_of_last_cap = byte_range.end;
             (line, date)
         })
@@ -138,10 +121,7 @@ fn main() {
     let root_dir_path = Path::new(&root_dir);
     let glob_pat = format!("{}/**/*.md", root_dir);
     let today_chrono = Utc::now().date_naive();
-    let current_month = Date {
-        year: today_chrono.year_ce().1,
-        month: today_chrono.month(),
-    };
+    let current_month = Date { year: today_chrono.year_ce().1, month: today_chrono.month() };
 
     let dates_by_file = collect_dates(glob(&glob_pat).unwrap().map(Result::unwrap));
     let dates_by_file: BTreeMap<_, _> =
@@ -173,10 +153,7 @@ fn main() {
         println!();
 
         for (path, dates) in dates_by_file {
-            println!(
-                "- {}",
-                path.strip_prefix(&root_dir_path).unwrap_or(&path).display(),
-            );
+            println!("- {}", path.strip_prefix(&root_dir_path).unwrap_or(&path).display(),);
             for (line, date) in dates {
                 println!("  - [ ] line {}: {}", line, date);
             }
@@ -191,14 +168,8 @@ mod tests {
 
     #[test]
     fn test_months_since() {
-        let date1 = Date {
-            year: 2020,
-            month: 3,
-        };
-        let date2 = Date {
-            year: 2021,
-            month: 1,
-        };
+        let date1 = Date { year: 2020, month: 3 };
+        let date2 = Date { year: 2021, month: 1 };
         assert_eq!(date2.months_since(date1), Some(10));
     }
 
@@ -273,83 +244,17 @@ Test8
         assert_eq!(
             collect_dates_from_file(&make_date_regex(), text),
             vec![
-                (
-                    3,
-                    Date {
-                        year: 2021,
-                        month: 1,
-                    }
-                ),
-                (
-                    6,
-                    Date {
-                        year: 2021,
-                        month: 2,
-                    }
-                ),
-                (
-                    9,
-                    Date {
-                        year: 2021,
-                        month: 3,
-                    }
-                ),
-                (
-                    11,
-                    Date {
-                        year: 2021,
-                        month: 4,
-                    }
-                ),
-                (
-                    17,
-                    Date {
-                        year: 2021,
-                        month: 5,
-                    }
-                ),
-                (
-                    20,
-                    Date {
-                        year: 2021,
-                        month: 1,
-                    }
-                ),
-                (
-                    23,
-                    Date {
-                        year: 2021,
-                        month: 2,
-                    }
-                ),
-                (
-                    26,
-                    Date {
-                        year: 2021,
-                        month: 3,
-                    }
-                ),
-                (
-                    28,
-                    Date {
-                        year: 2021,
-                        month: 4,
-                    }
-                ),
-                (
-                    34,
-                    Date {
-                        year: 2021,
-                        month: 5,
-                    }
-                ),
-                (
-                    38,
-                    Date {
-                        year: 2021,
-                        month: 6,
-                    }
-                ),
+                (3, Date { year: 2021, month: 1 }),
+                (6, Date { year: 2021, month: 2 }),
+                (9, Date { year: 2021, month: 3 }),
+                (11, Date { year: 2021, month: 4 }),
+                (17, Date { year: 2021, month: 5 }),
+                (20, Date { year: 2021, month: 1 }),
+                (23, Date { year: 2021, month: 2 }),
+                (26, Date { year: 2021, month: 3 }),
+                (28, Date { year: 2021, month: 4 }),
+                (34, Date { year: 2021, month: 5 }),
+                (38, Date { year: 2021, month: 6 }),
             ],
         );
     }
diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs
index 984bd3e37ae..db6ac185785 100644
--- a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs
+++ b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs
@@ -1,4 +1,4 @@
-// Tested with nightly-2025-02-13
+// Tested with nightly-2025-03-28
 
 #![feature(rustc_private)]
 
@@ -34,9 +34,9 @@ impl rustc_span::source_map::FileLoader for MyFileLoader {
     fn read_file(&self, path: &Path) -> io::Result<String> {
         if path == Path::new("main.rs") {
             Ok(r#"
+static MESSAGE: &str = "Hello, World!";
 fn main() {
-    let message = "Hello, World!";
-    println!("{message}");
+    println!("{MESSAGE}");
 }
 "#
             .to_string())
@@ -71,14 +71,12 @@ impl rustc_driver::Callbacks for MyCallbacks {
 
     fn after_analysis(&mut self, _compiler: &Compiler, tcx: TyCtxt<'_>) -> Compilation {
         // Analyze the program and inspect the types of definitions.
-        for id in tcx.hir().items() {
-            let hir = tcx.hir();
-            let item = hir.item(id);
+        for id in tcx.hir_free_items() {
+            let item = &tcx.hir_item(id);
             match item.kind {
-                rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => {
-                    let name = item.ident;
+                rustc_hir::ItemKind::Static(ident, ..) | rustc_hir::ItemKind::Fn { ident, .. } => {
                     let ty = tcx.type_of(item.hir_id().owner.def_id);
-                    println!("{name:?}:\t{ty:?}")
+                    println!("{ident:?}:\t{ty:?}")
                 }
                 _ => (),
             }
diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs
index 3270c722e07..c0d7f977d35 100644
--- a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs
+++ b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs
@@ -1,4 +1,4 @@
-// Tested with nightly-2025-02-13
+// Tested with nightly-2025-03-28
 
 #![feature(rustc_private)]
 
@@ -20,7 +20,7 @@ use std::path::Path;
 use std::sync::Arc;
 
 use rustc_ast_pretty::pprust::item_to_string;
-use rustc_driver::{run_compiler, Compilation};
+use rustc_driver::{Compilation, run_compiler};
 use rustc_interface::interface::{Compiler, Config};
 use rustc_middle::ty::TyCtxt;
 
@@ -70,11 +70,9 @@ impl rustc_driver::Callbacks for MyCallbacks {
     }
 
     fn after_analysis(&mut self, _compiler: &Compiler, tcx: TyCtxt<'_>) -> Compilation {
-        // Every compilation contains a single crate.
-        let hir_krate = tcx.hir();
         // Iterate over the top-level items in the crate, looking for the main function.
-        for id in hir_krate.items() {
-            let item = hir_krate.item(id);
+        for id in tcx.hir_free_items() {
+            let item = &tcx.hir_item(id);
             // Use pattern-matching to find a specific node inside the main function.
             if let rustc_hir::ItemKind::Fn { body, .. } = item.kind {
                 let expr = &tcx.hir_body(body).value;
diff --git a/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs b/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs
index 70f27c2a82a..360f70c8e86 100644
--- a/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs
+++ b/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs
@@ -1,4 +1,4 @@
-// Tested with nightly-2025-02-13
+// Tested with nightly-2025-03-28
 
 #![feature(rustc_private)]
 
@@ -64,14 +64,13 @@ fn main() {
         println!("{krate:?}");
         // Analyze the program and inspect the types of definitions.
         rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| {
-            for id in tcx.hir().items() {
-                let hir = tcx.hir();
-                let item = hir.item(id);
+            for id in tcx.hir_free_items() {
+                let item = tcx.hir_item(id);
                 match item.kind {
-                    rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => {
-                        let name = item.ident;
+                    rustc_hir::ItemKind::Static(ident, ..)
+                    | rustc_hir::ItemKind::Fn { ident, .. } => {
                         let ty = tcx.type_of(item.hir_id().owner.def_id);
-                        println!("{name:?}:\t{ty:?}")
+                        println!("{ident:?}:\t{ty:?}")
                     }
                     _ => (),
                 }
diff --git a/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs b/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs
index 39b236e1783..2512ba3c3f9 100644
--- a/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs
+++ b/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs
@@ -1,4 +1,4 @@
-// Tested with nightly-2025-02-13
+// Tested with nightly-2025-03-28
 
 #![feature(rustc_private)]
 
@@ -86,8 +86,10 @@ fn main() {
     rustc_interface::run_compiler(config, |compiler| {
         let krate = rustc_interface::passes::parse(&compiler.sess);
         rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| {
-            // Run the analysis phase on the local crate to trigger the type error.
-            let _ = tcx.analysis(());
+            // Iterate all the items defined and perform type checking.
+            tcx.par_hir_body_owners(|item_def_id| {
+                tcx.ensure_ok().typeck(item_def_id);
+            });
         });
         // If the compiler has encountered errors when this closure returns, it will abort (!) the program.
         // We avoid this by resetting the error count before returning
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index 6baf43397e8..d7c20d8ce62 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-493c38ba371929579fe136df26eccd9516347c7a
+ae9173d7dd4a31806c950c90dcc331f1508b4d17
diff --git a/src/doc/rustc-dev-guide/rustfmt.toml b/src/doc/rustc-dev-guide/rustfmt.toml
new file mode 100644
index 00000000000..b285329c78e
--- /dev/null
+++ b/src/doc/rustc-dev-guide/rustfmt.toml
@@ -0,0 +1,7 @@
+# matches that of rust-lang/rust
+style_edition = "2024"
+use_small_heuristics = "Max"
+merge_derives = false
+group_imports = "StdExternalCrate"
+imports_granularity = "Module"
+use_field_init_shorthand = true
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index ce74c741b39..95a3cd7c790 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -28,8 +28,11 @@
         - [Minicore](./tests/minicore.md)
     - [Ecosystem testing](./tests/ecosystem.md)
         - [Crater](./tests/crater.md)
-        - [Fuchsia](./tests/fuchsia.md)
-        - [Rust for Linux](./tests/rust-for-linux.md)
+        - [Fuchsia](./tests/ecosystem-test-jobs/fuchsia.md)
+        - [Rust for Linux](./tests/ecosystem-test-jobs/rust-for-linux.md)
+    - [Codegen backend testing](./tests/codegen-backend-tests/intro.md)
+        - [Cranelift codegen backend](./tests/codegen-backend-tests/cg_clif.md)
+        - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md)
     - [Performance testing](./tests/perf.md)
     - [Suggest tests tool](./tests/suggest-tests.md)
     - [Misc info](./tests/misc.md)
@@ -61,12 +64,13 @@
     - [ARM](notification-groups/arm.md)
     - [Cleanup Crew](notification-groups/cleanup-crew.md)
     - [Emscripten](notification-groups/emscripten.md)
+    - [Fuchsia](notification-groups/fuchsia.md)
     - [LLVM](notification-groups/llvm.md)
     - [RISC-V](notification-groups/risc-v.md)
+    - [Rust for Linux](notification-groups/rust-for-linux.md)
     - [WASI](notification-groups/wasi.md)
     - [WebAssembly](notification-groups/wasm.md)
     - [Windows](notification-groups/windows.md)
-    - [Rust for Linux](notification-groups/rust-for-linux.md)
 - [Licenses](./licenses.md)
 - [Editions](guides/editions.md)
 
@@ -94,7 +98,7 @@
 - [Parallel Compilation](./parallel-rustc.md)
 - [Rustdoc internals](./rustdoc-internals.md)
     - [Search](./rustdoc-internals/search.md)
-
+	- [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md)
 # Source Code Representation
 
 - [Prologue](./part-3-intro.md)
@@ -124,6 +128,7 @@
 - [rustc_driver and rustc_interface](./rustc-driver/intro.md)
     - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md)
     - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md)
+    - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md)
 - [Errors and Lints](diagnostics.md)
     - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md)
     - [Translation](./diagnostics/translation.md)
@@ -144,10 +149,7 @@
     - [ADTs and Generic Arguments](./ty_module/generic_arguments.md)
     - [Parameter types/consts/regions](./ty_module/param_ty_const_regions.md)
 - [`TypeFolder` and `TypeFoldable`](./ty-fold.md)
-- [Parameter Environments](./param_env/param_env_summary.md)
-    - [What is it?](./param_env/param_env_what_is_it.md)
-    - [How are `ParamEnv`'s constructed internally](./param_env/param_env_construction_internals.md)
-    - [Which `ParamEnv` do I use?](./param_env/param_env_acquisition.md)
+- [Typing/Param Envs](./typing_parameter_envs.md)
 - [Type inference](./type-inference.md)
 - [Trait solving](./traits/resolution.md)
     - [Higher-ranked trait bounds](./traits/hrtb.md)
diff --git a/src/doc/rustc-dev-guide/src/appendix/code-index.md b/src/doc/rustc-dev-guide/src/appendix/code-index.md
index b96ede68eab..65fbf752d79 100644
--- a/src/doc/rustc-dev-guide/src/appendix/code-index.md
+++ b/src/doc/rustc-dev-guide/src/appendix/code-index.md
@@ -40,5 +40,5 @@ Item            |  Kind    | Short description           | Chapter            |
 [Emitting Diagnostics]: ../diagnostics.html
 [Macro expansion]: ../macro-expansion.html
 [Name resolution]: ../name-resolution.html
-[Parameter Environment]: ../param_env/param_env_summary.html
+[Parameter Environment]: ../typing_parameter_envs.html
 [Trait Solving: Goals and Clauses]: ../traits/goals-and-clauses.html#domain-goals
diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
index 067e2871118..c3c1c41e3f6 100644
--- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
+++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
@@ -63,7 +63,7 @@ cd rust
 > **NOTE**: A shallow clone limits which `git` commands can be run.
 > If you intend to work on and contribute to the compiler, it is
 > generally recommended to fully clone the repository [as shown above](#get-the-source-code),
-> or to perform a [partial clone](#shallow-clone-the-repository) instead.
+> or to perform a [partial clone](#partial-clone-the-repository) instead.
 >
 > For example, `git bisect` and `git blame` require access to the commit history,
 > so they don't work if the repository was cloned with `--depth 1`.
diff --git a/src/doc/rustc-dev-guide/src/building/prerequisites.md b/src/doc/rustc-dev-guide/src/building/prerequisites.md
index f49f6bb0527..6761cabac1f 100644
--- a/src/doc/rustc-dev-guide/src/building/prerequisites.md
+++ b/src/doc/rustc-dev-guide/src/building/prerequisites.md
@@ -38,4 +38,4 @@ incremental compilation ([see here][config]). This will make compilation take
 longer (especially after a rebase), but will save a ton of space from the
 incremental caches.
 
-[config]: ./how-to-build-and-run.md#create-a-configtoml
+[config]: ./how-to-build-and-run.md#create-a-bootstraptoml
diff --git a/src/doc/rustc-dev-guide/src/const-eval.md b/src/doc/rustc-dev-guide/src/const-eval.md
index 69329a3e085..ca6a35a5e97 100644
--- a/src/doc/rustc-dev-guide/src/const-eval.md
+++ b/src/doc/rustc-dev-guide/src/const-eval.md
@@ -35,7 +35,7 @@ They're the wrappers of the `const_eval` query.
   Statics are special; all other functions do not represent statics correctly
   and have thus assertions preventing their use on statics.
 
-The `const_eval_*` functions use a [`ParamEnv`](./param_env/param_env_summary.html) of environment
+The `const_eval_*` functions use a [`ParamEnv`](./typing_parameter_envs.html) of environment
 in which the constant is evaluated (e.g. the function within which the constant is used)
 and a [`GlobalId`]. The `GlobalId` is made up of an `Instance` referring to a constant
 or static or of an `Instance` of a function and an index into the function's `Promoted` table.
diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md
index 972309b5cd3..6f72ea902f5 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics.md
@@ -954,9 +954,6 @@ application of these fields based on a variety of attributes when using
    `Self="std::iter::Iterator<char>"`. This is needed because `Self` is a
    keyword which cannot appear in attributes.
  - `direct`: user-specified rather than derived obligation.
- - `from_method`: usable both as boolean (whether the flag is present, like
-   `crate_local`) or matching against a particular method. Currently used
-   for `try`.
  - `from_desugaring`: usable both as boolean (whether the flag is present)
    or matching against a particular desugaring. The desugaring is identified
    with its variant name in the `DesugaringKind` enum.
diff --git a/src/doc/rustc-dev-guide/src/name-resolution.md b/src/doc/rustc-dev-guide/src/name-resolution.md
index 2727b8142f2..719ebce8553 100644
--- a/src/doc/rustc-dev-guide/src/name-resolution.md
+++ b/src/doc/rustc-dev-guide/src/name-resolution.md
@@ -120,9 +120,9 @@ even though they should be visible by ordinary scoping rules. An example:
 fn do_something<T: Default>(val: T) { // <- New rib in both types and values (1)
     // `val` is accessible, as is the helper function
     // `T` is accessible
-    let helper = || { // New rib on `helper` (2) and another on the block (3)
+   let helper = || { // New rib on the block (2)
         // `val` is accessible here
-    }; // End of (3)
+    }; // End of (2), new rib on `helper` (3)
     // `val` is accessible, `helper` variable shadows `helper` function
     fn helper() { // <- New rib in both types and values (4)
         // `val` is not accessible here, (4) is not transparent for locals
@@ -130,7 +130,7 @@ fn do_something<T: Default>(val: T) { // <- New rib in both types and values (1)
     } // End of (4)
     let val = T::default(); // New rib (5)
     // `val` is the variable, not the parameter here
-} // End of (5), (2) and (1)
+} // End of (5), (3) and (1)
 ```
 
 Because the rules for different namespaces are a bit different, each namespace
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/fuchsia.md b/src/doc/rustc-dev-guide/src/notification-groups/fuchsia.md
new file mode 100644
index 00000000000..e3c1a7148d3
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/notification-groups/fuchsia.md
@@ -0,0 +1,12 @@
+# Fuchsia notification group
+
+**Github Label:** [O-fuchsia] <br>
+**Ping command:** `@rustbot ping fuchsia`
+
+[O-fuchsia]: https://github.com/rust-lang/rust/labels/O-fuchsia
+
+This list will be used to notify [Fuchsia][fuchsia] maintainers
+when the compiler or the standard library changes in a way that would
+break the Fuchsia integration.
+
+[fuchsia]: ../tests/ecosystem-test-jobs/fuchsia.md
diff --git a/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md b/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md
deleted file mode 100644
index f6cff2d6c63..00000000000
--- a/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md
+++ /dev/null
@@ -1,43 +0,0 @@
-
-# Which `ParamEnv` do I use?
-
-When needing a [`ParamEnv`][pe] in the compiler there are a few options for obtaining one:
-- The correct env is already in scope simply use it (or pass it down the call stack to where you are).
-- The [`tcx.param_env(def_id)` query][param_env_query]
-- Use [`ParamEnv::new`][param_env_new] to construct an env with an arbitrary set of where clauses. Then call [`traits::normalize_param_env_or_error`][normalize_env_or_error] which will handle normalizing and elaborating all the where clauses in the env for you.
-- Creating an empty environment via [`ParamEnv::reveal_all`][env_reveal_all] or [`ParamEnv::empty`][env_empty]
-
-In the large majority of cases a `ParamEnv` when required already exists somewhere in scope or above in the call stack and should be passed down. A non exhaustive list of places where you might find an existing `ParamEnv`:
-- During typeck `FnCtxt` has a [`param_env` field][fnctxt_param_env]
-- When writing late lints the `LateContext` has a [`param_env` field][latectxt_param_env]
-- During well formedness checking the `WfCheckingCtxt` has a [`param_env` field][wfckctxt_param_env]
-- The `TypeChecker` used by Mir Typeck has a [`param_env` field][mirtypeck_param_env]
-- In the next-gen trait solver all `Goal`s have a [`param_env` field][goal_param_env] specifying what environment to prove the goal in
-- When editing an existing [`TypeRelation`][typerelation] if it implements `PredicateEmittingRelation` then a [`param_env` method][typerelation_param_env] will be available.
-
-Using the `param_env` query to obtain an env is generally done at the start of some kind of analysis and then passed everywhere that a `ParamEnv` is required. For example the type checker will create a `ParamEnv` for the item it is type checking and then pass it around everywhere.
-
-Creating an env from an arbitrary set of where clauses is usually unnecessary and should only be done if the environment you need does not correspond to an actual item in the source code (i.e. [`compare_method_predicate_entailment`][method_pred_entailment] as mentioned earlier).
-
-Creating an empty environment via `ParamEnv::empty` is almost always wrong. There are very few places where we actually know that the environment should be empty. One of the only places where we do actually know this is after monomorphization, however the `ParamEnv` there should be constructed via `ParamEnv::reveal_all` instead as at this point we should be able to determine the hidden type of opaque types. Codegen/Post-mono is one of the only places that should be using `ParamEnv::reveal_all`.
-
-An additional piece of complexity here is specifying the `Reveal` (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead.
-
-The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_reveal_all] which converts an existing `ParamEnv` into one with `Reveal::All` specified. Where possible the previously mentioned query should be preferred as it is more efficient.
-
-[param_env_new]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.new
-[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html
-[fnctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env
-[latectxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#structfield.param_env
-[wfckctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/struct.WfCheckingCtxt.html#structfield.param_env
-[goal_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/canonical/ir/solve/struct.Goal.html#structfield.param_env
-[typerelation_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/trait.PredicateEmittingRelation.html#tymethod.param_env
-[typerelation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/relate/trait.TypeRelation.html
-[mirtypeck_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/type_check/struct.TypeChecker.html#structfield.param_env
-[env_reveal_all_normalized]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env_reveal_all_normalized
-[with_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.with_reveal_all_normalized
-[env_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.reveal_all
-[env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty
-[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
-[param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env
-[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html
diff --git a/src/doc/rustc-dev-guide/src/param_env/param_env_construction_internals.md b/src/doc/rustc-dev-guide/src/param_env/param_env_construction_internals.md
deleted file mode 100644
index 69a262a176e..00000000000
--- a/src/doc/rustc-dev-guide/src/param_env/param_env_construction_internals.md
+++ /dev/null
@@ -1,83 +0,0 @@
-
-# How are `ParamEnv`'s constructed internally?
-
-Creating a [`ParamEnv`][pe] is more complicated than simply using the list of where clauses defined on an item as written by the user. We need to both elaborate supertraits into the env and fully normalize all aliases. This logic is handled by [`traits::normalize_param_env_or_error`][normalize_env_or_error] (even though it does not mention anything about elaboration).
-
-## Elaborating supertraits
-
-When we have a function such as `fn foo<T: Copy>()` we would like to be able to prove `T: Clone` inside of the function as the `Copy` trait has a `Clone` supertrait. Constructing a `ParamEnv` looks at all of the trait bounds in the env and explicitly adds new where clauses to the `ParamEnv` for any supertraits found on the traits.
-
-A concrete example would be the following function:
-```rust
-trait Trait: SuperTrait {}
-trait SuperTrait: SuperSuperTrait {}
-
-// `bar`'s unelaborated `ParamEnv` would be:
-// `[T: Sized, T: Copy, T: Trait]`
-fn bar<T: Copy + Trait>(a: T) {
-    requires_impl(a);
-}
-
-fn requires_impl<T: Clone + SuperSuperTrait>(a: T) {}
-```
-
-If we did not elaborate the env then the `requires_impl` call would fail to typecheck as we would not be able to prove `T: Clone` or `T: SuperSuperTrait`. In practice we elaborate the env which means that `bar`'s `ParamEnv` is actually:
-`[T: Sized, T: Copy, T: Clone, T: Trait, T: SuperTrait, T: SuperSuperTrait]`
-This allows us to prove `T: Clone` and `T: SuperSuperTrait` when type checking `bar`.
-
-The `Clone` trait has a `Sized` supertrait however we do not end up with two `T: Sized` bounds in the env (one for the supertrait and one for the implicitly added `T: Sized` bound). This is because the elaboration process (implemented via [`util::elaborate`][elaborate]) deduplicates the where clauses to avoid this.
-
-As a side effect this also means that even if no actual elaboration of supertraits takes place, the existing where clauses in the env are _also_ deduplicated. See the following example:
-```rust
-trait Trait {}
-// The unelaborated `ParamEnv` would be:
-// `[T: Sized, T: Trait, T: Trait]`
-// but after elaboration it would be:
-// `[T: Sized, T: Trait]`
-fn foo<T: Trait + Trait>() {}
-```
-
-The [next-gen trait solver][next-gen-solver] also requires this elaboration to take place.
-
-[elaborate]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/util/fn.elaborate.html
-[next-gen-solver]: ../solve/trait-solving.md
-
-## Normalizing all bounds
-
-In the old trait solver the where clauses stored in `ParamEnv` are required to be fully normalized or else the trait solver will not function correctly.  A concrete example of needing to normalize the `ParamEnv` is the following:
-```rust
-trait Trait<T> {
-    type Assoc;
-}
-
-trait Other {
-    type Bar;
-}
-
-impl<T> Other for T {
-    type Bar = u32;
-}
-
-// `foo`'s unnormalized `ParamEnv` would be:
-// `[T: Sized, U: Sized, U: Trait<T::Bar>]`
-fn foo<T, U>(a: U) 
-where
-    U: Trait<<T as Other>::Bar>,
-{
-    requires_impl(a);
-}
-
-fn requires_impl<U: Trait<u32>>(_: U) {}
-```
-
-As humans we can tell that `<T as Other>::Bar` is equal to `u32` so the trait bound on `U` is equivalent to `U: Trait<u32>`. In practice trying to prove `U: Trait<u32>` in the old solver in this environment would fail as it is unable to determine that `<T as Other>::Bar` is equal to `u32`.
-
-To work around this we normalize `ParamEnv`'s after constructing them so that `foo`'s `ParamEnv` is actually: `[T: Sized, U: Sized, U: Trait<u32>]` which means the trait solver is now able to use the `U: Trait<u32>` in the `ParamEnv` to determine that the trait bound `U: Trait<u32>` holds.
-
-This workaround does not work in all cases as normalizing associated types requires a `ParamEnv` which introduces a bootstrapping problem. We need a normalized `ParamEnv` in order for normalization to give correct results, but we need to normalize to get that `ParamEnv`. Currently we normalize the `ParamEnv` once using the unnormalized param env and it tends to give okay results in practice even though there are some examples where this breaks ([example]).
-
-In the next-gen trait solver the requirement for all where clauses in the `ParamEnv` to be fully normalized is not present and so we do not normalize when constructing `ParamEnv`s.
-
-[example]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e6933265ea3e84eaa47019465739992c
-[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
-[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html
diff --git a/src/doc/rustc-dev-guide/src/param_env/param_env_summary.md b/src/doc/rustc-dev-guide/src/param_env/param_env_summary.md
deleted file mode 100644
index 0ff6d8fc394..00000000000
--- a/src/doc/rustc-dev-guide/src/param_env/param_env_summary.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# The `ParamEnv` type
-
-## Summary
-
-The [`ParamEnv`][pe] is used to store information about the environment that we are interacting with the type system from. For example the set of in-scope where-clauses is stored in `ParamEnv` as it differs between each item whereas the list of user written impls is not stored in the `ParamEnv` as this does not change for each item.
-
-This chapter of the dev guide covers:
-- A high level summary of what a `ParamEnv` is and what it is used for
-- Technical details about what the process of constructing a `ParamEnv` involves
-- Guidance about how to acquire a `ParamEnv` when one is required
-
-## Bundling
-
-A useful API on `ParamEnv` is the [`and`][and] method which allows bundling a value with the `ParamEnv`. The `and` method produces a [`ParamEnvAnd<T>`][pea] making it clearer that using the inner value is intended to be done in that specific environment.
-
-[and]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.and
-[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
-[pea]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnvAnd.html
\ No newline at end of file
diff --git a/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md b/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md
deleted file mode 100644
index 5c2f4d59405..00000000000
--- a/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md
+++ /dev/null
@@ -1,59 +0,0 @@
-
-# What is a `ParamEnv`?
-
-The type system relies on information in the environment in order for it to function correctly. This information is stored in the [`ParamEnv`][pe] type and it is important to use the correct `ParamEnv` when interacting with the type system.
-
-The information represented by `ParamEnv` is a list of in-scope where-clauses, and a `Reveal` (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds.
-
-A `ParamEnv` can also be created with arbitrary data that is not derived from a specific item such as in [`compare_method_predicate_entailment`][method_pred_entailment] which creates a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses.
-
-If we have a function such as:
-```rust
-// `foo` would have a `ParamEnv` of:
-// `[T: Sized, T: Trait, <T as Trait>::Assoc: Clone]`
-fn foo<T: Trait>()
-where
-    <T as Trait>::Assoc: Clone,
-{}
-```
-If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. This would allow things such as normalization (TODO: write a chapter about normalization and link it), evaluating generic constants, and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc.
-
-A more concrete example:
-```rust
-// `foo` would have a `ParamEnv` of:
-// `[T: Sized, T: Clone]`
-fn foo<T: Clone>(a: T) {
-    // when typechecking `foo` we require all the where clauses on `bar`
-    // to hold in order for it to be legal to call. This means we have to
-    // prove `T: Clone`. As we are type checking `foo` we use `foo`'s
-    // environment when trying to check that `T: Clone` holds.
-    //
-    // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized, T: Clone]`
-    // will trivially succeed as bound we want to prove is in our environment.
-    requires_clone(a);
-}
-```
-
-Or alternatively an example that would not compile:
-```rust
-// `foo2` would have a `ParamEnv` of:
-// `[T: Sized]`
-fn foo2<T>(a: T) {
-    // When typechecking `foo2` we attempt to prove `T: Clone`.
-    // As we are type checking `foo2` we use `foo2`'s environment
-    // when trying to prove `T: Clone`.
-    //
-    // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized]` will
-    // fail as there is nothing in the environment telling the trait solver
-    // that `T` implements `Clone` and there exists no user written impl
-    // that could apply.
-    requires_clone(a);
-}
-```
-
-It's very important to use the correct `ParamEnv` when interacting with the type system as otherwise it can lead to ICEs or things compiling when they shouldn't (or vice versa). See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that changed rustc to use the correct param env to avoid ICE. Determining how to acquire the correct `ParamEnv` is explained later in this chapter.
-
-[predicates_of]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/predicates_of/fn.predicates_of.html
-[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html
-[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
-[query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env
diff --git a/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md b/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md
index 1043df6ecb6..518cf4e821a 100644
--- a/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md
+++ b/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md
@@ -7,7 +7,7 @@ otherwise be printed to stderr.
 
 To get diagnostics from the compiler,
 configure [`rustc_interface::Config`] to output diagnostic to a buffer,
-and run [`TyCtxt.analysis`].
+and run [`rustc_hir_typeck::typeck`] for each item.
 
 ```rust
 {{#include ../../examples/rustc-interface-getting-diagnostics.rs}}
@@ -16,3 +16,4 @@ and run [`TyCtxt.analysis`].
 [`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html
 [`rustc_interface::Config`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html
 [`TyCtxt.analysis`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/fn.analysis.html
+[`rustc_hir_typeck::typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn.typeck.html
diff --git a/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md b/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md
new file mode 100644
index 00000000000..b434cfc9cf1
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md
@@ -0,0 +1,54 @@
+# Remarks on perma unstable features
+
+## `rustc_private`
+
+### Overview
+
+The `rustc_private` feature allows external crates to use compiler internals.
+
+### Using `rustc-private` with Official Toolchains
+
+When using the `rustc_private` feature with official Rust toolchains distributed via rustup, you need to install two additional components:
+
+1. **`rustc-dev`**: Provides compiler libraries
+2. **`llvm-tools`**: Provides LLVM libraries required for linking
+
+#### Installation Steps
+
+Install both components using rustup:
+
+```text
+rustup component add rustc-dev llvm-tools
+```
+
+#### Common Error
+
+Without the `llvm-tools` component, you'll encounter linking errors like:
+
+```text
+error: linking with `cc` failed: exit status: 1
+  |
+  = note: rust-lld: error: unable to find library -lLLVM-{version}
+```
+
+### Using `rustc-private` with Custom Toolchains
+
+For custom-built toolchains or environments not using rustup, additional configuration is typically required:
+
+#### Requirements
+
+- LLVM libraries must be available in your system's library search paths
+- The LLVM version must match the one used to build your Rust toolchain
+
+#### Troubleshooting Steps
+
+1. **Check LLVM installation**: Verify LLVM is installed and accessible
+2. **Configure library paths**: You may need to set environment variables:
+   ```text
+   export LD_LIBRARY_PATH=/path/to/llvm/lib:$LD_LIBRARY_PATH
+   ```
+3. **Check version compatibility**: Ensure your LLVM version is compatible with your Rust toolchain
+
+### Additional Resources
+
+- [GitHub Issue #137421](https://github.com/rust-lang/rust/issues/137421): Explains that `rustc_private` linker failures often occur because `llvm-tools` is not installed
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
new file mode 100644
index 00000000000..169b95a7e1a
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
@@ -0,0 +1,112 @@
+# The `rustdoc` test suite
+
+This page is specifically about the test suite named `rustdoc`.
+For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests).
+
+The `rustdoc` test suite is specifically used to test the HTML output of rustdoc.
+
+This is achieved by means of `htmldocck.py`, a custom checker script that leverages [XPath].
+
+[XPath]: https://en.wikipedia.org/wiki/XPath
+
+## Directives
+Directives to htmldocck are similar to those given to `compiletest` in that they take the form of `//@` comments.
+
+In addition to the directives listed here,
+`rustdoc` tests also support most
+[compiletest directives](../tests/directives.html).
+
+All `PATH`s in directives are relative to the the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`),
+so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid
+having to write a long crate name multiple times.
+To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument.
+
+All arguments take the form of quoted strings
+(both single and double quotes are supported),
+with the exception of `COUNT` and the special `-` form of `PATH`.
+
+Directives are assertions that place constraints on the generated HTML.
+
+All directives (except `files`) can be negated by putting a `!` in front of their name.
+
+Similar to shell commands,
+directives can extend across multiple lines if their last char is `\`.
+In this case, the start of the next line should be `//`, with no `@`.
+
+For example, `//@ !has 'foo/struct.Bar.html'` checks that crate `foo` does not have a page for a struct named `Bar` in the crate root.
+
+### `has`
+
+Usage 1: `//@ has PATH`
+Usage 2: `//@ has PATH XPATH PATTERN`
+
+In the first form, `has` checks that a given file exists.
+
+In the second form, `has` is an alias for `matches`,
+except `PATTERN` is a whitespace-normalized[^1] string instead of a regex.
+
+### `matches`
+
+Usage: `//@ matches PATH XPATH PATTERN`
+
+Checks that the text of each element selected by `XPATH` in `PATH` matches the python-flavored regex `PATTERN`.
+
+### `matchesraw`
+
+Usage: `//@ matchesraw PATH PATTERN`
+
+Checks that the contents of the file `PATH` matches the regex `PATTERN`.
+
+### `hasraw`
+
+Usage: `//@ hasraw PATH PATTERN`
+
+Same as `matchesraw`, except `PATTERN` is a whitespace-normalized[^1] string instead of a regex.
+
+### `count`
+
+Usage: `//@ count PATH XPATH COUNT`
+
+Checks that there are exactly `COUNT` matches for `XPATH` within the file `PATH`.
+
+### `snapshot`
+
+Usage: `//@ snapshot NAME PATH XPATH`
+
+Creates a snapshot test named NAME.
+A snapshot test captures a subtree of the DOM, at the location
+determined by the XPath, and compares it to a pre-recorded value
+in a file. The file's name is the test's name with the `.rs` extension
+replaced with `.NAME.html`, where NAME is the snapshot's name.
+
+htmldocck supports the `--bless` option to accept the current subtree
+as expected, saving it to the file determined by the snapshot's name.
+compiletest's `--bless` flag is forwarded to htmldocck.
+
+### `has-dir`
+
+Usage: `//@ has-dir PATH`
+
+Checks for the existance of directory `PATH`.
+
+### `files`
+
+Usage: `//@ files PATH ENTRIES`
+
+Checks that the directory `PATH` contains exactly `ENTRIES`.
+`ENTRIES` is a python list of strings inside a quoted string,
+as if it were to be parsed by `eval`.
+(note that the list is actually parsed by `shlex.split`,
+so it cannot contain arbitrary python expressions).
+
+Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'`
+
+[^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space.  The files themselves are also whitespace-normalized.
+
+## Limitations
+`htmldocck.py` uses the xpath implementation from the standard library.
+This leads to several limitations:
+* All `XPATH` arguments must start with `//` due to a flaw in the implemention.
+* Many XPath features (functions, axies, etc.) are not supported.
+* Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags).
+
diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md
index 356698148e4..320dc9d5825 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc.md
@@ -77,27 +77,27 @@ does is call the `main()` that's in this crate's `lib.rs`, though.)
   `doctest.rs`.
 * The Markdown renderer is loaded up in `html/markdown.rs`, including functions
   for extracting doctests from a given block of Markdown.
-* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where
-  they're handled by the test runner of bootstrap and the supplementary script
-  `src/etc/htmldocck.py`.
 * Frontend CSS and JavaScript are stored in `html/static/`.
 
 ## Tests
 
-* All paths in this section are relative to `tests` in the rust-lang/rust repository.
-* Tests on search engine and index are located in `rustdoc-js` and `rustdoc-js-std`.
+* Tests on search engine and index are located in `tests/rustdoc-js` and `tests/rustdoc-js-std`.
   The format is specified
   [in the search guide](rustdoc-internals/search.md#testing-the-search-engine).
 * Tests on the "UI" of rustdoc (the terminal output it produces when run) are in
-  `rustdoc-ui`
+  `tests/rustdoc-ui`
 * Tests on the "GUI" of rustdoc (the HTML, JS, and CSS as rendered in a browser)
-  are in `rustdoc-gui`. These use a [NodeJS tool called
+  are in `tests/rustdoc-gui`. These use a [NodeJS tool called
   browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses
   puppeteer to run tests in a headless browser and check rendering and
   interactivity.
 * Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc]
   comments and an external d.ts file. The code itself is plain, valid JavaScript; we only
   use tsc as a linter.
+* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`,
+  where they're handled by the test runner of bootstrap and
+  the supplementary script `src/etc/htmldocck.py`.
+  [These tests have several extra directives available to them](./rustdoc-internals/rustdoc-test-suite.md).
 
 [TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
 
diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_clif.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_clif.md
new file mode 100644
index 00000000000..030ddd7dff5
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_clif.md
@@ -0,0 +1,3 @@
+# Cranelift codegen backend tests
+
+TODO: please add some more information to this page.
diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md
new file mode 100644
index 00000000000..4caf4c0e0ee
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md
@@ -0,0 +1,3 @@
+# GCC codegen backend tests
+
+TODO: please add some more information to this page.
diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/intro.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/intro.md
new file mode 100644
index 00000000000..6bf46ddcd21
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/intro.md
@@ -0,0 +1,13 @@
+# Codegen backend testing
+
+See also the [Code generation](../../backend/codegen.md) chapter.
+
+In addition to the primary LLVM codegen backend, the rust-lang/rust CI also runs tests of the [cranelift][cg_clif] and [GCC][cg_gcc] codegen backends in certain test jobs.
+
+For more details on the tests involved, see:
+
+- [Cranelift codegen backend tests](./cg_clif.md)
+- [GCC codegen backend tests](./cg_gcc.md)
+
+[cg_clif]: https://github.com/rust-lang/rustc_codegen_cranelift
+[cg_gcc]: https://github.com/rust-lang/rustc_codegen_gcc
diff --git a/src/doc/rustc-dev-guide/src/tests/fuchsia.md b/src/doc/rustc-dev-guide/src/tests/ecosystem-test-jobs/fuchsia.md
index e96290b9215..b19d94d6ff7 100644
--- a/src/doc/rustc-dev-guide/src/tests/fuchsia.md
+++ b/src/doc/rustc-dev-guide/src/tests/ecosystem-test-jobs/fuchsia.md
@@ -4,6 +4,14 @@
 million lines of Rust code.[^loc] It has caught a large number of [regressions]
 in the past and was subsequently included in CI.
 
+## What to do if the Fuchsia job breaks?
+
+Please contact the [fuchsia][fuchsia-ping] ping group and ask them for help.
+
+```text
+@rustbot ping fuchsia
+```
+
 ## Building Fuchsia in CI
 
 Fuchsia builds as part of the suite of bors tests that run before a pull request
@@ -32,7 +40,7 @@ using your local Rust toolchain.
 src/ci/docker/run.sh x86_64-fuchsia
 ```
 
-See the [Testing with Docker](docker.md) chapter for more details on how to run
+See the [Testing with Docker](../docker.md) chapter for more details on how to run
 and debug jobs with Docker.
 
 Note that a Fuchsia checkout is *large* – as of this writing, a checkout and
@@ -162,6 +170,7 @@ rustc book][platform-support].
 [`public_configs`]: https://gn.googlesource.com/gn/+/main/docs/reference.md#var_public_configs
 [`//build/config:compiler`]: https://cs.opensource.google/fuchsia/fuchsia/+/main:build/config/BUILD.gn;l=121;drc=c26c473bef93b33117ae417893118907a026fec7
 [build system]: https://fuchsia.dev/fuchsia-src/development/build/build_system
+[fuchsia-ping]: ../../notification-groups/fuchsia.md
 
 [^loc]: As of June 2024, Fuchsia had about 2 million lines of first-party Rust
 code and a roughly equal amount of third-party code, as counted by tokei
diff --git a/src/doc/rustc-dev-guide/src/tests/rust-for-linux.md b/src/doc/rustc-dev-guide/src/tests/ecosystem-test-jobs/rust-for-linux.md
index c674d1575b7..d549ec6fca5 100644
--- a/src/doc/rustc-dev-guide/src/tests/rust-for-linux.md
+++ b/src/doc/rustc-dev-guide/src/tests/ecosystem-test-jobs/rust-for-linux.md
@@ -3,26 +3,7 @@
 [Rust for Linux](https://rust-for-linux.com/) (RfL) is an effort for adding
 support for the Rust programming language into the Linux kernel.
 
-## Building Rust for Linux in CI
-
-Rust for Linux builds as part of the suite of bors tests that run before a pull
-request is merged.
-
-The workflow builds a stage1 sysroot of the Rust compiler, downloads the Linux
-kernel, and tries to compile several Rust for Linux drivers and examples using
-this sysroot. RfL uses several unstable compiler/language features, therefore
-this workflow notifies us if a given compiler change would break it.
-
-If you are worried that a pull request might break the Rust for Linux builder
-and want to test it out before submitting it to the bors queue, simply add this
-line to your PR description:
-
-> try-job: x86_64-rust-for-linux
-
-Then when you `@bors try` it will pick the job that builds the Rust for Linux
-integration.
-
-## What to do in case of failure
+## What to do if the Rust for Linux job breaks?
 
 If a PR breaks the Rust for Linux CI job, then:
 
@@ -48,4 +29,23 @@ ping group to ask for help:
 @rustbot ping rfl
 ```
 
-[rfl-ping]: ../notification-groups/rust-for-linux.md
+## Building Rust for Linux in CI
+
+Rust for Linux builds as part of the suite of bors tests that run before a pull
+request is merged.
+
+The workflow builds a stage1 sysroot of the Rust compiler, downloads the Linux
+kernel, and tries to compile several Rust for Linux drivers and examples using
+this sysroot. RfL uses several unstable compiler/language features, therefore
+this workflow notifies us if a given compiler change would break it.
+
+If you are worried that a pull request might break the Rust for Linux builder
+and want to test it out before submitting it to the bors queue, simply add this
+line to your PR description:
+
+> try-job: x86_64-rust-for-linux
+
+Then when you `@bors try` it will pick the job that builds the Rust for Linux
+integration.
+
+[rfl-ping]: ../../notification-groups/rust-for-linux.md
diff --git a/src/doc/rustc-dev-guide/src/tests/ecosystem.md b/src/doc/rustc-dev-guide/src/tests/ecosystem.md
index 08360140425..f4b93492e00 100644
--- a/src/doc/rustc-dev-guide/src/tests/ecosystem.md
+++ b/src/doc/rustc-dev-guide/src/tests/ecosystem.md
@@ -24,5 +24,5 @@ there aren't any significant regressions.
 We have CI jobs that build large open-source Rust projects that are used as
 regression tests in CI. Our integration jobs build the following projects:
 
-- [Fuchsia](fuchsia.md)
-- [Rust for Linux](rust-for-linux.md)
+- [Fuchsia](./ecosystem-test-jobs/fuchsia.md)
+- [Rust for Linux](./ecosystem-test-jobs/rust-for-linux.md)
diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md
index ba44a969bf9..7bf30b106b4 100644
--- a/src/doc/rustc-dev-guide/src/tests/intro.md
+++ b/src/doc/rustc-dev-guide/src/tests/intro.md
@@ -38,7 +38,7 @@ directory, and `x` will essentially run `cargo test` on that package.
 Examples:
 
 | Command                                   | Description                           |
-| ----------------------------------------- | ------------------------------------- |
+|-------------------------------------------|---------------------------------------|
 | `./x test library/std`                    | Runs tests on `std` only              |
 | `./x test library/core`                   | Runs tests on `core` only             |
 | `./x test compiler/rustc_data_structures` | Runs tests on `rustc_data_structures` |
@@ -86,7 +86,7 @@ above.
 Examples:
 
 | Command                 | Description                                                        |
-| ----------------------- | ------------------------------------------------------------------ |
+|-------------------------|--------------------------------------------------------------------|
 | `./x fmt --check`       | Checks formatting and exits with an error if formatting is needed. |
 | `./x fmt`               | Runs rustfmt across the entire codebase.                           |
 | `./x test tidy --bless` | First runs rustfmt to format the codebase, then runs tidy checks.  |
@@ -155,6 +155,10 @@ chapter](ecosystem.md) for more details.
 A separate infrastructure is used for testing and tracking performance of the
 compiler. See the [Performance testing chapter](perf.md) for more details.
 
+### Codegen backend testing
+
+See [Codegen backend testing](./codegen-backend-tests/intro.md).
+
 ## Miscellaneous information
 
 There are some other useful testing-related info at [Misc info](misc.md).
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 98bb9dee76c..407862d48af 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -202,6 +202,9 @@ several ways to match the message with the line (see the examples below):
 * `~|`: Associates the error level and message with the *same* line as the
   *previous comment*. This is more convenient than using multiple carets when
   there are multiple messages associated with the same line.
+* `~v`: Associates the error level and message with the *next* error
+  annotation line. Each symbol (`v`) that you add adds a line to this, so `~vvv`
+  is three lines below the error annotation line.
 * `~?`: Used to match error levels and messages with errors not having line
   information. These can be placed on any line in the test file, but are
   conventionally placed at the end.
@@ -273,6 +276,18 @@ fn main() {
 //~| ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields [E0023]
 ```
 
+#### Positioned above error line
+
+Use the `//~v` idiom with number of v's in the string to indicate the number
+of lines below. This is typically used in lexer or parser tests matching on errors like unclosed
+delimiter or unclosed literal happening at the end of file.
+
+```rust,ignore
+// ignore-tidy-trailing-newlines
+//~v ERROR this file contains an unclosed delimiter
+fn main((ؼ
+```
+
 #### Error without line information
 
 Use `//~?` to match an error without line information.
@@ -320,6 +335,9 @@ But for strict testing, try to use the `ERROR` annotation as much as possible,
 including `//~?` annotations for diagnostics without span.
 For compile time diagnostics `error-pattern` should very rarely be necessary.
 
+Per-line annotations (`//~`) are still checked in tests using `error-pattern`,
+to opt out of these checks in exceptional cases use `//@ compile-flags: --error-format=human`.
+
 ### Error levels
 
 The error levels that you can have are:
@@ -433,6 +451,14 @@ reasons, including:
    can alert the developer so they know that the associated issue has been fixed
    and can possibly be closed.
 
+This directive takes comma-separated issue numbers as arguments, or `"unknown"`:
+
+- `//@ known-bug: #123, #456` (when the issues are on rust-lang/rust)
+- `//@ known-bug: rust-lang/chalk#123456`
+  (allows arbitrary text before the `#`, which is useful when the issue is on another repo)
+- `//@ known-bug: unknown`
+  (when there is no known issue yet; preferrably open one if it does not already exist)
+
 Do not include [error annotations](#error-annotations) in a test with
 `known-bug`. The test should still include other normal directives and
 stdout/stderr files.
diff --git a/src/doc/rustc-dev-guide/src/traits/caching.md b/src/doc/rustc-dev-guide/src/traits/caching.md
index a9f20969b57..c44722a1d9a 100644
--- a/src/doc/rustc-dev-guide/src/traits/caching.md
+++ b/src/doc/rustc-dev-guide/src/traits/caching.md
@@ -61,7 +61,7 @@ to be pretty clearly safe and also still retains a very high hit rate
 **TODO**: it looks like `pick_candidate_cache` no longer exists. In
 general, is this section still accurate at all?
 
-[`ParamEnv`]: ../param_env/param_env_summary.html
+[`ParamEnv`]: ../typing_parameter_envs.html
 [`tcx`]: ../ty.html
 [#18290]: https://github.com/rust-lang/rust/issues/18290
 [#22019]: https://github.com/rust-lang/rust/issues/22019
diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md
index 26eb7245886..c62b0593694 100644
--- a/src/doc/rustc-dev-guide/src/traits/resolution.md
+++ b/src/doc/rustc-dev-guide/src/traits/resolution.md
@@ -183,7 +183,7 @@ in that list. If so, it is considered satisfied. More precisely, we
 want to check whether there is a where-clause obligation that is for
 the same trait (or some subtrait) and which can match against the obligation.
 
-[parameter environment]: ../param_env/param_env_summary.html
+[parameter environment]: ../typing_parameter_envs.html
 
 Consider this simple example:
 
diff --git a/src/doc/rustc-dev-guide/src/ty_module/binders.md b/src/doc/rustc-dev-guide/src/ty_module/binders.md
index defb7cde514..71157eca9b1 100644
--- a/src/doc/rustc-dev-guide/src/ty_module/binders.md
+++ b/src/doc/rustc-dev-guide/src/ty_module/binders.md
@@ -40,7 +40,7 @@ We did not always explicitly track the set of bound vars introduced by each `Bin
 ```
 Binder(
     fn(&'^1_0 &'^1 T/#0),
-    &[BoundVariarbleKind::Region(...)],
+    &[BoundVariableKind::Region(...)],
 )
 ```
 This would cause all kinds of issues as the region `'^1_0` refers to a binder at a higher level than the outermost binder i.e. it is an escaping bound var. The `'^1` region (also writeable as `'^0_1`) is also ill formed as the binder it refers to does not introduce a second parameter. Modern day rustc will ICE when constructing this binder due to both of those regions, in the past we would have simply allowed this to work and then ran into issues in other parts of the codebase. 
diff --git a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
new file mode 100644
index 00000000000..757296d1f65
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md
@@ -0,0 +1,206 @@
+# Typing/Parameter Environments
+
+<!-- toc -->
+
+## Typing Environments
+
+When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The the set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively).
+
+When an environment to perform type system operations in has not yet been created, the [`TypingEnv`][tenv] can be used to bundle all of the external context required into a single type.
+
+Once a context to perform type system operations in has been created (e.g. an [`ObligationCtxt`][ocx] or [`FnCtxt`][fnctxt]) a `TypingEnv` is typically not stored anywhere as only the `TypingMode` is a property of the whole environment, whereas different `ParamEnv`s can be used on a per-goal basis.
+
+[ocx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html
+[fnctxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html
+
+## Parameter Environemnts
+
+### What is a `ParamEnv`
+
+The [`ParamEnv`][penv] is a list of in-scope where-clauses, it typically corresponds to a specific item's where clauses. Some clauses are not explicitly written but are instead are implicitly added in the [`predicates_of`][predicates_of] query, such as `ConstArgHasType` or (some) implied bounds.
+
+In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. A `ParamEnv` can also be created with arbitrary sets of clauses that are not derived from a specific item, such as in [`compare_method_predicate_entailment`][method_pred_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses.
+
+---
+
+If we have a function such as:
+```rust
+// `foo` would have a `ParamEnv` of:
+// `[T: Sized, T: Trait, <T as Trait>::Assoc: Clone]`
+fn foo<T: Trait>()
+where
+    <T as Trait>::Assoc: Clone,
+{}
+```
+If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. This would allow things such as normalization (TODO: write a chapter about normalization and link it), evaluating generic constants, and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc.
+
+A more concrete example:
+```rust
+// `foo` would have a `ParamEnv` of:
+// `[T: Sized, T: Clone]`
+fn foo<T: Clone>(a: T) {
+    // when typechecking `foo` we require all the where clauses on `requires_clone`
+    // to hold in order for it to be legal to call. This means we have to
+    // prove `T: Clone`. As we are type checking `foo` we use `foo`'s
+    // environment when trying to check that `T: Clone` holds.
+    //
+    // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized, T: Clone]`
+    // will trivially succeed as bound we want to prove is in our environment.
+    requires_clone(a);
+}
+```
+
+Or alternatively an example that would not compile:
+```rust
+// `foo2` would have a `ParamEnv` of:
+// `[T: Sized]`
+fn foo2<T>(a: T) {
+    // When typechecking `foo2` we attempt to prove `T: Clone`.
+    // As we are type checking `foo2` we use `foo2`'s environment
+    // when trying to prove `T: Clone`.
+    //
+    // Trying to prove `T: Clone` with a `ParamEnv` of `[T: Sized]` will
+    // fail as there is nothing in the environment telling the trait solver
+    // that `T` implements `Clone` and there exists no user written impl
+    // that could apply.
+    requires_clone(a);
+}
+```
+
+[predicates_of]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/predicates_of/fn.predicates_of.html
+[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html
+[query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env
+
+### Acquiring a `ParamEnv`
+
+Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, illformed programs compiling, or erroing when we shouldn't. See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs.
+
+In the large majority of cases, when a `ParamEnv` is required it either already exists somewhere in scope, or above in the call stack and should be passed down. A non exhaustive list of places where you might find an existing `ParamEnv`:
+- During typeck `FnCtxt` has a [`param_env` field][fnctxt_param_env]
+- When writing late lints the `LateContext` has a [`param_env` field][latectxt_param_env]
+- During well formedness checking the `WfCheckingCtxt` has a [`param_env` field][wfckctxt_param_env]
+- The `TypeChecker` used for MIR Typeck has a [`param_env` field][mirtypeck_param_env]
+- In the next-gen trait solver all `Goal`s have a [`param_env` field][goal_param_env] specifying what environment to prove the goal in
+- When editing an existing [`TypeRelation`][typerelation] if it implements [`PredicateEmittingRelation`][predicate_emitting_relation] then a [`param_env` method][typerelation_param_env] will be available.
+
+If you aren't sure if there's a `ParamEnv` in scope somewhere that can be used it can be worth opening a thread in the [`#t-compiler/help`][compiler_help] zulip stream where someone may be able to point out where a `ParamEnv` can be acquired from.
+
+Manually constructing a `ParamEnv` is typically only needed at the start of some kind of top level analysis (e.g. hir typeck or borrow checking). In such cases there are three ways it can be done:
+- Calling the [`tcx.param_env(def_id)` query][param_env_query] which returns the environment associated with a given definition.
+- Creating an empty environment with [`ParamEnv::empty`][env_empty].
+- Using [`ParamEnv::new`][param_env_new] to construct an env with an arbitrary set of where clauses. Then calling [`traits::normalize_param_env_or_error`][normalize_env_or_error] to handle normalizing and elaborating all the where clauses in the env.
+
+Using the `param_env` query is by far the most common way to construct a `ParamEnv` as most of the time the compiler is performing an analysis as part of some specific definition.
+
+Creating an empty environment with `ParamEnv::empty` is typically only done either in codegen (indirectly via [`TypingEnv::fully_monomorphized`][tenv_mono]), or as part of some analysis that do not expect to ever encounter generic parameters (e.g. various parts of coherence/orphan check).
+
+Creating an env from an arbitrary set of where clauses is usually unnecessary and should only be done if the environment you need does not correspond to an actual item in the source code (e.g. [`compare_method_predicate_entailment`][method_pred_entailment]).
+
+[param_env_new]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.new
+[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html
+[fnctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env
+[latectxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#structfield.param_env
+[wfckctxt_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/struct.WfCheckingCtxt.html#structfield.param_env
+[goal_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/canonical/ir/solve/struct.Goal.html#structfield.param_env
+[typerelation_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/trait.PredicateEmittingRelation.html#tymethod.param_env
+[typerelation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/relate/trait.TypeRelation.html
+[mirtypeck_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/type_check/struct.TypeChecker.html#structfield.param_env
+[env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty
+[param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env
+[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html
+[predicate_emitting_relation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/relate/combine/trait.PredicateEmittingRelation.html
+[tenv_mono]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypingEnv.html#method.fully_monomorphized
+[compiler_help]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp
+
+### How are `ParamEnv`s constructed
+
+Creating a [`ParamEnv`][pe] is more complicated than simply using the list of where clauses defined on an item as written by the user. We need to both elaborate supertraits into the env and fully normalize all aliases. This logic is handled by [`traits::normalize_param_env_or_error`][normalize_env_or_error] (even though it does not mention anything about elaboration).
+
+#### Elaborating supertraits
+
+When we have a function such as `fn foo<T: Copy>()` we would like to be able to prove `T: Clone` inside of the function as the `Copy` trait has a `Clone` supertrait. Constructing a `ParamEnv` looks at all of the trait bounds in the env and explicitly adds new where clauses to the `ParamEnv` for any supertraits found on the traits.
+
+A concrete example would be the following function:
+```rust
+trait Trait: SuperTrait {}
+trait SuperTrait: SuperSuperTrait {}
+
+// `bar`'s unelaborated `ParamEnv` would be:
+// `[T: Sized, T: Copy, T: Trait]`
+fn bar<T: Copy + Trait>(a: T) {
+    requires_impl(a);
+}
+
+fn requires_impl<T: Clone + SuperSuperTrait>(a: T) {}
+```
+
+If we did not elaborate the env then the `requires_impl` call would fail to typecheck as we would not be able to prove `T: Clone` or `T: SuperSuperTrait`. In practice we elaborate the env which means that `bar`'s `ParamEnv` is actually:
+`[T: Sized, T: Copy, T: Clone, T: Trait, T: SuperTrait, T: SuperSuperTrait]`
+This allows us to prove `T: Clone` and `T: SuperSuperTrait` when type checking `bar`.
+
+The `Clone` trait has a `Sized` supertrait however we do not end up with two `T: Sized` bounds in the env (one for the supertrait and one for the implicitly added `T: Sized` bound) as the elaboration process (implemented via [`util::elaborate`][elaborate]) deduplicates where clauses.
+
+A side effect of this is that even if no actual elaboration of supertraits takes place, the existing where clauses in the env are _also_ deduplicated. See the following example:
+```rust
+trait Trait {}
+// The unelaborated `ParamEnv` would be:
+// `[T: Sized, T: Trait, T: Trait]`
+// but after elaboration it would be:
+// `[T: Sized, T: Trait]`
+fn foo<T: Trait + Trait>() {}
+```
+
+The [next-gen trait solver][next-gen-solver] also requires this elaboration to take place.
+
+[elaborate]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/util/fn.elaborate.html
+[next-gen-solver]: ./solve/trait-solving.md
+
+#### Normalizing all bounds
+
+In the old trait solver the where clauses stored in `ParamEnv` are required to be fully normalized as otherwise the trait solver will not function correctly. A concrete example of needing to normalize the `ParamEnv` is the following:
+```rust
+trait Trait<T> {
+    type Assoc;
+}
+
+trait Other {
+    type Bar;
+}
+
+impl<T> Other for T {
+    type Bar = u32;
+}
+
+// `foo`'s unnormalized `ParamEnv` would be:
+// `[T: Sized, U: Sized, U: Trait<T::Bar>]`
+fn foo<T, U>(a: U) 
+where
+    U: Trait<<T as Other>::Bar>,
+{
+    requires_impl(a);
+}
+
+fn requires_impl<U: Trait<u32>>(_: U) {}
+```
+
+As humans we can tell that `<T as Other>::Bar` is equal to `u32` so the trait bound on `U` is equivalent to `U: Trait<u32>`. In practice trying to prove `U: Trait<u32>` in the old solver in this environment would fail as it is unable to determine that `<T as Other>::Bar` is equal to `u32`.
+
+To work around this we normalize `ParamEnv`'s after constructing them so that `foo`'s `ParamEnv` is actually: `[T: Sized, U: Sized, U: Trait<u32>]` which means the trait solver is now able to use the `U: Trait<u32>` in the `ParamEnv` to determine that the trait bound `U: Trait<u32>` holds.
+
+This workaround does not work in all cases as normalizing associated types requires a `ParamEnv` which introduces a bootstrapping problem. We need a normalized `ParamEnv` in order for normalization to give correct results, but we need to normalize to get that `ParamEnv`. Currently we normalize the `ParamEnv` once using the unnormalized param env and it tends to give okay results in practice even though there are some examples where this breaks ([example]).
+
+In the next-gen trait solver the requirement for all where clauses in the `ParamEnv` to be fully normalized is not present and so we do not normalize when constructing `ParamEnv`s.
+
+[example]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e6933265ea3e84eaa47019465739992c
+[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
+[normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html
+
+## Typing Modes
+
+Depending on what context we are performing type system operations in, different behaviour may be required. For example during coherence there are stronger requirements about when we can consider goals to not hold or when we can consider types to be unequal.
+
+Tracking which "phase" of the compiler type system operations are being performed in is done by the [`TypingMode`][tenv] enum. The documentation on the `TypingMode` enum is quite good so instead of repeating it here verbatim we would recommend reading the API documentation directly.
+
+[penv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
+[tenv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/infer_ctxt/enum.TypingMode.html
+[tmode]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.TypingMode.html
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index d08e0bd1edf..9bb64adfa78 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -102,8 +102,7 @@
     - [s390x-unknown-linux-gnu](platform-support/s390x-unknown-linux-gnu.md)
     - [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md)
     - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
-    - [sparcv9-sun-solaris](platform-support/solaris.md)
-    - [\*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
+    - [solaris](platform-support/solaris.md)
     - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
     - [\*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
     - [\*-unknown-hermit](platform-support/hermit.md)
@@ -122,11 +121,12 @@
     - [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)
     - [wasm32v1-none](platform-support/wasm32v1-none.md)
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
+    - [windows-gnu](platform-support/windows-gnu.md)
+    - [windows-gnullvm](platform-support/windows-gnullvm.md)
     - [\*-win7-windows-gnu](platform-support/win7-windows-gnu.md)
     - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
     - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
     - [x86_64-pc-cygwin](platform-support/x86_64-pc-cygwin.md)
-    - [x86_64-pc-solaris](platform-support/solaris.md)
     - [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.md)
     - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
     - [xtensa-\*-none-elf](platform-support/xtensa.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index bc97568f85c..4149b4cb920 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -34,11 +34,10 @@ target | notes
 -------|-------
 [`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+)
 `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+)
-`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI]
 `i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI]
 `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+, Pentium 4) [^x86_32-floats-return-ABI]
 [`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+)
-`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+, Windows Server 2016+)
+[`x86_64-pc-windows-gnu`](platform-support/windows-gnu.md) | 64-bit MinGW (Windows 10+, Windows Server 2016+)
 `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 10+, Windows Server 2016+)
 `x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 3.2+, glibc 2.17+)
 
@@ -96,6 +95,7 @@ target | notes
 [`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | Armv7-A OpenHarmony
 [`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)
 [`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5)
+[`i686-pc-windows-gnu`](platform-support/windows-gnu.md) | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI]
 `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17)
 `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
 [`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10, glibc 2.17)
@@ -143,7 +143,7 @@ target | std | notes
 [`aarch64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on ARM64
 [`aarch64-apple-ios-sim`](platform-support/apple-ios.md) | ✓ | Apple iOS Simulator on ARM64
 [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android
-[`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ARM64 MinGW (Windows 10+), LLVM ABI
+[`aarch64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | ARM64 MinGW (Windows 10+), LLVM ABI
 [`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia
 `aarch64-unknown-none` | * | Bare ARM64, hardfloat
 `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
@@ -166,7 +166,7 @@ target | std | notes
 `i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, original Pentium) [^x86_32-floats-x87]
 `i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87]
 [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI]
-[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI]
+[`i686-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI]
 [`i686-unknown-freebsd`](platform-support/freebsd.md) | ✓ | 32-bit x86 FreeBSD (Pentium 4) [^x86_32-floats-return-ABI]
 `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 (Pentium 4) [^x86_32-floats-return-ABI]
 [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI (Pentium 4, softfloat)
@@ -202,7 +202,7 @@ target | std | notes
 [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
 [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android
 [`x86_64-pc-solaris`](platform-support/solaris.md) | ✓ | 64-bit x86 Solaris 11.4
-[`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI
+[`x86_64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI
 [`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia
 `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
 [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
diff --git a/src/doc/rustc/src/platform-support/netbsd.md b/src/doc/rustc/src/platform-support/netbsd.md
index ef9337befa6..5c2ce0ee900 100644
--- a/src/doc/rustc/src/platform-support/netbsd.md
+++ b/src/doc/rustc/src/platform-support/netbsd.md
@@ -34,7 +34,7 @@ are built for NetBSD 8.x but also work on newer OS versions).
 ## Designated Developers
 
 - [@he32](https://github.com/he32), `he@NetBSD.org`
-- [NetBSD/pkgsrc-wip's rust](https://github.com/NetBSD/pkgsrc-wip/blob/master/rust/Makefile) maintainer (see MAINTAINER variable). This package is part of "pkgsrc work-in-progress" and is used for deployment and testing of new versions of rust
+- [NetBSD/pkgsrc-wip's rust](https://github.com/NetBSD/pkgsrc-wip/blob/master/rust185/Makefile) maintainer (see MAINTAINER variable). This package is part of "pkgsrc work-in-progress" and is used for deployment and testing of new versions of rust
 - [NetBSD's pkgsrc lang/rust](https://github.com/NetBSD/pkgsrc/tree/trunk/lang/rust) for the "proper" package in pkgsrc.
 - [NetBSD's pkgsrc lang/rust-bin](https://github.com/NetBSD/pkgsrc/tree/trunk/lang/rust-bin) which re-uses the bootstrap kit as a binary distribution and therefore avoids the rather protracted native build time of rust itself
 
diff --git a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
index f4ed6201bbd..746b8443547 100644
--- a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
@@ -26,8 +26,7 @@ only option because there is no FPU support in [Armv6-M].
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Cortex-M
-  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
index 11c9486cb76..12e28265678 100644
--- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
@@ -21,8 +21,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Cortex-M
-  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
index b258033bb0f..03324b341d0 100644
--- a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
@@ -22,8 +22,7 @@ only option because there is no FPU support in [Armv7-M].
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Cortex-M
-  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
index 0ae4e3e94bd..4a92e856466 100644
--- a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
@@ -22,8 +22,7 @@ only option because there is no FPU support in [Armv8-M] Baseline.
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Cortex-M
-  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
index 82fdc5b21cf..9f85d08fa0a 100644
--- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
@@ -25,8 +25,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Cortex-M
-  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/windows-gnu.md b/src/doc/rustc/src/platform-support/windows-gnu.md
new file mode 100644
index 00000000000..a867ebcfe25
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/windows-gnu.md
@@ -0,0 +1,32 @@
+# \*-windows-gnu
+
+**⚠️ This documentation page is a stub, you can help improving it by sending a PR. ⚠️**
+
+**Tier: 1/2 (with host tools)**
+
+Target triples available:
+- `i686-pc-windows-gnu`: Tier 2
+- `x86_64-pc-windows-gnu`: Tier 1
+
+## Target maintainers
+
+**⚠️ These targets do not have any maintainers and are not properly maintained. ⚠️**
+
+If you are using this target, consider signing up to become a target maintainer.
+See the target tier policy for details.
+Without maintainers, these targets may be demoted in the future.
+
+## Requirements
+
+These targets support std and host tools.
+
+Unlike their MSVC counterparts, windows-gnu targets support cross-compilation and are free of all MSVC licensing implications.
+
+They follow Windows calling convention for `extern "C"`.
+
+Like with any other Windows target, created binaries are in PE format.
+
+## Building Rust programs
+
+Rust does ship a pre-compiled std library for those targets.
+That means one can easily compile and cross-compile for those targets from other hosts if C proper toolchain is installed.
diff --git a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md b/src/doc/rustc/src/platform-support/windows-gnullvm.md
index f14fe7df422..1ff559fe960 100644
--- a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md
+++ b/src/doc/rustc/src/platform-support/windows-gnullvm.md
@@ -1,8 +1,8 @@
-# \*-pc-windows-gnullvm
+# \*-windows-gnullvm
 
 **Tier: 2 (without host tools)**
 
-Windows targets similar to `*-pc-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils.
+Windows targets similar to `*-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils.
 
 Target triples available so far:
 - `aarch64-pc-windows-gnullvm`
@@ -17,9 +17,9 @@ Target triples available so far:
 ## Requirements
 
 The easiest way to obtain these targets is cross-compilation, but native build from `x86_64-pc-windows-gnu` is possible with few hacks which I don't recommend.
-Std support is expected to be on par with `*-pc-windows-gnu`.
+Std support is expected to be on par with `*-windows-gnu`.
 
-Binaries for this target should be at least on par with `*-pc-windows-gnu` in terms of requirements and functionality.
+Binaries for this target should be at least on par with `*-windows-gnu` in terms of requirements and functionality.
 
 Those targets follow Windows calling convention for `extern "C"`.
 
diff --git a/src/doc/unstable-book/src/compiler-flags/embed-metadata.md b/src/doc/unstable-book/src/compiler-flags/embed-metadata.md
new file mode 100644
index 00000000000..a2a790ee76a
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/embed-metadata.md
@@ -0,0 +1,3 @@
+## `embed-metadata`
+
+This option instructs `rustc` to include the full metadata in `rlib` and `dylib` crate types. The default value is `yes` (enabled). If disabled (`no`), only stub metadata will be stored in these files, to reduce their size on disk. When using `-Zembed-metadata=no`, you will probably want to use `--emit=metadata` to produce the full metadata into a separate `.rmeta` file.
diff --git a/src/doc/unstable-book/src/compiler-flags/print-crate-root-lint-levels.md b/src/doc/unstable-book/src/compiler-flags/print-crate-root-lint-levels.md
new file mode 100644
index 00000000000..0bad8b8ab96
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/print-crate-root-lint-levels.md
@@ -0,0 +1,23 @@
+# `print=crate-root-lint-levels`
+
+The tracking issue for this feature is: [#139180](https://github.com/rust-lang/rust/issues/139180).
+
+------------------------
+
+This option of the `--print` flag print the list of lints with print out all the lints and their associated levels (`allow`, `warn`, `deny`, `forbid`) based on the regular Rust rules at crate root, that is *(roughly)*:
+ - command line args (`-W`, `-A`, `--force-warn`, `--cap-lints`, ...)
+ - crate root attributes (`#![allow]`, `#![warn]`, `#[expect]`, ...)
+ - *the special `warnings` lint group*
+ - the default lint level
+
+The output format is `LINT_NAME=LINT_LEVEL`, e.g.:
+```text
+unknown_lint=warn
+arithmetic_overflow=deny
+```
+
+To be used like this:
+
+```bash
+rustc --print=crate-root-lint-levels -Zunstable-options lib.rs
+```
diff --git a/src/doc/unstable-book/src/language-features/import-trait-associated-functions.md b/src/doc/unstable-book/src/language-features/import-trait-associated-functions.md
new file mode 100644
index 00000000000..0ae5915361e
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/import-trait-associated-functions.md
@@ -0,0 +1,22 @@
+# import_trait_associated_functions
+
+The tracking issue for this feature is: [#134691]
+
+[#134691]: https://github.com/rust-lang/rust/issues/134691
+
+------------------------
+
+This feature allows importing associated functions and constants from traits and then using them like regular items.
+
+```rust
+#![feature(import_trait_associated_functions)]
+
+use std::ops::Add::add;
+
+fn main() {
+    let numbers = vec![1, 2, 3, 4, 5, 6];
+    let sum = numbers.into_iter().reduce(add); // instead of `.reduce(Add:add)`
+
+    assert_eq!(sum, Some(21));
+}
+```
diff --git a/src/doc/unstable-book/src/language-features/inline-const-pat.md b/src/doc/unstable-book/src/language-features/inline-const-pat.md
deleted file mode 100644
index c6f54d79cfc..00000000000
--- a/src/doc/unstable-book/src/language-features/inline-const-pat.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# `inline_const_pat`
-
-The tracking issue for this feature is: [#76001]
-
-------
-
-This feature allows you to use inline constant expressions in pattern position:
-
-```rust
-#![feature(inline_const_pat)]
-
-const fn one() -> i32 { 1 }
-
-let some_int = 3;
-match some_int {
-    const { 1 + 2 } => println!("Matched 1 + 2"),
-    const { one() } => println!("Matched const fn returning 1"),
-    _ => println!("Didn't match anything :("),
-}
-```
-
-[#76001]: https://github.com/rust-lang/rust/issues/76001
diff --git a/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md b/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md
new file mode 100644
index 00000000000..a6fb25a55be
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md
@@ -0,0 +1,159 @@
+# `type_alias_impl_trait`
+
+The tracking issue for this feature is: [#63063]
+
+------------------------
+
+> This feature is not to be confused with [`trait_alias`] or [`impl_trait_in_assoc_type`].
+
+### What is `impl Trait`?
+
+`impl Trait` in return position is useful for declaring types that are constrained by traits, but whose concrete type should be hidden:
+
+```rust
+use std::fmt::Debug;
+
+fn new() -> impl Debug {
+    42
+}
+
+fn main() {
+    let thing = new();
+    // What actually is a `thing`?
+    // No idea but we know it implements `Debug`, so we can debug print it
+    println!("{thing:?}");
+}
+```
+
+See the [reference] for more information about `impl Trait` in return position.
+
+### `type_alias_impl_trait`
+
+However, we might want to use an `impl Trait` in multiple locations but actually use the same concrete type everywhere while keeping it hidden.
+This can be useful in libraries where you want to hide implementation details.
+
+The `#[define_opaque]` attribute must be used to explicitly list opaque items constrained by the item it's on.
+
+```rust
+#![feature(type_alias_impl_trait)]
+# #![allow(unused_variables, dead_code)]
+trait Trait {}
+
+struct MyType;
+
+impl Trait for MyType {}
+
+type Alias = impl Trait;
+
+#[define_opaque(Alias)] // To constrain the type alias to `MyType`
+fn new() -> Alias {
+    MyType
+}
+
+#[define_opaque(Alias)] // So we can name the concrete type inside this item
+fn main() {
+    let thing: MyType = new();
+}
+
+// It can be a part of a struct too
+struct HaveAlias {
+    stuff: String,
+    thing: Alias,
+}
+```
+
+In this example, the concrete type referred to by `Alias` is guaranteed to be the same wherever `Alias` occurs.
+
+> Orginally this feature included type aliases as an associated type of a trait. In [#110237] this was split off to [`impl_trait_in_assoc_type`].
+
+### `type_alias_impl_trait` in argument position.
+
+Note that using `Alias` as an argument type is *not* the same as argument-position `impl Trait`, as `Alias` refers to a unique type, whereas the concrete type for argument-position `impl Trait` is chosen by the caller.
+
+```rust
+# #![feature(type_alias_impl_trait)]
+# #![allow(unused_variables)]
+# pub mod x {
+# pub trait Trait {}
+#
+# struct MyType;
+#
+# impl Trait for MyType {}
+#
+# pub type Alias = impl Trait;
+#
+# #[define_opaque(Alias)]
+# pub fn new() -> Alias {
+#     MyType
+# }
+# }
+# use x::*;
+// this...
+pub fn take_alias(x: Alias) {
+    // ...
+}
+
+// ...is *not* the same as
+pub fn take_impl(x: impl Trait) {
+    // ...
+}
+# fn main(){}
+```
+
+```rust,compile_fail,E0308
+# #![feature(type_alias_impl_trait)]
+# #![allow(unused_variables)]
+# pub mod x {
+# pub trait Trait {}
+#
+# struct MyType;
+#
+# impl Trait for MyType {}
+#
+# pub type Alias = impl Trait;
+#
+# #[define_opaque(Alias)]
+# pub fn new() -> Alias {
+#     MyType
+# }
+# }
+# use x::*;
+# pub fn take_alias(x: Alias) {
+#     // ...
+# }
+#
+# pub fn take_impl(x: impl Trait) {
+#    // ...
+# }
+#
+// a user's crate using the trait and type alias
+struct UserType;
+impl Trait for UserType {}
+
+# fn main(){
+let x = UserType;
+take_alias(x);
+// ERROR expected opaque type, found `UserType`
+// this function *actually* takes a `MyType` as is constrained in `new`
+
+let x = UserType;
+take_impl(x);
+// OK
+
+let x = new();
+take_alias(x);
+// OK
+
+let x = new();
+take_impl(x);
+// OK
+# }
+```
+
+Note that the user cannot use `#[define_opaque(Alias)]` to reify the opaque type because only the crate where the type alias is declared may do so. But if this happened in the same crate and the opaque type was reified, they'd get a familiar error: "expected `MyType`, got `UserType`".
+
+[#63063]: https://github.com/rust-lang/rust/issues/63063
+[#110237]: https://github.com/rust-lang/rust/pull/110237
+[reference]: https://doc.rust-lang.org/stable/reference/types/impl-trait.html#abstract-return-types
+[`trait_alias`]: ./trait-alias.md
+[`impl_trait_in_assoc_type`]: ./impl-trait-in-assoc-type.md
diff --git a/src/doc/unstable-book/src/library-features/c-variadic.md b/src/doc/unstable-book/src/library-features/c-variadic.md
deleted file mode 100644
index 77762116e6b..00000000000
--- a/src/doc/unstable-book/src/library-features/c-variadic.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# `c_variadic`
-
-The tracking issue for this feature is: [#44930]
-
-[#44930]: https://github.com/rust-lang/rust/issues/44930
-
-------------------------
-
-The `c_variadic` library feature exposes the `VaList` structure,
-Rust's analogue of C's `va_list` type.
-
-## Examples
-
-```rust
-#![feature(c_variadic)]
-
-use std::ffi::VaList;
-
-pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize {
-    let mut sum = 0;
-    for _ in 0..n {
-        sum += args.arg::<usize>();
-    }
-    sum
-}
-```
diff --git a/src/etc/test-float-parse/Cargo.toml b/src/etc/test-float-parse/Cargo.toml
index bacb9e09f3f..8a9c5322ef7 100644
--- a/src/etc/test-float-parse/Cargo.toml
+++ b/src/etc/test-float-parse/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "test-float-parse"
 version = "0.1.0"
-edition = "2021"
+edition = "2024"
 publish = false
 
 [dependencies]
diff --git a/src/etc/test-float-parse/src/gen/exhaustive.rs b/src/etc/test-float-parse/src/gen_/exhaustive.rs
index 01458fb0b60..01458fb0b60 100644
--- a/src/etc/test-float-parse/src/gen/exhaustive.rs
+++ b/src/etc/test-float-parse/src/gen_/exhaustive.rs
diff --git a/src/etc/test-float-parse/src/gen/exponents.rs b/src/etc/test-float-parse/src/gen_/exponents.rs
index 3748e9d380c..3748e9d380c 100644
--- a/src/etc/test-float-parse/src/gen/exponents.rs
+++ b/src/etc/test-float-parse/src/gen_/exponents.rs
diff --git a/src/etc/test-float-parse/src/gen/fuzz.rs b/src/etc/test-float-parse/src/gen_/fuzz.rs
index 1d6c5562a14..1d6c5562a14 100644
--- a/src/etc/test-float-parse/src/gen/fuzz.rs
+++ b/src/etc/test-float-parse/src/gen_/fuzz.rs
diff --git a/src/etc/test-float-parse/src/gen/integers.rs b/src/etc/test-float-parse/src/gen_/integers.rs
index 070d188e88c..070d188e88c 100644
--- a/src/etc/test-float-parse/src/gen/integers.rs
+++ b/src/etc/test-float-parse/src/gen_/integers.rs
diff --git a/src/etc/test-float-parse/src/gen/long_fractions.rs b/src/etc/test-float-parse/src/gen_/long_fractions.rs
index b75148b779c..b75148b779c 100644
--- a/src/etc/test-float-parse/src/gen/long_fractions.rs
+++ b/src/etc/test-float-parse/src/gen_/long_fractions.rs
diff --git a/src/etc/test-float-parse/src/gen/many_digits.rs b/src/etc/test-float-parse/src/gen_/many_digits.rs
index 741e11437fe..741e11437fe 100644
--- a/src/etc/test-float-parse/src/gen/many_digits.rs
+++ b/src/etc/test-float-parse/src/gen_/many_digits.rs
diff --git a/src/etc/test-float-parse/src/gen/sparse.rs b/src/etc/test-float-parse/src/gen_/sparse.rs
index 72b65d4ce7f..72b65d4ce7f 100644
--- a/src/etc/test-float-parse/src/gen/sparse.rs
+++ b/src/etc/test-float-parse/src/gen_/sparse.rs
diff --git a/src/etc/test-float-parse/src/gen/spot_checks.rs b/src/etc/test-float-parse/src/gen_/spot_checks.rs
index 18691f9d6cf..18691f9d6cf 100644
--- a/src/etc/test-float-parse/src/gen/spot_checks.rs
+++ b/src/etc/test-float-parse/src/gen_/spot_checks.rs
diff --git a/src/etc/test-float-parse/src/gen/subnorm.rs b/src/etc/test-float-parse/src/gen_/subnorm.rs
index 4fe3b90a3dd..4fe3b90a3dd 100644
--- a/src/etc/test-float-parse/src/gen/subnorm.rs
+++ b/src/etc/test-float-parse/src/gen_/subnorm.rs
diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs
index e2f84b085c6..3c3ef5802b6 100644
--- a/src/etc/test-float-parse/src/lib.rs
+++ b/src/etc/test-float-parse/src/lib.rs
@@ -17,7 +17,7 @@ use traits::{Float, Generator, Int};
 use validate::CheckError;
 
 /// Test generators.
-mod gen {
+mod gen_ {
     pub mod exhaustive;
     pub mod exponents;
     pub mod fuzz;
@@ -136,24 +136,24 @@ where
 {
     if F::BITS <= MAX_BITS_FOR_EXHAUUSTIVE {
         // Only run exhaustive tests if there is a chance of completion.
-        TestInfo::register::<F, gen::exhaustive::Exhaustive<F>>(tests);
+        TestInfo::register::<F, gen_::exhaustive::Exhaustive<F>>(tests);
     }
 
-    gen::fuzz::Fuzz::<F>::set_iterations(cfg.fuzz_count);
-
-    TestInfo::register::<F, gen::exponents::LargeExponents<F>>(tests);
-    TestInfo::register::<F, gen::exponents::SmallExponents<F>>(tests);
-    TestInfo::register::<F, gen::fuzz::Fuzz<F>>(tests);
-    TestInfo::register::<F, gen::integers::LargeInt<F>>(tests);
-    TestInfo::register::<F, gen::integers::SmallInt>(tests);
-    TestInfo::register::<F, gen::long_fractions::RepeatingDecimal>(tests);
-    TestInfo::register::<F, gen::many_digits::RandDigits<F>>(tests);
-    TestInfo::register::<F, gen::sparse::FewOnesFloat<F>>(tests);
-    TestInfo::register::<F, gen::sparse::FewOnesInt<F>>(tests);
-    TestInfo::register::<F, gen::spot_checks::RegressionCheck>(tests);
-    TestInfo::register::<F, gen::spot_checks::Special>(tests);
-    TestInfo::register::<F, gen::subnorm::SubnormComplete<F>>(tests);
-    TestInfo::register::<F, gen::subnorm::SubnormEdgeCases<F>>(tests);
+    gen_::fuzz::Fuzz::<F>::set_iterations(cfg.fuzz_count);
+
+    TestInfo::register::<F, gen_::exponents::LargeExponents<F>>(tests);
+    TestInfo::register::<F, gen_::exponents::SmallExponents<F>>(tests);
+    TestInfo::register::<F, gen_::fuzz::Fuzz<F>>(tests);
+    TestInfo::register::<F, gen_::integers::LargeInt<F>>(tests);
+    TestInfo::register::<F, gen_::integers::SmallInt>(tests);
+    TestInfo::register::<F, gen_::long_fractions::RepeatingDecimal>(tests);
+    TestInfo::register::<F, gen_::many_digits::RandDigits<F>>(tests);
+    TestInfo::register::<F, gen_::sparse::FewOnesFloat<F>>(tests);
+    TestInfo::register::<F, gen_::sparse::FewOnesInt<F>>(tests);
+    TestInfo::register::<F, gen_::spot_checks::RegressionCheck>(tests);
+    TestInfo::register::<F, gen_::spot_checks::Special>(tests);
+    TestInfo::register::<F, gen_::subnorm::SubnormComplete<F>>(tests);
+    TestInfo::register::<F, gen_::subnorm::SubnormEdgeCases<F>>(tests);
 }
 
 /// Configuration for a single test.
@@ -343,7 +343,7 @@ fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration {
 ///
 /// This calls the generator's iterator multiple times (in parallel) and validates each output.
 fn test_runner<F: Float, G: Generator<F>>(test: &TestInfo, cfg: &Config) {
-    let gen = G::new();
+    let gen_ = G::new();
     let executed = AtomicU64::new(0);
     let failures = AtomicU64::new(0);
 
@@ -387,7 +387,7 @@ fn test_runner<F: Float, G: Generator<F>>(test: &TestInfo, cfg: &Config) {
 
     // Run the test iterations in parallel. Each thread gets a string buffer to write
     // its check values to.
-    let res = gen.par_bridge().try_for_each_init(String::new, check_one);
+    let res = gen_.par_bridge().try_for_each_init(String::new, check_one);
 
     let elapsed = started.elapsed();
     let executed = executed.into_inner();
diff --git a/src/etc/test-float-parse/src/ui.rs b/src/etc/test-float-parse/src/ui.rs
index 1ee57723e6a..73473eef0bf 100644
--- a/src/etc/test-float-parse/src/ui.rs
+++ b/src/etc/test-float-parse/src/ui.rs
@@ -157,7 +157,7 @@ pub fn set_panic_hook(drop_bars: &[ProgressBar]) {
     }));
 }
 
-/// Allow non-Debug items in a `derive(Debug)` struct`.
+/// Allow non-Debug items in a `derive(Debug)` struct.
 #[derive(Clone)]
 struct NoDebug<T>(T);
 
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 143191a6f2a..d3ddb77c0b3 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -367,10 +367,7 @@ impl fmt::Debug for Item {
 pub(crate) fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
     Span::new(def_id.as_local().map_or_else(
         || tcx.def_span(def_id),
-        |local| {
-            let hir = tcx.hir();
-            hir.span_with_body(tcx.local_def_id_to_hir_id(local))
-        },
+        |local| tcx.hir_span_with_body(tcx.local_def_id_to_hir_id(local)),
     ))
 }
 
diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs
index 9935074877b..4edd5433de6 100644
--- a/src/librustdoc/doctest/make.rs
+++ b/src/librustdoc/doctest/make.rs
@@ -5,22 +5,36 @@ use std::fmt::{self, Write as _};
 use std::io;
 use std::sync::Arc;
 
-use rustc_ast as ast;
+use rustc_ast::token::{Delimiter, TokenKind};
+use rustc_ast::tokenstream::TokenTree;
+use rustc_ast::{self as ast, AttrStyle, HasAttrs, StmtKind};
+use rustc_errors::ColorConfig;
 use rustc_errors::emitter::stderr_destination;
-use rustc_errors::{ColorConfig, FatalError};
 use rustc_parse::new_parser_from_source_str;
-use rustc_parse::parser::attr::InnerAttrPolicy;
 use rustc_session::parse::ParseSess;
-use rustc_span::FileName;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::sym;
+use rustc_span::{FileName, kw};
 use tracing::debug;
 
 use super::GlobalTestOptions;
 use crate::display::Joined as _;
 use crate::html::markdown::LangString;
 
+#[derive(Default)]
+struct ParseSourceInfo {
+    has_main_fn: bool,
+    already_has_extern_crate: bool,
+    supports_color: bool,
+    has_global_allocator: bool,
+    has_macro_def: bool,
+    everything_else: String,
+    crates: String,
+    crate_attrs: String,
+    maybe_crate_attrs: String,
+}
+
 /// This struct contains information about the doctest itself which is then used to generate
 /// doctest source code appropriately.
 pub(crate) struct DocTestBuilder {
@@ -34,7 +48,7 @@ pub(crate) struct DocTestBuilder {
     pub(crate) crates: String,
     pub(crate) everything_else: String,
     pub(crate) test_id: Option<String>,
-    pub(crate) failed_ast: bool,
+    pub(crate) invalid_ast: bool,
     pub(crate) can_be_merged: bool,
 }
 
@@ -53,9 +67,26 @@ impl DocTestBuilder {
                 !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate
             });
 
-        let Some(SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else }) =
-            partition_source(source, edition)
+        let result = rustc_driver::catch_fatal_errors(|| {
+            rustc_span::create_session_if_not_set_then(edition, |_| {
+                parse_source(source, &crate_name)
+            })
+        });
+
+        let Ok(Ok(ParseSourceInfo {
+            has_main_fn,
+            already_has_extern_crate,
+            supports_color,
+            has_global_allocator,
+            has_macro_def,
+            everything_else,
+            crates,
+            crate_attrs,
+            maybe_crate_attrs,
+        })) = result
         else {
+            // If the AST returned an error, we don't want this doctest to be merged with the
+            // others.
             return Self::invalid(
                 String::new(),
                 String::new(),
@@ -65,35 +96,12 @@ impl DocTestBuilder {
             );
         };
 
-        // Uses librustc_ast to parse the doctest and find if there's a main fn and the extern
-        // crate already is included.
-        let Ok((
-            ParseSourceInfo {
-                has_main_fn,
-                found_extern_crate,
-                supports_color,
-                has_global_allocator,
-                has_macro_def,
-                ..
-            },
-            failed_ast,
-        )) = check_for_main_and_extern_crate(
-            crate_name,
-            source,
-            &everything_else,
-            &crates,
-            edition,
-            can_merge_doctests,
-        )
-        else {
-            // If the parser panicked due to a fatal error, pass the test code through unchanged.
-            // The error will be reported during compilation.
-            return Self::invalid(crate_attrs, maybe_crate_attrs, crates, everything_else, test_id);
-        };
-        // If the AST returned an error, we don't want this doctest to be merged with the
-        // others. Same if it contains `#[feature]` or `#[no_std]`.
+        debug!("crate_attrs:\n{crate_attrs}{maybe_crate_attrs}");
+        debug!("crates:\n{crates}");
+        debug!("after:\n{everything_else}");
+
+        // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either.
         let can_be_merged = can_merge_doctests
-            && !failed_ast
             && !has_global_allocator
             && crate_attrs.is_empty()
             // If this is a merged doctest and a defined macro uses `$crate`, then the path will
@@ -106,9 +114,9 @@ impl DocTestBuilder {
             maybe_crate_attrs,
             crates,
             everything_else,
-            already_has_extern_crate: found_extern_crate,
+            already_has_extern_crate,
             test_id,
-            failed_ast: false,
+            invalid_ast: false,
             can_be_merged,
         }
     }
@@ -129,7 +137,7 @@ impl DocTestBuilder {
             everything_else,
             already_has_extern_crate: false,
             test_id,
-            failed_ast: true,
+            invalid_ast: true,
             can_be_merged: false,
         }
     }
@@ -143,9 +151,10 @@ impl DocTestBuilder {
         opts: &GlobalTestOptions,
         crate_name: Option<&str>,
     ) -> (String, usize) {
-        if self.failed_ast {
+        if self.invalid_ast {
             // If the AST failed to compile, no need to go generate a complete doctest, the error
             // will be better this way.
+            debug!("invalid AST:\n{test_code}");
             return (test_code.to_string(), 0);
         }
         let mut line_offset = 0;
@@ -168,9 +177,24 @@ impl DocTestBuilder {
 
         // Now push any outer attributes from the example, assuming they
         // are intended to be crate attributes.
-        prog.push_str(&self.crate_attrs);
-        prog.push_str(&self.maybe_crate_attrs);
-        prog.push_str(&self.crates);
+        if !self.crate_attrs.is_empty() {
+            prog.push_str(&self.crate_attrs);
+            if !self.crate_attrs.ends_with('\n') {
+                prog.push('\n');
+            }
+        }
+        if !self.maybe_crate_attrs.is_empty() {
+            prog.push_str(&self.maybe_crate_attrs);
+            if !self.maybe_crate_attrs.ends_with('\n') {
+                prog.push('\n');
+            }
+        }
+        if !self.crates.is_empty() {
+            prog.push_str(&self.crates);
+            if !self.crates.ends_with('\n') {
+                prog.push('\n');
+            }
+        }
 
         // Don't inject `extern crate std` because it's already injected by the
         // compiler.
@@ -255,14 +279,7 @@ impl DocTestBuilder {
     }
 }
 
-#[derive(PartialEq, Eq, Debug)]
-enum ParsingResult {
-    Failed,
-    AstError,
-    Ok,
-}
-
-fn cancel_error_count(psess: &ParseSess) {
+fn reset_error_count(psess: &ParseSess) {
     // Reset errors so that they won't be reported as compiler bugs when dropping the
     // dcx. Any errors in the tests will be reported when the test file is compiled,
     // Note that we still need to cancel the errors above otherwise `Diag` will panic on
@@ -270,17 +287,19 @@ fn cancel_error_count(psess: &ParseSess) {
     psess.dcx().reset_err_count();
 }
 
-fn parse_source(
-    source: String,
-    info: &mut ParseSourceInfo,
-    crate_name: &Option<&str>,
-) -> ParsingResult {
+const DOCTEST_CODE_WRAPPER: &str = "fn f(){";
+
+fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceInfo, ()> {
     use rustc_errors::DiagCtxt;
     use rustc_errors::emitter::{Emitter, HumanEmitter};
-    use rustc_parse::parser::ForceCollect;
     use rustc_span::source_map::FilePathMapping;
 
-    let filename = FileName::anon_source_code(&source);
+    let mut info =
+        ParseSourceInfo { already_has_extern_crate: crate_name.is_none(), ..Default::default() };
+
+    let wrapped_source = format!("{DOCTEST_CODE_WRAPPER}{source}\n}}");
+
+    let filename = FileName::anon_source_code(&wrapped_source);
 
     // Any errors in parsing should also appear when the doctest is compiled for real, so just
     // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
@@ -299,25 +318,32 @@ fn parse_source(
     let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
     let psess = ParseSess::with_dcx(dcx, sm);
 
-    let mut parser = match new_parser_from_source_str(&psess, filename, source) {
+    let mut parser = match new_parser_from_source_str(&psess, filename, wrapped_source) {
         Ok(p) => p,
         Err(errs) => {
             errs.into_iter().for_each(|err| err.cancel());
-            cancel_error_count(&psess);
-            return ParsingResult::Failed;
+            reset_error_count(&psess);
+            return Err(());
         }
     };
-    let mut parsing_result = ParsingResult::Ok;
+
+    fn push_to_s(s: &mut String, source: &str, span: rustc_span::Span, prev_span_hi: &mut usize) {
+        let extra_len = DOCTEST_CODE_WRAPPER.len();
+        // We need to shift by the length of `DOCTEST_CODE_WRAPPER` because we
+        // added it at the beginning of the source we provided to the parser.
+        let mut hi = span.hi().0 as usize - extra_len;
+        if hi > source.len() {
+            hi = source.len();
+        }
+        s.push_str(&source[*prev_span_hi..hi]);
+        *prev_span_hi = hi;
+    }
 
     // Recurse through functions body. It is necessary because the doctest source code is
     // wrapped in a function to limit the number of AST errors. If we don't recurse into
     // functions, we would thing all top-level items (so basically nothing).
-    fn check_item(
-        item: &ast::Item,
-        info: &mut ParseSourceInfo,
-        crate_name: &Option<&str>,
-        is_top_level: bool,
-    ) {
+    fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) -> bool {
+        let mut is_extern_crate = false;
         if !info.has_global_allocator
             && item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator)
         {
@@ -325,320 +351,130 @@ fn parse_source(
         }
         match item.kind {
             ast::ItemKind::Fn(ref fn_item) if !info.has_main_fn => {
-                if item.ident.name == sym::main && is_top_level {
+                // We only push if it's the top item because otherwise, we would duplicate
+                // its content since the top-level item was already added.
+                if fn_item.ident.name == sym::main {
                     info.has_main_fn = true;
                 }
-                if let Some(ref body) = fn_item.body {
-                    for stmt in &body.stmts {
-                        match stmt.kind {
-                            ast::StmtKind::Item(ref item) => {
-                                check_item(item, info, crate_name, false)
-                            }
-                            ast::StmtKind::MacCall(..) => info.found_macro = true,
-                            _ => {}
-                        }
-                    }
-                }
             }
-            ast::ItemKind::ExternCrate(original) => {
-                if !info.found_extern_crate
+            ast::ItemKind::ExternCrate(original, ident) => {
+                is_extern_crate = true;
+                if !info.already_has_extern_crate
                     && let Some(crate_name) = crate_name
                 {
-                    info.found_extern_crate = match original {
+                    info.already_has_extern_crate = match original {
                         Some(name) => name.as_str() == *crate_name,
-                        None => item.ident.as_str() == *crate_name,
+                        None => ident.as_str() == *crate_name,
                     };
                 }
             }
-            ast::ItemKind::MacCall(..) => info.found_macro = true,
-            ast::ItemKind::MacroDef(..) => info.has_macro_def = true,
+            ast::ItemKind::MacroDef(..) => {
+                info.has_macro_def = true;
+            }
             _ => {}
         }
+        is_extern_crate
     }
 
-    loop {
-        match parser.parse_item(ForceCollect::No) {
-            Ok(Some(item)) => {
-                check_item(&item, info, crate_name, true);
+    let mut prev_span_hi = 0;
+    let not_crate_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
+    let parsed = parser.parse_item(rustc_parse::parser::ForceCollect::No);
 
-                if info.has_main_fn && info.found_extern_crate {
-                    break;
+    let result = match parsed {
+        Ok(Some(ref item))
+            if let ast::ItemKind::Fn(ref fn_item) = item.kind
+                && let Some(ref body) = fn_item.body =>
+        {
+            for attr in &item.attrs {
+                let attr_name = attr.name_or_empty();
+
+                if attr.style == AttrStyle::Outer || not_crate_attrs.contains(&attr_name) {
+                    // There is one exception to these attributes:
+                    // `#![allow(internal_features)]`. If this attribute is used, we need to
+                    // consider it only as a crate-level attribute.
+                    if attr_name == sym::allow
+                        && let Some(list) = attr.meta_item_list()
+                        && list.iter().any(|sub_attr| {
+                            sub_attr.name_or_empty().as_str() == "internal_features"
+                        })
+                    {
+                        push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
+                    } else {
+                        push_to_s(
+                            &mut info.maybe_crate_attrs,
+                            source,
+                            attr.span,
+                            &mut prev_span_hi,
+                        );
+                    }
+                } else {
+                    push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
                 }
             }
-            Ok(None) => break,
-            Err(e) => {
-                parsing_result = ParsingResult::AstError;
-                e.cancel();
-                break;
-            }
-        }
-
-        // The supplied item is only used for diagnostics,
-        // which are swallowed here anyway.
-        parser.maybe_consume_incorrect_semicolon(None);
-    }
-
-    cancel_error_count(&psess);
-    parsing_result
-}
-
-#[derive(Default)]
-struct ParseSourceInfo {
-    has_main_fn: bool,
-    found_extern_crate: bool,
-    found_macro: bool,
-    supports_color: bool,
-    has_global_allocator: bool,
-    has_macro_def: bool,
-}
-
-fn check_for_main_and_extern_crate(
-    crate_name: Option<&str>,
-    original_source_code: &str,
-    everything_else: &str,
-    crates: &str,
-    edition: Edition,
-    can_merge_doctests: bool,
-) -> Result<(ParseSourceInfo, bool), FatalError> {
-    let result = rustc_driver::catch_fatal_errors(|| {
-        rustc_span::create_session_if_not_set_then(edition, |_| {
-            let mut info =
-                ParseSourceInfo { found_extern_crate: crate_name.is_none(), ..Default::default() };
-
-            let mut parsing_result =
-                parse_source(format!("{crates}{everything_else}"), &mut info, &crate_name);
-            // No need to double-check this if the "merged doctests" feature isn't enabled (so
-            // before the 2024 edition).
-            if can_merge_doctests && parsing_result != ParsingResult::Ok {
-                // If we found an AST error, we want to ensure it's because of an expression being
-                // used outside of a function.
-                //
-                // To do so, we wrap in a function in order to make sure that the doctest AST is
-                // correct. For example, if your doctest is `foo::bar()`, if we don't wrap it in a
-                // block, it would emit an AST error, which would be problematic for us since we
-                // want to filter out such errors which aren't "real" errors.
-                //
-                // The end goal is to be able to merge as many doctests as possible as one for much
-                // faster doctests run time.
-                parsing_result = parse_source(
-                    format!("{crates}\nfn __doctest_wrap(){{{everything_else}\n}}"),
-                    &mut info,
-                    &crate_name,
-                );
-            }
-
-            (info, parsing_result)
-        })
-    });
-    let (mut info, parsing_result) = match result {
-        Err(..) | Ok((_, ParsingResult::Failed)) => return Err(FatalError),
-        Ok((info, parsing_result)) => (info, parsing_result),
-    };
-
-    // If a doctest's `fn main` is being masked by a wrapper macro, the parsing loop above won't
-    // see it. In that case, run the old text-based scan to see if they at least have a main
-    // function written inside a macro invocation. See
-    // https://github.com/rust-lang/rust/issues/56898
-    if info.found_macro
-        && !info.has_main_fn
-        && original_source_code
-            .lines()
-            .map(|line| {
-                let comment = line.find("//");
-                if let Some(comment_begins) = comment { &line[0..comment_begins] } else { line }
-            })
-            .any(|code| code.contains("fn main"))
-    {
-        info.has_main_fn = true;
-    }
-
-    Ok((info, parsing_result != ParsingResult::Ok))
-}
-
-enum AttrKind {
-    CrateAttr,
-    Attr,
-}
-
-/// Returns `Some` if the attribute is complete and `Some(true)` if it is an attribute that can be
-/// placed at the crate root.
-fn check_if_attr_is_complete(source: &str, edition: Edition) -> Option<AttrKind> {
-    if source.is_empty() {
-        // Empty content so nothing to check in here...
-        return None;
-    }
-    let not_crate_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny];
-
-    rustc_driver::catch_fatal_errors(|| {
-        rustc_span::create_session_if_not_set_then(edition, |_| {
-            use rustc_errors::DiagCtxt;
-            use rustc_errors::emitter::HumanEmitter;
-            use rustc_span::source_map::FilePathMapping;
-
-            let filename = FileName::anon_source_code(source);
-            // Any errors in parsing should also appear when the doctest is compiled for real, so just
-            // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
-            let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
-            let fallback_bundle = rustc_errors::fallback_fluent_bundle(
-                rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
-                false,
-            );
-
-            let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
-
-            let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
-            let psess = ParseSess::with_dcx(dcx, sm);
-            let mut parser = match new_parser_from_source_str(&psess, filename, source.to_owned()) {
-                Ok(p) => p,
-                Err(errs) => {
-                    errs.into_iter().for_each(|err| err.cancel());
-                    // If there is an unclosed delimiter, an error will be returned by the
-                    // tokentrees.
-                    return None;
-                }
-            };
-            // If a parsing error happened, it's very likely that the attribute is incomplete.
-            let ret = match parser.parse_attribute(InnerAttrPolicy::Permitted) {
-                Ok(attr) => {
-                    let attr_name = attr.name_or_empty();
-
-                    if not_crate_attrs.contains(&attr_name) {
-                        // There is one exception to these attributes:
-                        // `#![allow(internal_features)]`. If this attribute is used, we need to
-                        // consider it only as a crate-level attribute.
-                        if attr_name == sym::allow
-                            && let Some(list) = attr.meta_item_list()
-                            && list.iter().any(|sub_attr| {
-                                sub_attr.name_or_empty().as_str() == "internal_features"
-                            })
-                        {
-                            Some(AttrKind::CrateAttr)
-                        } else {
-                            Some(AttrKind::Attr)
+            for stmt in &body.stmts {
+                let mut is_extern_crate = false;
+                match stmt.kind {
+                    StmtKind::Item(ref item) => {
+                        is_extern_crate = check_item(&item, &mut info, crate_name);
+                    }
+                    StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
+                        reset_error_count(&psess);
+                        return Err(());
+                    }
+                    StmtKind::MacCall(ref mac_call) if !info.has_main_fn => {
+                        let mut iter = mac_call.mac.args.tokens.iter();
+
+                        while let Some(token) = iter.next() {
+                            if let TokenTree::Token(token, _) = token
+                                && let TokenKind::Ident(name, _) = token.kind
+                                && name == kw::Fn
+                                && let Some(TokenTree::Token(fn_token, _)) = iter.peek()
+                                && let TokenKind::Ident(fn_name, _) = fn_token.kind
+                                && fn_name == sym::main
+                                && let Some(TokenTree::Delimited(_, _, Delimiter::Parenthesis, _)) = {
+                                    iter.next();
+                                    iter.peek()
+                                }
+                            {
+                                info.has_main_fn = true;
+                                break;
+                            }
                         }
-                    } else {
-                        Some(AttrKind::CrateAttr)
                     }
+                    _ => {}
                 }
-                Err(e) => {
-                    e.cancel();
-                    None
-                }
-            };
-            ret
-        })
-    })
-    .unwrap_or(None)
-}
 
-fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edition: Edition) {
-    if let Some(attr_kind) = check_if_attr_is_complete(mod_attr_pending, edition) {
-        let push_to = match attr_kind {
-            AttrKind::CrateAttr => &mut source_info.crate_attrs,
-            AttrKind::Attr => &mut source_info.maybe_crate_attrs,
-        };
-        push_to.push_str(mod_attr_pending);
-        push_to.push('\n');
-        // If it's complete, then we can clear the pending content.
-        mod_attr_pending.clear();
-    } else {
-        mod_attr_pending.push('\n');
-    }
-}
-
-#[derive(Default)]
-struct SourceInfo {
-    crate_attrs: String,
-    maybe_crate_attrs: String,
-    crates: String,
-    everything_else: String,
-}
-
-fn partition_source(s: &str, edition: Edition) -> Option<SourceInfo> {
-    #[derive(Copy, Clone, PartialEq)]
-    enum PartitionState {
-        Attrs,
-        Crates,
-        Other,
-    }
-    let mut source_info = SourceInfo::default();
-    let mut state = PartitionState::Attrs;
-    let mut mod_attr_pending = String::new();
-
-    for line in s.lines() {
-        let trimline = line.trim();
-
-        // FIXME(misdreavus): if a doc comment is placed on an extern crate statement, it will be
-        // shunted into "everything else"
-        match state {
-            PartitionState::Attrs => {
-                state = if trimline.starts_with("#![") {
-                    mod_attr_pending = line.to_owned();
-                    handle_attr(&mut mod_attr_pending, &mut source_info, edition);
-                    continue;
-                } else if trimline.chars().all(|c| c.is_whitespace())
-                    || (trimline.starts_with("//") && !trimline.starts_with("///"))
+                // Weirdly enough, the `Stmt` span doesn't include its attributes, so we need to
+                // tweak the span to include the attributes as well.
+                let mut span = stmt.span;
+                if let Some(attr) =
+                    stmt.kind.attrs().iter().find(|attr| attr.style == AttrStyle::Outer)
                 {
-                    PartitionState::Attrs
-                } else if trimline.starts_with("extern crate")
-                    || trimline.starts_with("#[macro_use] extern crate")
-                {
-                    PartitionState::Crates
-                } else {
-                    // First we check if the previous attribute was "complete"...
-                    if !mod_attr_pending.is_empty() {
-                        // If not, then we append the new line into the pending attribute to check
-                        // if this time it's complete...
-                        mod_attr_pending.push_str(line);
-                        if !trimline.is_empty() {
-                            handle_attr(&mut mod_attr_pending, &mut source_info, edition);
-                        }
-                        continue;
-                    } else {
-                        PartitionState::Other
-                    }
-                };
-            }
-            PartitionState::Crates => {
-                state = if trimline.starts_with("extern crate")
-                    || trimline.starts_with("#[macro_use] extern crate")
-                    || trimline.chars().all(|c| c.is_whitespace())
-                    || (trimline.starts_with("//") && !trimline.starts_with("///"))
+                    span = span.with_lo(attr.span.lo());
+                }
+                if info.everything_else.is_empty()
+                    && (!info.maybe_crate_attrs.is_empty() || !info.crate_attrs.is_empty())
                 {
-                    PartitionState::Crates
+                    // To keep the doctest code "as close as possible" to the original, we insert
+                    // all the code located between this new span and the previous span which
+                    // might contain code comments and backlines.
+                    push_to_s(&mut info.crates, source, span.shrink_to_lo(), &mut prev_span_hi);
+                }
+                if !is_extern_crate {
+                    push_to_s(&mut info.everything_else, source, span, &mut prev_span_hi);
                 } else {
-                    PartitionState::Other
-                };
+                    push_to_s(&mut info.crates, source, span, &mut prev_span_hi);
+                }
             }
-            PartitionState::Other => {}
+            Ok(info)
         }
-
-        match state {
-            PartitionState::Attrs => {
-                source_info.crate_attrs.push_str(line);
-                source_info.crate_attrs.push('\n');
-            }
-            PartitionState::Crates => {
-                source_info.crates.push_str(line);
-                source_info.crates.push('\n');
-            }
-            PartitionState::Other => {
-                source_info.everything_else.push_str(line);
-                source_info.everything_else.push('\n');
-            }
+        Err(e) => {
+            e.cancel();
+            Err(())
         }
-    }
-
-    if !mod_attr_pending.is_empty() {
-        debug!("invalid doctest code: {s:?}");
-        return None;
-    }
-
-    source_info.everything_else = source_info.everything_else.trim().to_string();
-
-    debug!("crate_attrs:\n{}{}", source_info.crate_attrs, source_info.maybe_crate_attrs);
-    debug!("crates:\n{}", source_info.crates);
-    debug!("after:\n{}", source_info.everything_else);
+        _ => Err(()),
+    };
 
-    Some(source_info)
+    reset_error_count(&psess);
+    result
 }
diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs
index f891505d2a6..784d628805d 100644
--- a/src/librustdoc/doctest/runner.rs
+++ b/src/librustdoc/doctest/runner.rs
@@ -113,6 +113,7 @@ impl DocTestRunner {
 mod __doctest_mod {{
     use std::sync::OnceLock;
     use std::path::PathBuf;
+    use std::process::ExitCode;
 
     pub static BINARY_PATH: OnceLock<PathBuf> = OnceLock::new();
     pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\";
@@ -123,16 +124,17 @@ mod __doctest_mod {{
     }}
 
     #[allow(unused)]
-    pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{
+    pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> ExitCode {{
         let out = std::process::Command::new(bin)
             .env(self::RUN_OPTION, test_nb.to_string())
             .args(std::env::args().skip(1).collect::<Vec<_>>())
             .output()
             .expect(\"failed to run command\");
         if !out.status.success() {{
-            Err(String::from_utf8_lossy(&out.stderr).to_string())
+            eprint!(\"{{}}\", String::from_utf8_lossy(&out.stderr));
+            ExitCode::FAILURE
         }} else {{
-            Ok(())
+            ExitCode::SUCCESS
         }}
     }}
 }}
@@ -144,7 +146,6 @@ let tests = {{
     {ids}
     tests
 }};
-let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION);
 let test_args = &[{test_args}];
 const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\";
 
diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs
index 12f8b26b1e3..be2dea641d7 100644
--- a/src/librustdoc/doctest/rust.rs
+++ b/src/librustdoc/doctest/rust.rs
@@ -80,7 +80,7 @@ impl<'tcx> HirCollector<'tcx> {
 
     pub fn collect_crate(mut self) -> Vec<ScrapedDocTest> {
         let tcx = self.tcx;
-        self.visit_testable(None, CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), |this| {
+        self.visit_testable(None, CRATE_DEF_ID, tcx.hir_span(CRATE_HIR_ID), |this| {
             tcx.hir_walk_toplevel_module(this)
         });
         self.collector.tests
diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs
index e2b964bf5af..49add73e9d6 100644
--- a/src/librustdoc/doctest/tests.rs
+++ b/src/librustdoc/doctest/tests.rs
@@ -197,6 +197,7 @@ fn make_test_crate_attrs() {
 assert_eq!(2+2, 4);";
     let expected = "#![allow(unused)]
 #![feature(sick_rad)]
+
 fn main() {
 assert_eq!(2+2, 4);
 }"
@@ -228,8 +229,8 @@ fn make_test_fake_main() {
     let input = "//Ceci n'est pas une `fn main`
 assert_eq!(2+2, 4);";
     let expected = "#![allow(unused)]
-//Ceci n'est pas une `fn main`
 fn main() {
+//Ceci n'est pas une `fn main`
 assert_eq!(2+2, 4);
 }"
     .to_string();
@@ -259,8 +260,8 @@ fn make_test_issues_21299() {
 assert_eq!(2+2, 4);";
 
     let expected = "#![allow(unused)]
-// fn main
 fn main() {
+// fn main
 assert_eq!(2+2, 4);
 }"
     .to_string();
@@ -401,3 +402,76 @@ fn check_split_args() {
     compare("a\n\t \rb", &["a", "b"]);
     compare("a\n\t1 \rb", &["a", "1", "b"]);
 }
+
+#[test]
+fn comment_in_attrs() {
+    // If there is an inline code comment after attributes, we need to ensure that
+    // a backline will be added to prevent generating code "inside" it (and thus generating)
+    // invalid code.
+    let opts = default_global_opts("");
+    let input = "\
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
+#![doc(rust_logo)]
+//! This crate has the Rust(tm) branding on it.";
+    let expected = "\
+#![allow(unused)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
+#![doc(rust_logo)]
+//! This crate has the Rust(tm) branding on it.
+fn main() {
+
+}"
+    .to_string();
+    let (output, len) = make_test(input, None, false, &opts, None);
+    assert_eq!((output, len), (expected, 2));
+
+    // And same, if there is a `main` function provided by the user, we ensure that it's
+    // correctly separated.
+    let input = "\
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
+#![doc(rust_logo)]
+//! This crate has the Rust(tm) branding on it.
+fn main() {}";
+    let expected = "\
+#![allow(unused)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
+#![doc(rust_logo)]
+//! This crate has the Rust(tm) branding on it.
+
+fn main() {}"
+        .to_string();
+    let (output, len) = make_test(input, None, false, &opts, None);
+    assert_eq!((output, len), (expected, 1));
+}
+
+// This test ensures that the only attributes taken into account when we switch between
+// "crate level" content and the rest doesn't include inner attributes span, as it would
+// include part of the item and generate broken code.
+#[test]
+fn inner_attributes() {
+    let opts = default_global_opts("");
+    let input = r#"
+//! A doc comment that applies to the implicit anonymous module of this crate
+
+pub mod outer_module {
+    //!! - Still an inner line doc (but with a bang at the beginning)
+}
+"#;
+    let expected = "#![allow(unused)]
+
+//! A doc comment that applies to the implicit anonymous module of this crate
+
+
+fn main() {
+pub mod outer_module {
+    //!! - Still an inner line doc (but with a bang at the beginning)
+}
+}"
+    .to_string();
+    let (output, len) = make_test(input, None, false, &opts, None);
+    assert_eq!((output, len), (expected, 2));
+}
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 0d547a6a0d9..334a7a86989 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1724,6 +1724,7 @@ pub(crate) fn markdown_links<'md, R>(
     md: &'md str,
     preprocess_link: impl Fn(MarkdownLink) -> Option<R>,
 ) -> Vec<R> {
+    use itertools::Itertools;
     if md.is_empty() {
         return vec![];
     }
@@ -1882,7 +1883,7 @@ pub(crate) fn markdown_links<'md, R>(
     let mut links = Vec::new();
 
     let mut refdefs = FxIndexMap::default();
-    for (label, refdef) in event_iter.reference_definitions().iter() {
+    for (label, refdef) in event_iter.reference_definitions().iter().sorted_by_key(|x| x.0) {
         refdefs.insert(label.to_string(), (false, refdef.dest.to_string(), refdef.span.clone()));
     }
 
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 3676051b1bd..846d3ad310c 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -95,7 +95,7 @@ impl SpanMapVisitor<'_> {
                     .unwrap_or(path.span);
                 self.matches.insert(span, link);
             }
-            Res::Local(_) if let Some(span) = self.tcx.hir().res_span(path.res) => {
+            Res::Local(_) if let Some(span) = self.tcx.hir_res_span(path.res) => {
                 self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span)));
             }
             Res::PrimTy(p) => {
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 0ea4d8f1e39..aa8df35258d 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1446,6 +1446,9 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	align-items: center;
 	cursor: pointer;
 }
+.setting-check input {
+	flex-shrink: 0,
+}
 
 .setting-radio input:checked {
 	box-shadow: inset 0 0 0 3px var(--main-background-color);
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 4150c5609a9..a7ce2bf9048 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -1101,7 +1101,6 @@ function preLoadCss(cssUrl) {
         });
     }());
 
-    // @ts-expect-error
     window.rustdoc_add_line_numbers_to_examples = () => {
         // @ts-expect-error
         function generateLine(nb) {
@@ -1123,7 +1122,6 @@ function preLoadCss(cssUrl) {
         });
     };
 
-    // @ts-expect-error
     window.rustdoc_remove_line_numbers_from_examples = () => {
         onEachLazy(
             document.querySelectorAll(".rustdoc:not(.src) :not(.scraped-example) > .example-wrap"),
@@ -1132,7 +1130,6 @@ function preLoadCss(cssUrl) {
     };
 
     if (getSettingValue("line-numbers") === "true") {
-        // @ts-expect-error
         window.rustdoc_add_line_numbers_to_examples();
     }
 
@@ -1596,7 +1593,7 @@ function preLoadCss(cssUrl) {
     /**
      * Hide popover menus, clickable tooltips, and the sidebar (if applicable).
      *
-     * Pass "true" to reset focus for tooltip popovers.
+     * Pass `true` to reset focus for tooltip popovers.
      */
     window.hideAllModals = switchFocus => {
         hideSidebar();
diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts
index e94c6beabea..0d2e19e019f 100644
--- a/src/librustdoc/html/static/js/rustdoc.d.ts
+++ b/src/librustdoc/html/static/js/rustdoc.d.ts
@@ -6,8 +6,10 @@
 declare global {
     /** Map from crate name to directory structure, for source view */
     declare var srcIndex: Map<string, rustdoc.Dir>;
-    /** Defined and documented in `main.js` */
+    /** Defined and documented in `storage.js` */
     declare function nonnull(x: T|null, msg: string|undefined);
+    /** Defined and documented in `storage.js` */
+    declare function nonundef(x: T|undefined, msg: string|undefined);
     interface Window {
         /** Make the current theme easy to find */
         currentTheme: HTMLLinkElement|null;
@@ -28,6 +30,8 @@ declare global {
         currentCrate: string|null;
         /**
          * Hide popovers, tooltips, or the mobile sidebar.
+         *
+         * Pass `true` to reset focus for tooltip popovers.
          */
         hideAllModals: function(boolean),
         /**
@@ -76,6 +80,8 @@ declare global {
         pending_implementors?: rustdoc.Implementors,
         register_type_impls?: function(rustdoc.TypeImpls): void,
         pending_type_impls?: rustdoc.TypeImpls,
+        rustdoc_add_line_numbers_to_examples?: function(),
+        rustdoc_remove_line_numbers_from_examples?: function(),
     }
     interface HTMLElement {
         /** Used by the popover tooltip code. */
@@ -255,13 +261,21 @@ declare namespace rustdoc {
         ty: number,
         type?: FunctionSearchType,
         paramNames?: string[],
-        displayType: Promise<Array<Array<string>>>|null,
-        displayTypeMappedNames: Promise<Array<[string, Array<string>]>>|null,
+        displayTypeSignature: Promise<rustdoc.DisplayTypeSignature> | null,
         item: Row,
         dontValidate?: boolean,
     }
 
     /**
+     * output of `formatDisplayTypeSignature`
+     */
+    interface DisplayTypeSignature {
+        type: Array<string>,
+        mappedNames: Map<string, string>,
+        whereClause: Map<string, Array<string>>,
+    }
+
+    /**
      * A pair of [inputs, outputs], or 0 for null. This is stored in the search index.
      * The JavaScript deserializes this into FunctionSearchType.
      *
@@ -467,4 +481,14 @@ declare namespace rustdoc {
      * is a tuple of (filename, subdirs, filenames).
      */
     type Dir = [string, rustdoc.Dir[], string[]]
+
+    /**
+     * Indivitual setting object, used in `settings.js`
+     */
+    interface Setting {
+        js_name: string,
+        name: string,
+        options?: string[],
+        default: string | boolean,
+    }
 }
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index c275127997a..dce5fddb317 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -33,6 +33,20 @@ function onEachBtwn(arr, func, funcBtwn) {
     }
 }
 
+/**
+ * Convert any `undefined` to `null`.
+ *
+ * @template T
+ * @param {T|undefined} x
+ * @returns {T|null}
+ */
+function undef2null(x) {
+    if (x !== undefined) {
+        return x;
+    }
+    return null;
+}
+
 // ==================== Core search logic begin ====================
 // This mapping table should match the discriminants of
 // `rustdoc::formats::item_type::ItemType` type in Rust.
@@ -338,7 +352,7 @@ function getFilteredNextElem(query, parserState, elems, isInGenerics) {
         // The type filter doesn't count as an element since it's a modifier.
         const typeFilterElem = elems.pop();
         checkExtraTypeFilterCharacters(start, parserState);
-        // typeFilterElem is not null. If it was, the elems.length check would have fired.
+        // typeFilterElem is not undefined. If it was, the elems.length check would have fired.
         // @ts-expect-error
         parserState.typeFilter = typeFilterElem.normalizedPathLast;
         parserState.pos += 1;
@@ -1311,10 +1325,9 @@ class NameTrie {
                 let sste;
                 if (substart >= 2) {
                     const tail = name.substring(substart - 2, substart + 1);
-                    if (tailTable.has(tail)) {
-                        // it's not undefined
-                        // @ts-expect-error
-                        sste = tailTable.get(tail);
+                    const entry = tailTable.get(tail);
+                    if (entry !== undefined) {
+                        sste = entry;
                     } else {
                         sste = [];
                         tailTable.set(tail, sste);
@@ -1338,10 +1351,9 @@ class NameTrie {
                 new Lev1TParametricDescription(name.length);
             this.searchLev(name, 0, levParams, results);
             const tail = name.substring(0, 3);
-            if (tailTable.has(tail)) {
-                // it's not undefined
-                // @ts-expect-error
-                for (const entry of tailTable.get(tail)) {
+            const list = tailTable.get(tail);
+            if (list !== undefined) {
+                for (const entry of list) {
                     entry.searchSubstringPrefix(name, 3, results);
                 }
             }
@@ -1600,10 +1612,8 @@ class DocSearch {
             return null;
         }
 
-        if (this.typeNameIdMap.has(name)) {
-            /** @type {{id: number, assocOnly: boolean}} */
-            // @ts-expect-error
-            const obj = this.typeNameIdMap.get(name);
+        const obj = this.typeNameIdMap.get(name);
+        if (obj !== undefined) {
             obj.assocOnly = !!(isAssocType && obj.assocOnly);
             return obj.id;
         } else {
@@ -2082,7 +2092,8 @@ class DocSearch {
                 descIndex += 1;
             }
 
-            // a String of one character item type codes
+            // see `RawSearchIndexCrate` in `rustdoc.d.ts` for a more
+            // up to date description of these fields
             const itemTypes = crateCorpus.t;
             // an array of (String) item names
             const itemNames = crateCorpus.n;
@@ -2099,8 +2110,6 @@ class DocSearch {
             const itemParentIdxDecoder = new VlqHexDecoder(crateCorpus.i, noop => noop);
             // a map Number, string for impl disambiguators
             const implDisambiguator = new Map(crateCorpus.b);
-            // an array of [(Number) item type,
-            //              (String) name]
             const rawPaths = crateCorpus.p;
             const aliases = crateCorpus.a;
             // an array of [(Number) item index,
@@ -2139,30 +2148,31 @@ class DocSearch {
             // convert `rawPaths` entries into object form
             // generate normalizedPaths for function search mode
             let len = rawPaths.length;
-            let lastPath = itemPaths.get(0);
+            let lastPath = undef2null(itemPaths.get(0));
             for (let i = 0; i < len; ++i) {
                 const elem = rawPaths[i];
                 const ty = elem[0];
                 const name = elem[1];
-                let path = null;
-                if (elem.length > 2 && elem[2] !== null) {
-                    // @ts-expect-error
-                    path = itemPaths.has(elem[2]) ? itemPaths.get(elem[2]) : lastPath;
-                    lastPath = path;
-                }
-                let exactPath = elem.length > 3 && elem[3] !== null ?
-                    // @ts-expect-error
-                    itemPaths.get(elem[3]) :
-                    path;
+                /**
+                 * @param {2|3} idx
+                 * @param {string|null} if_null
+                 * @param {string|null} if_not_found
+                 * @returns {string|null}
+                 */
+                const elemPath = (idx, if_null, if_not_found) => {
+                    if (elem.length > idx && elem[idx] !== undefined) {
+                        const p = itemPaths.get(elem[idx]);
+                        if (p !== undefined) {
+                            return p;
+                        }
+                        return if_not_found;
+                    }
+                    return if_null;
+                };
+                const path = elemPath(2, lastPath, null);
+                const exactPath = elemPath(3, path, path);
                 const unboxFlag = elem.length > 4 && !!elem[4];
 
-                if (path === undefined) {
-                    path = null;
-                }
-                if (exactPath === undefined) {
-                    exactPath = null;
-                }
-
                 lowercasePaths.push({ ty, name: name.toLowerCase(), path, exactPath, unboxFlag });
                 paths[i] = { ty, name, path, exactPath, unboxFlag };
             }
@@ -2196,12 +2206,11 @@ class DocSearch {
                 }
                 const name = itemNames[i] === "" ? lastName : itemNames[i];
                 const word = itemNames[i] === "" ? lastWord : itemNames[i].toLowerCase();
-                /** @type {string} */
-                // @ts-expect-error
-                const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath;
-                const paramNames = itemParamNames.has(i) ?
-                    // @ts-expect-error
-                    itemParamNames.get(i).split(",") :
+                const pathU = itemPaths.get(i);
+                const path = pathU !== undefined ? pathU : lastPath;
+                const paramNameString = itemParamNames.get(i);
+                const paramNames = paramNameString !== undefined ?
+                    paramNameString.split(",") :
                     lastParamNames;
                 const type = itemFunctionDecoder.next();
                 if (type !== null) {
@@ -2243,8 +2252,7 @@ class DocSearch {
                     word,
                     normalizedName,
                     bitIndex,
-                    implDisambiguator: implDisambiguator.has(i) ?
-                        implDisambiguator.get(i) : null,
+                    implDisambiguator: undef2null(implDisambiguator.get(i)),
                 };
                 this.nameTrie.insert(normalizedName, id, this.tailTable);
                 id += 1;
@@ -2482,9 +2490,13 @@ class DocSearch {
             }
         } catch (err) {
             query = newParsedQuery(userQuery);
-            // is string list
-            // @ts-expect-error
-            query.error = err;
+            if (Array.isArray(err) && err.every(elem => typeof elem === "string")) {
+                query.error = err;
+            } else {
+                // rethrow the error if it isn't a string array
+                throw err;
+            }
+
             return query;
         }
         if (!query.literalSearch) {
@@ -2572,9 +2584,9 @@ class DocSearch {
             if ((elem.id === null && parsedQuery.totalElems > 1 && elem.typeFilter === -1
                 && elem.generics.length === 0 && elem.bindings.size === 0)
                 || elem.typeFilter === TY_GENERIC) {
-                if (genericSymbols.has(elem.normalizedPathLast)) {
-                    // @ts-expect-error
-                    elem.id = genericSymbols.get(elem.normalizedPathLast);
+                const id = genericSymbols.get(elem.normalizedPathLast);
+                if (id !== undefined) {
+                    elem.id = id;
                 } else {
                     elem.id = -(genericSymbols.size + 1);
                     genericSymbols.set(elem.normalizedPathLast, elem.id);
@@ -2766,15 +2778,28 @@ class DocSearch {
             for (const result of results) {
                 if (result.id !== -1) {
                     const res = buildHrefAndPath(this.searchIndex[result.id]);
+                    // many of these properties don't strictly need to be
+                    // copied over, but copying them over satisfies tsc,
+                    // and hopefully plays nice with the shape optimization
+                    // of the browser engine.
+                    /** @type {rustdoc.ResultObject} */
                     const obj = Object.assign({
+                        parent: result.parent,
+                        type: result.type,
                         dist: result.dist,
+                        path_dist: result.path_dist,
+                        index: result.index,
+                        desc: result.desc,
+                        item: result.item,
                         displayPath: pathSplitter(res[0]),
+                        fullPath: "",
+                        href: "",
+                        displayTypeSignature: null,
                     }, this.searchIndex[result.id]);
 
                     // To be sure than it some items aren't considered as duplicate.
-                    // @ts-expect-error
                     obj.fullPath = res[2] + "|" + obj.ty;
-                    // @ts-expect-error
+
                     if (duplicates.has(obj.fullPath)) {
                         continue;
                     }
@@ -2787,18 +2812,15 @@ class DocSearch {
                     if (duplicates.has(res[2] + "|" + TY_IMPORT)) {
                         continue;
                     }
-                    // @ts-expect-error
                     duplicates.add(obj.fullPath);
                     duplicates.add(res[2]);
 
                     if (typeInfo !== null) {
-                        // @ts-expect-error
                         obj.displayTypeSignature =
                             // @ts-expect-error
                             this.formatDisplayTypeSignature(obj, typeInfo);
                     }
 
-                    // @ts-expect-error
                     obj.href = res[1];
                     out.push(obj);
                     if (out.length >= MAX_RESULTS) {
@@ -2806,7 +2828,6 @@ class DocSearch {
                     }
                 }
             }
-            // @ts-expect-error
             return out;
         };
 
@@ -2819,11 +2840,7 @@ class DocSearch {
          *
          * @param {rustdoc.ResultObject} obj
          * @param {"sig"|"elems"|"returned"|null} typeInfo
-         * @returns {Promise<{
-         *   "type": Array<string>,
-         *   "mappedNames": Map<string, string>,
-         *   "whereClause": Map<string, Array<string>>,
-         * }>}
+         * @returns {Promise<rustdoc.DisplayTypeSignature>}
          */
         this.formatDisplayTypeSignature = async(obj, typeInfo) => {
             const objType = obj.type;
@@ -2885,7 +2902,7 @@ class DocSearch {
             const whereClause = new Map();
 
             const fnParamNames = obj.paramNames || [];
-            // @ts-expect-error
+            /** @type {string[]} */
             const queryParamNames = [];
             /**
              * Recursively writes a map of IDs to query generic names,
@@ -2918,7 +2935,7 @@ class DocSearch {
              * index 2 is not highlighted, etc.
              *
              * @param {{name?: string, highlighted?: boolean}} fnType - input
-             * @param {[string]} result
+             * @param {string[]} result
              */
             const pushText = (fnType, result) => {
                 // If !!(result.length % 2) == false, then pushing a new slot starts an even
@@ -2930,7 +2947,6 @@ class DocSearch {
                 // needs coerced to a boolean.
                 if (!!(result.length % 2) === !!fnType.highlighted) {
                     result.push("");
-                // @ts-expect-error
                 } else if (result.length === 0 && !!fnType.highlighted) {
                     result.push("");
                     result.push("");
@@ -2944,7 +2960,7 @@ class DocSearch {
              * or a trait bound on Fn, FnMut, or FnOnce.
              *
              * @param {rustdoc.HighlightedFunctionType} fnType - input
-             * @param {[string]} result
+             * @param {string[]} result
              */
             const writeHof = (fnType, result) => {
                 const hofOutput = fnType.bindings.get(this.typeNameIdOfOutput) || [];
@@ -2984,7 +3000,7 @@ class DocSearch {
              * Returns `false` if the supplied type isn't special.
              *
              * @param {rustdoc.HighlightedFunctionType} fnType
-             * @param {[string]} result
+             * @param {string[]} result
              */
             const writeSpecialPrimitive = (fnType, result) => {
                 if (fnType.id === this.typeNameIdOfArray || fnType.id === this.typeNameIdOfSlice ||
@@ -3031,7 +3047,7 @@ class DocSearch {
              * updating the where clause and generic type param map.
              *
              * @param {rustdoc.HighlightedFunctionType} fnType
-             * @param {[string]} result
+             * @param {string[]} result
              */
             const writeFn = (fnType, result) => {
                 if (fnType.id !== null && fnType.id < 0) {
@@ -3049,7 +3065,6 @@ class DocSearch {
                         for (const [queryId, fnId] of mgens) {
                             if (fnId === fnType.id) {
                                 mappedNames.set(
-                                    // @ts-expect-error
                                     queryParamNames[-1 - queryId],
                                     fnParamNames[-1 - fnType.id],
                                 );
@@ -3064,7 +3079,6 @@ class DocSearch {
                     const where = [];
                     onEachBtwn(
                         fnType.generics,
-                        // @ts-expect-error
                         nested => writeFn(nested, where),
                         // @ts-expect-error
                         () => pushText({ name: " + ", highlighted: false }, where),
@@ -3099,7 +3113,6 @@ class DocSearch {
                                     // shown in the where clause and name mapping output, but is
                                     // redundant in this spot
                                     for (const value of values) {
-                                        // @ts-expect-error
                                         writeFn(value, []);
                                     }
                                     return true;
@@ -3141,26 +3154,22 @@ class DocSearch {
                     }
                 }
             };
-            // @ts-expect-error
+            /** @type {string[]} */
             const type = [];
             onEachBtwn(
                 fnInputs,
-                // @ts-expect-error
                 fnType => writeFn(fnType, type),
                 // @ts-expect-error
                 () => pushText({ name: ", ",  highlighted: false }, type),
             );
-            // @ts-expect-error
             pushText({ name: " -> ", highlighted: false }, type);
             onEachBtwn(
                 fnOutput,
-                // @ts-expect-error
                 fnType => writeFn(fnType, type),
                 // @ts-expect-error
                 () => pushText({ name: ", ",  highlighted: false }, type),
             );
 
-            // @ts-expect-error
             return {type, mappedNames, whereClause};
         };
 
@@ -3475,8 +3484,7 @@ class DocSearch {
                         }
                     }
                 }
-                // @ts-expect-error
-                return false;
+                return null;
             }
 
             // Multiple element recursive case
@@ -3532,7 +3540,7 @@ class DocSearch {
                 }
                 /** @type {rustdoc.HighlightedFunctionType[]|null} */
                 let unifiedGenerics = [];
-                // @ts-expect-error
+                /** @type {null|Map<number, number>} */
                 let unifiedGenericsMgens = null;
                 /** @type {rustdoc.HighlightedFunctionType[]|null} */
                 const passesUnification = unifyFunctionTypes(
@@ -3586,7 +3594,6 @@ class DocSearch {
                                 // @ts-expect-error
                                 queryElem.bindings.get(k),
                                 whereClause,
-                                // @ts-expect-error
                                 unifiedGenericsMgens,
                                 solutionCb,
                                 unboxingDepth,
@@ -3984,7 +3991,7 @@ class DocSearch {
                     }
                     const fnTypeBindings = fnType.bindings.get(name);
                     mgensSolutionSet = mgensSolutionSet.flatMap(mgens => {
-                        // @ts-expect-error
+                        /** @type{Array<Map<number, number> | null>} */
                         const newSolutions = [];
                         unifyFunctionTypes(
                             // @ts-expect-error
@@ -4000,7 +4007,6 @@ class DocSearch {
                             },
                             unboxingDepth,
                         );
-                        // @ts-expect-error
                         return newSolutions;
                     });
                 }
@@ -4248,6 +4254,7 @@ class DocSearch {
             return false;
         }
 
+        // this does not yet have a type in `rustdoc.d.ts`.
         // @ts-expect-error
         function createAliasFromItem(item) {
             return {
diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js
index 5f1bbd27328..2430b5829b2 100644
--- a/src/librustdoc/html/static/js/settings.js
+++ b/src/librustdoc/html/static/js/settings.js
@@ -1,22 +1,39 @@
 // Local js definitions:
 /* global getSettingValue, updateLocalStorage, updateTheme */
 /* global addClass, removeClass, onEach, onEachLazy */
-/* global MAIN_ID, getVar, getSettingsButton, getHelpButton */
-
-// Eventually fix this.
-// @ts-nocheck
+/* global MAIN_ID, getVar, getSettingsButton, getHelpButton, nonnull */
 
 "use strict";
 
 (function() {
     const isSettingsPage = window.location.pathname.endsWith("/settings.html");
 
+    /**
+     * @param {Element} elem
+     * @param {EventTarget|null} target
+     */
+    function elemContainsTarget(elem, target) {
+        if (target instanceof Node) {
+            return elem.contains(target);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * @overload {"theme"|"preferred-dark-theme"|"preferred-light-theme"}
+     * @param {string} settingName
+     * @param {string} value
+     * @returns
+     * @param {string} settingName
+     * @param {string|boolean} value
+     */
     function changeSetting(settingName, value) {
         if (settingName === "theme") {
             const useSystem = value === "system preference" ? "true" : "false";
             updateLocalStorage("use-system-theme", useSystem);
         }
-        updateLocalStorage(settingName, value);
+        updateLocalStorage(settingName, "" + value);
 
         switch (settingName) {
             case "theme":
@@ -27,9 +44,15 @@
                 break;
             case "line-numbers":
                 if (value === true) {
-                    window.rustdoc_add_line_numbers_to_examples();
+                    const f = window.rustdoc_add_line_numbers_to_examples;
+                    if (f !== undefined) {
+                        f();
+                    }
                 } else {
-                    window.rustdoc_remove_line_numbers_from_examples();
+                    const f = window.rustdoc_remove_line_numbers_from_examples;
+                    if (f !== undefined) {
+                        f();
+                    }
                 }
                 break;
             case "hide-sidebar":
@@ -89,6 +112,9 @@
         }
     }
 
+    /**
+     * @param {HTMLElement} settingsElement
+     */
     function setEvents(settingsElement) {
         updateLightAndDark();
         onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"), toggle => {
@@ -101,23 +127,27 @@
                 changeSetting(toggle.id, toggle.checked);
             };
         });
-        onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), elem => {
-            const settingId = elem.name;
-            let settingValue = getSettingValue(settingId);
-            if (settingId === "theme") {
-                const useSystem = getSettingValue("use-system-theme");
-                if (useSystem === "true" || settingValue === null) {
-                    // "light" is the default theme
-                    settingValue = useSystem === "false" ? "light" : "system preference";
+        onEachLazy(
+            settingsElement.querySelectorAll("input[type=\"radio\"]"),
+            /** @param {HTMLInputElement} elem */
+            elem => {
+                const settingId = elem.name;
+                let settingValue = getSettingValue(settingId);
+                if (settingId === "theme") {
+                    const useSystem = getSettingValue("use-system-theme");
+                    if (useSystem === "true" || settingValue === null) {
+                        // "light" is the default theme
+                        settingValue = useSystem === "false" ? "light" : "system preference";
+                    }
                 }
-            }
-            if (settingValue !== null && settingValue !== "null") {
-                elem.checked = settingValue === elem.value;
-            }
-            elem.addEventListener("change", ev => {
-                changeSetting(ev.target.name, ev.target.value);
-            });
-        });
+                if (settingValue !== null && settingValue !== "null") {
+                    elem.checked = settingValue === elem.value;
+                }
+                elem.addEventListener("change", () => {
+                    changeSetting(elem.name, elem.value);
+                });
+            },
+        );
     }
 
     /**
@@ -125,7 +155,7 @@
      * as argument which describes each setting and how to render it. It returns a string
      * representing the raw HTML.
      *
-     * @param {Array<Object>} settings
+     * @param {Array<rustdoc.Setting>} settings
      *
      * @return {string}
      */
@@ -133,11 +163,6 @@
         let output = "";
 
         for (const setting of settings) {
-            if (setting === "hr") {
-                output += "<hr>";
-                continue;
-            }
-
             const js_data_name = setting["js_name"];
             const setting_name = setting["name"];
 
@@ -182,7 +207,9 @@
      * @return {HTMLElement}
      */
     function buildSettingsPage() {
-        const theme_names = getVar("themes").split(",").filter(t => t);
+        const theme_list = getVar("themes");
+        const theme_names = (theme_list === null ? "" : theme_list)
+              .split(",").filter(t => t);
         theme_names.push("light", "dark", "ayu");
 
         const settings = [
@@ -272,10 +299,16 @@
         el.innerHTML = innerHTML;
 
         if (isSettingsPage) {
-            document.getElementById(MAIN_ID).appendChild(el);
+            const mainElem = document.getElementById(MAIN_ID);
+            if (mainElem !== null) {
+                mainElem.appendChild(el);
+            }
         } else {
             el.setAttribute("tabindex", "-1");
-            getSettingsButton().appendChild(el);
+            const settingsBtn = getSettingsButton();
+            if (settingsBtn !== null) {
+                settingsBtn.appendChild(el);
+            }
         }
         return el;
     }
@@ -293,34 +326,44 @@
         });
     }
 
+    /**
+     * @param {FocusEvent} event
+     */
     function settingsBlurHandler(event) {
-        if (!getHelpButton().contains(document.activeElement) &&
-            !getHelpButton().contains(event.relatedTarget) &&
-            !getSettingsButton().contains(document.activeElement) &&
-            !getSettingsButton().contains(event.relatedTarget)
-        ) {
+        const helpBtn = getHelpButton();
+        const settingsBtn = getSettingsButton();
+        const helpUnfocused = helpBtn === null ||
+              (!helpBtn.contains(document.activeElement) &&
+               !elemContainsTarget(helpBtn, event.relatedTarget));
+        const settingsUnfocused = settingsBtn === null ||
+              (!settingsBtn.contains(document.activeElement) &&
+               !elemContainsTarget(settingsBtn, event.relatedTarget));
+        if (helpUnfocused && settingsUnfocused) {
             window.hidePopoverMenus();
         }
     }
 
     if (!isSettingsPage) {
         // We replace the existing "onclick" callback.
-        const settingsButton = getSettingsButton();
-        const settingsMenu = document.getElementById("settings");
+        // These elements must exist, as (outside of the settings page)
+        // `settings.js` is only loaded after the settings button is clicked.
+        const settingsButton = nonnull(getSettingsButton());
+        const settingsMenu = nonnull(document.getElementById("settings"));
         settingsButton.onclick = event => {
-            if (settingsMenu.contains(event.target)) {
+            if (elemContainsTarget(settingsMenu, event.target)) {
                 return;
             }
             event.preventDefault();
             const shouldDisplaySettings = settingsMenu.style.display === "none";
 
-            window.hideAllModals();
+            window.hideAllModals(false);
             if (shouldDisplaySettings) {
                 displaySettings();
             }
         };
         settingsButton.onblur = settingsBlurHandler;
-        settingsButton.querySelector("a").onblur = settingsBlurHandler;
+        // the settings button should always have a link in it
+        nonnull(settingsButton.querySelector("a")).onblur = settingsBlurHandler;
         onEachLazy(settingsMenu.querySelectorAll("input"), el => {
             el.onblur = settingsBlurHandler;
         });
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 748d2ef33c3..76113726894 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -44,6 +44,28 @@ function nonnull(x, msg) {
 }
 
 /**
+ * Assert that the passed value is not undefined, then return it.
+ *
+ * Takes an optional error message argument.
+ *
+ * Must be defined in this file, as it is loaded before all others.
+ *
+ * @template T
+ * @param {T|undefined} x
+ * @param {string=} msg
+ * @returns T
+ */
+// used in other files, not yet used in this one.
+// eslint-disable-next-line no-unused-vars
+function nonundef(x, msg) {
+    if (x === undefined) {
+        throw (msg || "unexpected null value!");
+    } else {
+        return x;
+    }
+}
+
+/**
  * Get a configuration value. If it's not set, get the default.
  *
  * @param {string} settingName
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index f8f670f575b..761282bde7c 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -5,7 +5,7 @@ use std::ops;
 
 use rustc_hir as hir;
 use rustc_lint::builtin::MISSING_DOCS;
-use rustc_middle::lint::LintLevelSource;
+use rustc_middle::lint::{LevelAndSource, LintLevelSource};
 use rustc_session::lint;
 use rustc_span::FileName;
 use serde::Serialize;
@@ -216,7 +216,8 @@ impl DocVisitor<'_> for CoverageCalculator<'_, '_> {
 
                 let has_doc_example = tests.found_tests != 0;
                 let hir_id = DocContext::as_local_hir_id(self.ctx.tcx, i.item_id).unwrap();
-                let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
+                let LevelAndSource { level, src, .. } =
+                    self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
 
                 // In case we have:
                 //
@@ -251,7 +252,7 @@ impl DocVisitor<'_> for CoverageCalculator<'_, '_> {
                 // unless the user had an explicit `allow`.
                 //
                 let should_have_docs = !should_be_ignored
-                    && (level != lint::Level::Allow || matches!(source, LintLevelSource::Default));
+                    && (level != lint::Level::Allow || matches!(src, LintLevelSource::Default));
 
                 if let Some(span) = i.span(self.ctx.tcx) {
                     let filename = span.filename(self.ctx.sess());
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 0fefd13f763..70dbb944d4c 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -6,7 +6,7 @@
 //! - PRIVATE_DOC_TESTS: this lint is **STABLE** and looks for private items with doctests.
 
 use rustc_hir as hir;
-use rustc_middle::lint::LintLevelSource;
+use rustc_middle::lint::{LevelAndSource, LintLevelSource};
 use rustc_session::lint;
 use tracing::debug;
 
@@ -107,11 +107,11 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
     {
         return false;
     }
-    let (level, source) = cx.tcx.lint_level_at_node(
+    let LevelAndSource { level, src, .. } = cx.tcx.lint_level_at_node(
         crate::lint::MISSING_DOC_CODE_EXAMPLES,
         cx.tcx.local_def_id_to_hir_id(def_id),
     );
-    level != lint::Level::Allow || matches!(source, LintLevelSource::Default)
+    level != lint::Level::Allow || matches!(src, LintLevelSource::Default)
 }
 
 pub(crate) fn look_for_tests(cx: &DocContext<'_>, dox: &str, item: &Item) {
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index 44551d75903..fceacb69fb5 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -176,8 +176,7 @@ where
 
         // If the enclosing item has a span coming from a proc macro, then we also don't want to
         // include the example.
-        let enclosing_item_span =
-            tcx.hir().span_with_body(tcx.hir_get_parent_item(ex.hir_id).into());
+        let enclosing_item_span = tcx.hir_span_with_body(tcx.hir_get_parent_item(ex.hir_id).into());
         if enclosing_item_span.from_expansion() {
             trace!("Rejecting expr ({call_span:?}) from macro item: {enclosing_item_span:?}");
             return;
diff --git a/src/llvm-project b/src/llvm-project
-Subproject acaea3d2bb8f351b740db7ebce7d7a40b9e2148
+Subproject a9865ceca08101071e25f3bba97bba8bf0ea971
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 48b5d4da888..7bb5dbee126 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -199,7 +199,7 @@ fn check_simplify_not(cx: &LateContext<'_>, msrv: Msrv, expr: &Expr<'_>) {
         && !expr.span.from_expansion()
         && !inner.span.from_expansion()
         && let Some(suggestion) = simplify_not(cx, msrv, inner)
-        && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
+        && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).level != Level::Allow
     {
         use clippy_utils::sugg::{Sugg, has_enclosing_paren};
         let maybe_par = if let Some(sug) = Sugg::hir_opt(cx, inner) {
@@ -605,7 +605,7 @@ impl<'tcx> NonminimalBoolVisitor<'_, 'tcx> {
                 }
             }
             let nonminimal_bool_lint = |mut suggestions: Vec<_>| {
-                if self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, e.hir_id).0 != Level::Allow {
+                if self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, e.hir_id).level != Level::Allow {
                     suggestions.sort();
                     span_lint_hir_and_then(
                         self.cx,
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index 7885f171461..72953818a70 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -143,7 +143,7 @@ pub(super) fn check<'tcx>(
 
     if cast_from.kind() == cast_to.kind() && !expr.span.in_external_macro(cx.sess().source_map()) {
         if let Some(id) = path_to_local(cast_expr)
-            && !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
+            && !cx.tcx.hir_span(id).eq_ctxt(cast_expr.span)
         {
             // Binding context is different than the identifiers context.
             // Weird macro wizardry could be involved here.
diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
index 7d86bd3e540..c2aac7ca090 100644
--- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
+++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
@@ -53,7 +53,7 @@ declare_lint_pass!(CrateInMacroDef => [CRATE_IN_MACRO_DEF]);
 
 impl EarlyLintPass for CrateInMacroDef {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if let ItemKind::MacroDef(macro_def) = &item.kind
+        if let ItemKind::MacroDef(_, macro_def) = &item.kind
             && item.attrs.iter().any(is_macro_export)
             && let Some(span) = contains_unhygienic_crate_reference(&macro_def.body.tokens)
         {
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 7fa23dad698..39e45163707 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -638,7 +638,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::precedence::PRECEDENCE_INFO,
     crate::precedence::PRECEDENCE_BITS_INFO,
     crate::ptr::CMP_NULL_INFO,
-    crate::ptr::INVALID_NULL_PTR_USAGE_INFO,
     crate::ptr::MUT_FROM_REF_INFO,
     crate::ptr::PTR_ARG_INFO,
     crate::ptr::PTR_EQ_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
index 0031da406f1..de66ead4f42 100644
--- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
@@ -131,6 +131,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
     ("clippy::clone_double_ref", "suspicious_double_ref_op"),
     #[clippy::version = ""]
     ("clippy::cmp_nan", "invalid_nan_comparisons"),
+    #[clippy::version = "CURRENT_RUSTC_VERSION"]
+    ("clippy::invalid_null_ptr_usage", "invalid_null_arguments"),
     #[clippy::version = "1.86.0"]
     ("clippy::double_neg", "double_negations"),
     #[clippy::version = ""]
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 2ae35b40055..c85aca8d04e 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -254,7 +254,7 @@ fn check_hash_peq<'tcx>(
                     |diag| {
                         if let Some(local_def_id) = impl_id.as_local() {
                             let hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id);
-                            diag.span_note(cx.tcx.hir().span(hir_id), "`PartialEq` implemented here");
+                            diag.span_note(cx.tcx.hir_span(hir_id), "`PartialEq` implemented here");
                         }
                     },
                 );
@@ -298,7 +298,7 @@ fn check_ord_partial_ord<'tcx>(
                 span_lint_and_then(cx, DERIVE_ORD_XOR_PARTIAL_ORD, span, mess, |diag| {
                     if let Some(local_def_id) = impl_id.as_local() {
                         let hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id);
-                        diag.span_note(cx.tcx.hir().span(hir_id), "`PartialOrd` implemented here");
+                        diag.span_note(cx.tcx.hir_span(hir_id), "`PartialOrd` implemented here");
                     }
                 });
             }
@@ -324,11 +324,9 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
     // there's a Copy impl for any instance of the adt.
     if !is_copy(cx, ty) {
         if ty_subs.non_erasable_generics().next().is_some() {
-            let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).is_some_and(|impls| {
-                impls.iter().any(|&id| {
-                    matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
+            let has_copy_impl = cx.tcx.local_trait_impls(copy_id).iter().any(|&id| {
+                matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
                                         if ty_adt.did() == adt.did())
-                })
             });
             if !has_copy_impl {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
index 53c24a3faf1..d1a8590c59b 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
@@ -69,7 +69,7 @@ impl EarlyLintPass for DisallowedScriptIdents {
         // Implementation is heavily inspired by the implementation of [`non_ascii_idents`] lint:
         // https://github.com/rust-lang/rust/blob/master/compiler/rustc_lint/src/non_ascii_idents.rs
 
-        let check_disallowed_script_idents = cx.builder.lint_level(DISALLOWED_SCRIPT_IDENTS).0 != Level::Allow;
+        let check_disallowed_script_idents = cx.builder.lint_level(DISALLOWED_SCRIPT_IDENTS).level != Level::Allow;
         if !check_disallowed_script_idents {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index 3008082c232..f6c10da1596 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -13,16 +13,16 @@ use rustc_parse::parser::ForceCollect;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::{FilePathMapping, SourceMap};
-use rustc_span::{FileName, Pos, sym};
+use rustc_span::{FileName, Ident, Pos, sym};
 
 use super::Fragments;
 
-fn get_test_spans(item: &Item, test_attr_spans: &mut Vec<Range<usize>>) {
+fn get_test_spans(item: &Item, ident: Ident, test_attr_spans: &mut Vec<Range<usize>>) {
     test_attr_spans.extend(
         item.attrs
             .iter()
             .find(|attr| attr.has_name(sym::test))
-            .map(|attr| attr.span.lo().to_usize()..item.ident.span.hi().to_usize()),
+            .map(|attr| attr.span.lo().to_usize()..ident.span.hi().to_usize()),
     );
 }
 
@@ -64,10 +64,10 @@ pub fn check(
                     match parser.parse_item(ForceCollect::No) {
                         Ok(Some(item)) => match &item.kind {
                             ItemKind::Fn(box Fn {
-                                sig, body: Some(block), ..
-                            }) if item.ident.name == sym::main => {
+                                ident, sig, body: Some(block), ..
+                            }) if ident.name == sym::main => {
                                 if !ignore {
-                                    get_test_spans(&item, &mut test_attr_spans);
+                                    get_test_spans(&item, *ident, &mut test_attr_spans);
                                 }
                                 let is_async = matches!(sig.header.coroutine_kind, Some(CoroutineKind::Async { .. }));
                                 let returns_nothing = match &sig.decl.output {
@@ -85,10 +85,10 @@ pub fn check(
                                 }
                             },
                             // Another function was found; this case is ignored for needless_doctest_main
-                            ItemKind::Fn(box Fn { .. }) => {
+                            ItemKind::Fn(fn_) => {
                                 eligible = false;
                                 if !ignore {
-                                    get_test_spans(&item, &mut test_attr_spans);
+                                    get_test_spans(&item, fn_.ident, &mut test_attr_spans);
                                 }
                             },
                             // Tests with one of these items are ignored
diff --git a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
index 1dac7b971f9..ce551a64d99 100644
--- a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
+++ b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
@@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind};
 use rustc_errors::MultiSpan;
 use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
+use rustc_middle::lint::LevelAndSource;
 use rustc_session::impl_lint_pass;
 use rustc_span::{FileName, Span};
 use std::collections::BTreeMap;
@@ -45,11 +46,10 @@ declare_clippy_lint! {
     "file loaded as module multiple times"
 }
 
-#[derive(PartialOrd, Ord, PartialEq, Eq)]
 struct Modules {
     local_path: PathBuf,
     spans: Vec<Span>,
-    lint_levels: Vec<Level>,
+    lint_levels: Vec<LevelAndSource>,
 }
 
 #[derive(Default)]
@@ -63,7 +63,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);
 
 impl EarlyLintPass for DuplicateMod {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind
+        if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind
             && let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)
             && let Some(local_path) = real.into_local_path()
             && let Ok(absolute_path) = local_path.canonicalize()
@@ -95,11 +95,11 @@ impl EarlyLintPass for DuplicateMod {
                 .iter()
                 .zip(lint_levels)
                 .filter_map(|(span, lvl)| {
-                    if let Some(id) = lvl.get_expectation_id() {
+                    if let Some(id) = lvl.lint_id {
                         cx.fulfill_expectation(id);
                     }
 
-                    (!matches!(lvl, Level::Allow | Level::Expect(_))).then_some(*span)
+                    (!matches!(lvl.level, Level::Allow | Level::Expect)).then_some(*span)
                 })
                 .collect();
 
diff --git a/src/tools/clippy/clippy_lints/src/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
index 80c2b03c41c..c67dcd3c82b 100644
--- a/src/tools/clippy/clippy_lints/src/empty_line_after.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
@@ -8,8 +8,7 @@ use rustc_errors::{Applicability, Diag, SuggestionStyle};
 use rustc_lexer::TokenKind;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::kw;
-use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol};
+use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol, kw};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -375,21 +374,23 @@ impl EmptyLineAfter {
         &mut self,
         cx: &EarlyContext<'_>,
         kind: &ItemKind,
-        ident: &Ident,
+        ident: Option<Ident>,
         span: Span,
         attrs: &[Attribute],
         id: NodeId,
     ) {
         self.items.push(ItemInfo {
             kind: kind.descr(),
-            name: ident.name,
-            span: if span.contains(ident.span) {
+            // FIXME: this `sym::empty` can be leaked, see
+            // https://github.com/rust-lang/rust/pull/138740#discussion_r2021979899
+            name: if let Some(ident) = ident { ident.name } else { kw::Empty },
+            span: if let Some(ident) = ident {
                 span.with_hi(ident.span.hi())
             } else {
                 span.with_hi(span.lo())
             },
             mod_items: match kind {
-                ItemKind::Mod(_, ModKind::Loaded(items, _, _, _)) => items
+                ItemKind::Mod(_, _, ModKind::Loaded(items, _, _, _)) => items
                     .iter()
                     .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
                     .map(|i| i.id)
@@ -471,7 +472,7 @@ impl EarlyLintPass for EmptyLineAfter {
         self.check_item_kind(
             cx,
             &item.kind.clone().into(),
-            &item.ident,
+            item.kind.ident(),
             item.span,
             &item.attrs,
             item.id,
@@ -482,7 +483,7 @@ impl EarlyLintPass for EmptyLineAfter {
         self.check_item_kind(
             cx,
             &item.kind.clone().into(),
-            &item.ident,
+            item.kind.ident(),
             item.span,
             &item.attrs,
             item.id,
@@ -490,6 +491,6 @@ impl EarlyLintPass for EmptyLineAfter {
     }
 
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        self.check_item_kind(cx, &item.kind, &item.ident, item.span, &item.attrs, item.id);
+        self.check_item_kind(cx, &item.kind, item.kind.ident(), item.span, &item.attrs, item.id);
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
index 743ec5b9ea7..7d87f04fef9 100644
--- a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
@@ -74,10 +74,9 @@ declare_lint_pass!(EmptyWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS, EMPTY_ENUM
 
 impl EarlyLintPass for EmptyWithBrackets {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        let span_after_ident = item.span.with_lo(item.ident.span.hi());
-
-        if let ItemKind::Struct(var_data, _) = &item.kind
+        if let ItemKind::Struct(ident, var_data, _) = &item.kind
             && has_brackets(var_data)
+            && let span_after_ident = item.span.with_lo(ident.span.hi())
             && has_no_fields(cx, var_data, span_after_ident)
         {
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index de0fc2b1bf4..e248f08789b 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -120,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
                 cx,
                 BOXED_LOCAL,
                 node,
-                cx.tcx.hir().span(node),
+                cx.tcx.hir_span(node),
                 "local variable doesn't need to be boxed here",
             );
         }
diff --git a/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs b/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs
index ba2b37fbf11..aae8291905d 100644
--- a/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs
+++ b/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs
@@ -51,7 +51,7 @@ declare_lint_pass!(FieldScopedVisibilityModifiers => [FIELD_SCOPED_VISIBILITY_MO
 
 impl EarlyLintPass for FieldScopedVisibilityModifiers {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        let ItemKind::Struct(ref st, _) = item.kind else {
+        let ItemKind::Struct(_, ref st, _) = item.kind else {
             return;
         };
         for field in st.fields() {
diff --git a/src/tools/clippy/clippy_lints/src/format_push_string.rs b/src/tools/clippy/clippy_lints/src/format_push_string.rs
index 68cc50f3939..b64d608c0c7 100644
--- a/src/tools/clippy/clippy_lints/src/format_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/format_push_string.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher;
 use clippy_utils::ty::is_type_lang_item;
-use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource};
+use rustc_hir::{AssignOpKind, Expr, ExprKind, LangItem, MatchSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
@@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString {
                     return;
                 }
             },
-            ExprKind::AssignOp(op, left, arg) if op.node == BinOpKind::Add && is_string(cx, left) => arg,
+            ExprKind::AssignOp(op, left, arg) if op.node == AssignOpKind::AddAssign && is_string(cx, left) => arg,
             _ => return,
         };
         if is_format(cx, arg) {
diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
index 41d2b18803d..185fc2aa2d4 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
@@ -5,7 +5,7 @@ use clippy_utils::source::snippet_with_context;
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind};
+use rustc_hir::{AssignOpKind, BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{IntTy, Ty, UintTy};
 use rustc_session::declare_lint_pass;
@@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {
             && ex.span.ctxt() == ctxt
             && expr1.span.ctxt() == ctxt
             && clippy_utils::SpanlessEq::new(cx).eq_expr(l, target)
-            && BinOpKind::Add == op1.node
+            && AssignOpKind::AddAssign == op1.node
             && let ExprKind::Lit(lit) = value.kind
             && let LitKind::Int(Pu128(1), LitIntType::Unsuffixed) = lit.node
             && block.expr.is_none()
diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
index cbc3e2ccd5b..5d7d3ae3f24 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
@@ -8,7 +8,7 @@ use clippy_utils::{
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath};
+use rustc_hir::{AssignOpKind, BinOp, BinOpKind, Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
@@ -366,7 +366,7 @@ fn subtracts_one<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a Exp
     match peel_blocks_with_stmt(expr).kind {
         ExprKind::AssignOp(ref op1, target, value) => {
             // Check if literal being subtracted is one
-            (BinOpKind::Sub == op1.node && is_integer_literal(value, 1)).then_some(target)
+            (AssignOpKind::SubAssign == op1.node && is_integer_literal(value, 1)).then_some(target)
         },
         ExprKind::Assign(target, value, _) => {
             if let ExprKind::Binary(ref op1, left1, right1) = value.kind
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 d53e139de01..989997d69f7 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<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> {
             {
                 use_info
                     .index_use
-                    .push((index_value, cx.tcx.hir().span(parent_expr.hir_id)));
+                    .push((index_value, cx.tcx.hir_span(parent_expr.hir_id)));
                 return;
             }
 
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index cc3d972f017..3fe3cd67e16 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -408,9 +408,9 @@ mod zombie_processes;
 
 use clippy_config::{Conf, get_configuration_metadata, sanitize_explanation};
 use clippy_utils::macros::FormatArgsStorage;
-use utils::attr_collector::{AttrCollector, AttrStorage};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_lint::{Lint, LintId};
+use utils::attr_collector::{AttrCollector, AttrStorage};
 
 /// Register all pre expansion lints
 ///
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 5afcf51167d..a24dd44790e 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
@@ -85,10 +85,10 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
         if bk == ty::BorrowKind::Mutable {
             if let PlaceBase::Local(id) = cmt.place.base {
                 if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {
-                    self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id));
+                    self.span_low = Some(self.cx.tcx.hir_span(diag_expr_id));
                 }
                 if Some(id) == self.hir_id_high && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {
-                    self.span_high = Some(self.cx.tcx.hir().span(diag_expr_id));
+                    self.span_high = Some(self.cx.tcx.hir_span(diag_expr_id));
                 }
             }
         }
@@ -97,10 +97,10 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
     fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
         if let PlaceBase::Local(id) = cmt.place.base {
             if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {
-                self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id));
+                self.span_low = Some(self.cx.tcx.hir_span(diag_expr_id));
             }
             if Some(id) == self.hir_id_high && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {
-                self.span_high = Some(self.cx.tcx.hir().span(diag_expr_id));
+                self.span_high = Some(self.cx.tcx.hir_span(diag_expr_id));
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs
index a5185d38e7c..3c6fbef2bda 100644
--- a/src/tools/clippy/clippy_lints/src/loops/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs
@@ -3,7 +3,9 @@ use clippy_utils::{get_parent_expr, is_integer_const, path_to_local, path_to_loc
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_expr, walk_local};
-use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind};
+use rustc_hir::{
+    AssignOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind
+};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty};
@@ -58,7 +60,7 @@ impl<'tcx> Visitor<'tcx> for IncrementVisitor<'_, 'tcx> {
                 match parent.kind {
                     ExprKind::AssignOp(op, lhs, rhs) => {
                         if lhs.hir_id == expr.hir_id {
-                            *state = if op.node == BinOpKind::Add
+                            *state = if op.node == AssignOpKind::AddAssign
                                 && is_integer_const(self.cx, rhs, 1)
                                 && *state == IncrementVisitorVarState::Initial
                                 && self.depth == 0
diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
index 006addb987f..df6e85611fb 100644
--- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
@@ -253,7 +253,7 @@ impl<'tcx> LateLintPass<'tcx> for ExprMetavarsInUnsafe {
                 // Remove the syntax context to hide "in this macro invocation" in the diagnostic.
                 // The invocation doesn't matter. Also we want to dedupe by the unsafe block and not by anything
                 // related to the callsite.
-                let span = cx.tcx.hir().span(id);
+                let span = cx.tcx.hir_span(id);
 
                 (id, Span::new(span.lo(), span.hi(), SyntaxContext::root(), None))
             })
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index b712b351d06..98ad1f6a160 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -153,9 +153,15 @@ impl LateLintPass<'_> for MacroUseImports {
                     [] | [_] => return,
                     [root, item] => {
                         if !check_dup.contains(&(*item).to_string()) {
-                            used.entry(((*root).to_string(), span, hir_id))
-                                .or_insert_with(Vec::new)
-                                .push((*item).to_string());
+                            used.entry((
+                                (*root).to_string(),
+                                span,
+                                hir_id.local_id,
+                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
+                            ))
+                            .or_insert_with(|| (vec![], hir_id))
+                            .0
+                            .push((*item).to_string());
                             check_dup.push((*item).to_string());
                         }
                     },
@@ -171,15 +177,27 @@ impl LateLintPass<'_> for MacroUseImports {
                                     }
                                 })
                                 .collect::<Vec<_>>();
-                            used.entry(((*root).to_string(), span, hir_id))
-                                .or_insert_with(Vec::new)
-                                .push(filtered.join("::"));
+                            used.entry((
+                                (*root).to_string(),
+                                span,
+                                hir_id.local_id,
+                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
+                            ))
+                            .or_insert_with(|| (vec![], hir_id))
+                            .0
+                            .push(filtered.join("::"));
                             check_dup.extend(filtered);
                         } else {
                             let rest = rest.to_vec();
-                            used.entry(((*root).to_string(), span, hir_id))
-                                .or_insert_with(Vec::new)
-                                .push(rest.join("::"));
+                            used.entry((
+                                (*root).to_string(),
+                                span,
+                                hir_id.local_id,
+                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
+                            ))
+                            .or_insert_with(|| (vec![], hir_id))
+                            .0
+                            .push(rest.join("::"));
                             check_dup.extend(rest.iter().map(ToString::to_string));
                         }
                     },
@@ -190,7 +208,7 @@ impl LateLintPass<'_> for MacroUseImports {
         // If mac_refs is not empty we have encountered an import we could not handle
         // such as `std::prelude::v1::foo` or some other macro that expands to an import.
         if self.mac_refs.is_empty() {
-            for ((root, span, hir_id), path) in used {
+            for ((root, span, ..), (path, hir_id)) in used {
                 let import = if let [single] = &path[..] {
                     format!("{root}::{single}")
                 } else {
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index ab53ad98572..9bbef8da0a4 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -246,7 +246,6 @@ fn emit_redundant_guards<'tcx>(
 fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     for_each_expr_without_closures(expr, |expr| {
         if match expr.kind {
-            ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat(),
             ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => {
                 // Allow ctors
                 matches!(cx.qpath_res(&qpath, c.hir_id), Res::Def(DefKind::Ctor(..), ..))
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index 693d1a8dd76..09ee6f7037c 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -329,7 +329,7 @@ fn used_underscore_binding<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
     let name = ident.name.as_str();
     if name.starts_with('_')
         && !name.starts_with("__")
-        && let definition_span = cx.tcx.hir().span(definition_hir_id)
+        && let definition_span = cx.tcx.hir_span(definition_hir_id)
         && !definition_span.from_expansion()
         && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id])
     {
diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
index d78299fe08b..cdd6f4e5b03 100644
--- a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
@@ -10,7 +10,7 @@ use rustc_ast::{LitKind, RangeLimits};
 use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::unhash::UnindexMap;
 use rustc_errors::{Applicability, Diag};
-use rustc_hir::{BinOp, Block, Body, Expr, ExprKind, UnOp};
+use rustc_hir::{BinOpKind, Block, Body, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
@@ -97,7 +97,7 @@ enum LengthComparison {
 ///
 /// E.g. for `v.len() > 5` this returns `Some((LengthComparison::IntLessThanLength, 5, v.len()))`
 fn len_comparison<'hir>(
-    bin_op: BinOp,
+    bin_op: BinOpKind,
     left: &'hir Expr<'hir>,
     right: &'hir Expr<'hir>,
 ) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> {
@@ -112,7 +112,7 @@ fn len_comparison<'hir>(
 
     // normalize comparison, `v.len() > 4` becomes `4 < v.len()`
     // this simplifies the logic a bit
-    let (op, left, right) = normalize_comparison(bin_op.node, left, right)?;
+    let (op, left, right) = normalize_comparison(bin_op, left, right)?;
     match (op, left.kind, right.kind) {
         (Rel::Lt, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanLength, left as usize, right)),
         (Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, right as usize, left)),
@@ -138,7 +138,7 @@ fn assert_len_expr<'hir>(
         && let ExprKind::Unary(UnOp::Not, condition) = &cond.kind
         && let ExprKind::Binary(bin_op, left, right) = &condition.kind
 
-        && let Some((cmp, asserted_len, slice_len)) = len_comparison(*bin_op, left, right)
+        && let Some((cmp, asserted_len, slice_len)) = len_comparison(bin_op.node, left, right)
         && let ExprKind::MethodCall(method, recv, [], _) = &slice_len.kind
         && cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice()
         && method.ident.name == sym::len
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 be728e6c8b7..fbd287f5285 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
@@ -261,10 +261,11 @@ fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> St
         | ExprKind::Assign(..)
         | ExprKind::Index(..)
         | ExprKind::Repeat(_, _)
-        | ExprKind::Struct(_, _, _) => {
+        | ExprKind::Struct(_, _, _)
+        | ExprKind::AssignOp(_, _, _) => {
             walk_expr(vis, expr);
         },
-        ExprKind::Binary(op, _, _) | ExprKind::AssignOp(op, _, _) => {
+        ExprKind::Binary(op, _, _) => {
             if op.node == BinOpKind::And || op.node == BinOpKind::Or {
                 // x && y and x || y always evaluate x first, so these are
                 // strictly sequenced.
diff --git a/src/tools/clippy/clippy_lints/src/module_style.rs b/src/tools/clippy/clippy_lints/src/module_style.rs
index 676d608eb31..7287193326f 100644
--- a/src/tools/clippy/clippy_lints/src/module_style.rs
+++ b/src/tools/clippy/clippy_lints/src/module_style.rs
@@ -73,8 +73,8 @@ impl_lint_pass!(ModStyle => [MOD_MODULE_FILES, SELF_NAMED_MODULE_FILES]);
 
 impl EarlyLintPass for ModStyle {
     fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
-        if cx.builder.lint_level(MOD_MODULE_FILES).0 == Level::Allow
-            && cx.builder.lint_level(SELF_NAMED_MODULE_FILES).0 == Level::Allow
+        if cx.builder.lint_level(MOD_MODULE_FILES).level == Level::Allow
+            && cx.builder.lint_level(SELF_NAMED_MODULE_FILES).level == Level::Allow
         {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
index 0e1980a6acb..4b32ba83b32 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
@@ -39,7 +39,7 @@ declare_lint_pass!(MultipleBoundLocations => [MULTIPLE_BOUND_LOCATIONS]);
 
 impl EarlyLintPass for MultipleBoundLocations {
     fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, _: Span, _: NodeId) {
-        if let FnKind::Fn(_, _, _, Fn { generics, .. }) = kind
+        if let FnKind::Fn(_, _, Fn { generics, .. }) = kind
             && !generics.params.is_empty()
             && !generics.where_clause.predicates.is_empty()
         {
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 576bb27b254..b61061d076b 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
@@ -280,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
                             diag.span_suggestion(
                                 sp,
                                 "consider changing to".to_string(),
-                                format!("&{}", snippet(cx, cx.tcx.hir().span(inner_ty.ty.hir_id), "_"),),
+                                format!("&{}", snippet(cx, cx.tcx.hir_span(inner_ty.ty.hir_id), "_"),),
                                 Applicability::Unspecified,
                             );
                             if cx.effective_visibilities.is_exported(*fn_def_id) {
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 55ca875edce..978fde33d51 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -198,7 +198,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                 // Dereference suggestion
                 let sugg = |diag: &mut Diag<'_, ()>| {
                     if let ty::Adt(def, ..) = ty.kind() {
-                        if let Some(span) = cx.tcx.hir().span_if_local(def.did()) {
+                        if let Some(span) = cx.tcx.hir_span_if_local(def.did()) {
                             if type_allowed_to_implement_copy(
                                 cx.tcx,
                                 cx.param_env,
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index f0ee613791f..1e469c3b63a 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -97,14 +97,14 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                         {
                             if self.impling_types.is_none() {
                                 let mut impls = HirIdSet::default();
-                                cx.tcx.for_each_impl(default_trait_id, |d| {
+                                for &d in cx.tcx.local_trait_impls(default_trait_id) {
                                     let ty = cx.tcx.type_of(d).instantiate_identity();
                                     if let Some(ty_def) = ty.ty_adt_def() {
                                         if let Some(local_def_id) = ty_def.did().as_local() {
                                             impls.insert(cx.tcx.local_def_id_to_hir_id(local_def_id));
                                         }
                                     }
-                                });
+                                }
                                 self.impling_types = Some(impls);
                             }
 
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index 594101427f5..a78a342d4fe 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -335,9 +335,12 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
             return;
         }
         match &expr.kind {
-            hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
+            hir::ExprKind::Binary(op, lhs, rhs) => {
                 self.manage_bin_ops(cx, expr, op.node, lhs, rhs);
             },
+            hir::ExprKind::AssignOp(op, lhs, rhs) => {
+                self.manage_bin_ops(cx, expr, op.node.into(), lhs, rhs);
+            },
             hir::ExprKind::MethodCall(ps, receiver, args, _) => {
                 self.manage_method_call(args, cx, expr, ps, receiver);
             },
@@ -354,7 +357,7 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
 
         let body_owner_kind = cx.tcx.hir_body_owner_kind(body_owner_def_id);
         if let hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) = body_owner_kind {
-            let body_span = cx.tcx.hir().span_with_body(body_owner);
+            let body_span = cx.tcx.hir_span_with_body(body_owner);
             if let Some(span) = self.const_span
                 && span.contains(body_span)
             {
@@ -366,7 +369,7 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
 
     fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
         let body_owner = cx.tcx.hir_body_owner(body.id());
-        let body_span = cx.tcx.hir().span(body_owner);
+        let body_span = cx.tcx.hir_span(body_owner);
         if let Some(span) = self.const_span
             && span.contains(body_span)
         {
diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs
index f758d08d366..d32c062cf56 100644
--- a/src/tools/clippy/clippy_lints/src/operators/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs
@@ -913,9 +913,10 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
                 );
             },
             ExprKind::AssignOp(op, lhs, rhs) => {
-                self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
-                misrefactored_assign_op::check(cx, e, op.node, lhs, rhs);
-                modulo_arithmetic::check(cx, e, op.node, lhs, rhs, false);
+                let bin_op = op.node.into();
+                self.arithmetic_context.check_binary(cx, e, bin_op, lhs, rhs);
+                misrefactored_assign_op::check(cx, e, bin_op, lhs, rhs);
+                modulo_arithmetic::check(cx, e, bin_op, lhs, rhs, false);
             },
             ExprKind::Assign(lhs, rhs, _) => {
                 assign_op_pattern::check(cx, e, lhs, rhs);
diff --git a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
index c261fd9bd9c..96c9775e292 100644
--- a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
@@ -73,7 +73,7 @@ impl Context {
 
         match cx.tcx.hir_body_owner_kind(body_owner_def_id) {
             hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const { .. } => {
-                let body_span = cx.tcx.hir().span_with_body(body_owner);
+                let body_span = cx.tcx.hir_span_with_body(body_owner);
 
                 if let Some(span) = self.const_span {
                     if span.contains(body_span) {
@@ -88,7 +88,7 @@ impl Context {
 
     pub fn body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
         let body_owner = cx.tcx.hir_body_owner(body.id());
-        let body_span = cx.tcx.hir().span_with_body(body_owner);
+        let body_span = cx.tcx.hir_span_with_body(body_owner);
 
         if let Some(span) = self.const_span {
             if span.contains(body_span) {
diff --git a/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs b/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs
index 267e2067e10..cda752d003f 100644
--- a/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs
+++ b/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs
@@ -41,7 +41,7 @@ declare_lint_pass!(PartialPubFields => [PARTIAL_PUB_FIELDS]);
 
 impl EarlyLintPass for PartialPubFields {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        let ItemKind::Struct(ref st, _) = item.kind else {
+        let ItemKind::Struct(_, ref st, _) = item.kind else {
             return;
         };
 
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 55f1ece0559..50ef56db167 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -127,29 +127,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// This lint checks for invalid usages of `ptr::null`.
-    ///
-    /// ### Why is this bad?
-    /// This causes undefined behavior.
-    ///
-    /// ### Example
-    /// ```ignore
-    /// // Undefined behavior
-    /// unsafe { std::slice::from_raw_parts(ptr::null(), 0); }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```ignore
-    /// unsafe { std::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0); }
-    /// ```
-    #[clippy::version = "1.53.0"]
-    pub INVALID_NULL_PTR_USAGE,
-    correctness,
-    "invalid usage of a null pointer, suggesting `NonNull::dangling()` instead"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Use `std::ptr::eq` when applicable
     ///
     /// ### Why is this bad?
@@ -177,7 +154,7 @@ declare_clippy_lint! {
     "use `std::ptr::eq` when comparing raw pointers"
 }
 
-declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, INVALID_NULL_PTR_USAGE, PTR_EQ]);
+declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, PTR_EQ]);
 
 impl<'tcx> LateLintPass<'tcx> for Ptr {
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
@@ -301,54 +278,6 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
                 format!("{non_null_path_snippet}.is_null()"),
                 Applicability::MachineApplicable,
             );
-        } else {
-            check_invalid_ptr_usage(cx, expr);
-        }
-    }
-}
-
-fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-    if let ExprKind::Call(fun, args) = expr.kind
-        && let ExprKind::Path(ref qpath) = fun.kind
-        && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
-        && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id)
-    {
-        // TODO: `ptr_slice_from_raw_parts` and its mutable variant should probably still be linted
-        // conditionally based on how the return value is used, but not universally like the other
-        // functions since there are valid uses for null slice pointers.
-        //
-        // See: https://github.com/rust-lang/rust-clippy/pull/13452/files#r1773772034
-
-        // `arg` positions where null would cause U.B.
-        let arg_indices: &[_] = match name {
-            sym::ptr_read
-            | sym::ptr_read_unaligned
-            | sym::ptr_read_volatile
-            | sym::ptr_replace
-            | sym::ptr_write
-            | sym::ptr_write_bytes
-            | sym::ptr_write_unaligned
-            | sym::ptr_write_volatile
-            | sym::slice_from_raw_parts
-            | sym::slice_from_raw_parts_mut => &[0],
-            sym::ptr_copy | sym::ptr_copy_nonoverlapping | sym::ptr_swap | sym::ptr_swap_nonoverlapping => &[0, 1],
-            _ => return,
-        };
-
-        for &arg_idx in arg_indices {
-            if let Some(arg) = args.get(arg_idx).filter(|arg| is_null_path(cx, arg))
-                && let Some(std_or_core) = std_or_core(cx)
-            {
-                span_lint_and_sugg(
-                    cx,
-                    INVALID_NULL_PTR_USAGE,
-                    arg.span,
-                    "pointer must be non-null",
-                    "change this to",
-                    format!("{std_or_core}::ptr::NonNull::dangling().as_ptr()"),
-                    Applicability::MachineApplicable,
-                );
-            }
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs
index c6e6e782f9d..6a79cae32a5 100644
--- a/src/tools/clippy/clippy_lints/src/raw_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs
@@ -138,7 +138,7 @@ impl RawStrings {
                     );
                 },
             );
-            if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
+            if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS).level, rustc_lint::Allow) {
                 return;
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 4cb73df8b48..d8e8ead2912 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -404,7 +404,7 @@ fn check_final_expr<'tcx>(
             match cx.tcx.hir_attrs(expr.hir_id) {
                 [] => {},
                 [attr] => {
-                    if matches!(Level::from_attr(attr), Some(Level::Expect(_)))
+                    if matches!(Level::from_attr(attr), Some((Level::Expect, _)))
                         && let metas = attr.meta_item_list()
                         && let Some(lst) = metas
                         && let [MetaItemInner::MetaItem(meta_item), ..] = lst.as_slice()
diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs
index ee282ee1dfb..b82ddedd56c 100644
--- a/src/tools/clippy/clippy_lints/src/shadow.rs
+++ b/src/tools/clippy/clippy_lints/src/shadow.rs
@@ -218,7 +218,7 @@ fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span)
         },
     };
     span_lint_and_then(cx, lint, span, msg, |diag| {
-        diag.span_note(cx.tcx.hir().span(shadowed), "previous binding is here");
+        diag.span_note(cx.tcx.hir_span(shadowed), "previous binding is here");
     });
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
index e9db7c9d031..76874cc3420 100644
--- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
+++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
@@ -79,10 +79,11 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
             if apa.counter <= 1 || !apa.has_expensive_expr_after_last_attr {
                 continue;
             }
+            let first_bind_ident = apa.first_bind_ident.unwrap();
             span_lint_and_then(
                 cx,
                 SIGNIFICANT_DROP_TIGHTENING,
-                apa.first_bind_ident.span,
+                first_bind_ident.span,
                 "temporary with significant `Drop` can be early dropped",
                 |diag| {
                     match apa.counter {
@@ -91,13 +92,13 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
                             let indent = " ".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0));
                             let init_method = snippet(cx, apa.first_method_span, "..");
                             let usage_method = snippet(cx, apa.last_method_span, "..");
-                            let stmt = if apa.last_bind_ident == Ident::empty() {
-                                format!("\n{indent}{init_method}.{usage_method};")
-                            } else {
+                            let stmt = if let Some(last_bind_ident) = apa.last_bind_ident {
                                 format!(
                                     "\n{indent}let {} = {init_method}.{usage_method};",
-                                    snippet(cx, apa.last_bind_ident.span, ".."),
+                                    snippet(cx, last_bind_ident.span, ".."),
                                 )
+                            } else {
+                                format!("\n{indent}{init_method}.{usage_method};")
                             };
 
                             diag.multipart_suggestion_verbose(
@@ -113,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
                                 format!(
                                     "\n{}drop({});",
                                     " ".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0)),
-                                    apa.first_bind_ident
+                                    first_bind_ident
                                 ),
                                 Applicability::MaybeIncorrect,
                             );
@@ -124,7 +125,7 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
                         apa.first_block_span,
                         format!(
                             "temporary `{}` is currently being dropped at the end of its contained scope",
-                            apa.first_bind_ident
+                            first_bind_ident
                         ),
                     );
                 },
@@ -283,7 +284,7 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
                 let mut apa = AuxParamsAttr {
                     first_block_hir_id: self.ap.curr_block_hir_id,
                     first_block_span: self.ap.curr_block_span,
-                    first_bind_ident: ident,
+                    first_bind_ident: Some(ident),
                     first_method_span: {
                         let expr_or_init = expr_or_init(self.cx, expr);
                         if let hir::ExprKind::MethodCall(_, local_expr, _, span) = expr_or_init.kind {
@@ -307,7 +308,7 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
                 match self.ap.curr_stmt.kind {
                     hir::StmtKind::Let(local) => {
                         if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind {
-                            apa.last_bind_ident = ident;
+                            apa.last_bind_ident = Some(ident);
                         }
                         if let Some(local_init) = local.init
                             && let hir::ExprKind::MethodCall(_, _, _, span) = local_init.kind
@@ -373,7 +374,7 @@ struct AuxParamsAttr {
     first_block_span: Span,
     /// The binding or variable that references the initial construction of the type marked with
     /// `#[has_significant_drop]`.
-    first_bind_ident: Ident,
+    first_bind_ident: Option<Ident>,
     /// Similar to `init_bind_ident` but encompasses the right-hand method call.
     first_method_span: Span,
     /// Similar to `init_bind_ident` but encompasses the whole contained statement.
@@ -381,7 +382,7 @@ struct AuxParamsAttr {
 
     /// The last visited binding or variable span within a block that had any referenced inner type
     /// marked with `#[has_significant_drop]`.
-    last_bind_ident: Ident,
+    last_bind_ident: Option<Ident>,
     /// Similar to `last_bind_span` but encompasses the right-hand method call.
     last_method_span: Span,
     /// Similar to `last_bind_span` but encompasses the whole contained statement.
@@ -395,10 +396,10 @@ impl Default for AuxParamsAttr {
             has_expensive_expr_after_last_attr: false,
             first_block_hir_id: HirId::INVALID,
             first_block_span: DUMMY_SP,
-            first_bind_ident: Ident::empty(),
+            first_bind_ident: None,
             first_method_span: DUMMY_SP,
             first_stmt_span: DUMMY_SP,
-            last_bind_ident: Ident::empty(),
+            last_bind_ident: None,
             last_method_span: DUMMY_SP,
             last_stmt_span: DUMMY_SP,
         }
@@ -413,7 +414,7 @@ fn dummy_stmt_expr<'any>(expr: &'any hir::Expr<'any>) -> hir::Stmt<'any> {
     }
 }
 
-fn has_drop(expr: &hir::Expr<'_>, first_bind_ident: &Ident, lcx: &LateContext<'_>) -> bool {
+fn has_drop(expr: &hir::Expr<'_>, first_bind_ident: &Option<Ident>, lcx: &LateContext<'_>) -> bool {
     if let hir::ExprKind::Call(fun, [first_arg]) = expr.kind
         && let hir::ExprKind::Path(hir::QPath::Resolved(_, fun_path)) = &fun.kind
         && let Res::Def(DefKind::Fn, did) = fun_path.res
@@ -422,6 +423,7 @@ fn has_drop(expr: &hir::Expr<'_>, first_bind_ident: &Ident, lcx: &LateContext<'_
         let has_ident = |local_expr: &hir::Expr<'_>| {
             if let hir::ExprKind::Path(hir::QPath::Resolved(_, arg_path)) = &local_expr.kind
                 && let [first_arg_ps, ..] = arg_path.segments
+                && let Some(first_bind_ident) = first_bind_ident
                 && &first_arg_ps.ident == first_bind_ident
             {
                 true
diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
index 1a2fb77acc1..64891743dc6 100644
--- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
@@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for SingleCallFn {
         for (&def_id, usage) in &self.def_id_to_usage {
             if let CallState::Once { call_site } = *usage
                 && let fn_hir_id = cx.tcx.local_def_id_to_hir_id(def_id)
-                && let fn_span = cx.tcx.hir().span_with_body(fn_hir_id)
+                && let fn_span = cx.tcx.hir_span_with_body(fn_hir_id)
                 && !self.is_function_allowed(cx, def_id, fn_hir_id, fn_span)
             {
                 span_lint_hir_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
index fa082453504..35f80b2acda 100644
--- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
@@ -174,11 +174,11 @@ impl SingleComponentPathImports {
         }
 
         match &item.kind {
-            ItemKind::Mod(_, ModKind::Loaded(items, ..)) => {
+            ItemKind::Mod(_, _, ModKind::Loaded(items, ..)) => {
                 self.check_mod(items);
             },
-            ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => {
-                macros.push(item.ident.name);
+            ItemKind::MacroDef(ident, MacroDef { macro_rules: true, .. }) => {
+                macros.push(ident.name);
             },
             ItemKind::Use(use_tree) => {
                 let segments = &use_tree.prefix.segments;
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 fb426e91bf0..56bd8fefdb4 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -5,6 +5,7 @@ use core::ops::ControlFlow;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -56,8 +57,27 @@ declare_lint_pass!(SuspiciousImpl => [SUSPICIOUS_ARITHMETIC_IMPL, SUSPICIOUS_OP_
 
 impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
-        if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind
-            && let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop.node)
+        match expr.kind {
+            hir::ExprKind::Binary(op, _, _) => {
+                self.check_expr_inner(cx, expr, op.node, op.span);
+            }
+            hir::ExprKind::AssignOp(op, _, _) => {
+                self.check_expr_inner(cx, expr, op.node.into(), op.span);
+            }
+            _ => {}
+        }
+    }
+}
+
+impl<'tcx> SuspiciousImpl {
+    fn check_expr_inner(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        expr: &'tcx hir::Expr<'_>,
+        binop: hir::BinOpKind,
+        span: Span,
+    ) {
+        if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop)
             && let Some(binop_trait_id) = cx.tcx.lang_items().get(binop_trait_lang)
             && let Some(op_assign_trait_id) = cx.tcx.lang_items().get(op_assign_trait_lang)
 
@@ -82,10 +102,10 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
             span_lint(
                 cx,
                 lint,
-                binop.span,
+                span,
                 format!(
                     "suspicious use of `{}` in `{}` impl",
-                    binop.node.as_str(),
+                    binop.as_str(),
                     cx.tcx.item_name(trait_id)
                 ),
             );
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index 7176d533b61..0337b74b4b1 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir::intravisit::{Visitor, walk_expr};
 
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
+use rustc_hir::{AssignOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
@@ -307,7 +307,7 @@ fn extract_sides_of_xor_assign<'a, 'hir>(
     if let StmtKind::Semi(expr) = stmt.kind
         && let ExprKind::AssignOp(
             Spanned {
-                node: BinOpKind::BitXor,
+                node: AssignOpKind::BitXorAssign,
                 ..
             },
             lhs,
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 6023ae9cc7b..eba576392eb 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -321,17 +321,18 @@ pub fn eq_local_kind(l: &LocalKind, r: &LocalKind) -> bool {
 }
 
 pub fn eq_item<K>(l: &Item<K>, r: &Item<K>, mut eq_kind: impl FnMut(&K, &K) -> bool) -> bool {
-    eq_id(l.ident, r.ident) && over(&l.attrs, &r.attrs, eq_attr) && eq_vis(&l.vis, &r.vis) && eq_kind(&l.kind, &r.kind)
+    over(&l.attrs, &r.attrs, eq_attr) && eq_vis(&l.vis, &r.vis) && eq_kind(&l.kind, &r.kind)
 }
 
 #[expect(clippy::similar_names, clippy::too_many_lines)] // Just a big match statement
 pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
     use ItemKind::*;
     match (l, r) {
-        (ExternCrate(l), ExternCrate(r)) => l == r,
+        (ExternCrate(ls, li), ExternCrate(rs, ri)) => ls == rs && eq_id(*li, *ri),
         (Use(l), Use(r)) => eq_use_tree(l, r),
         (
             Static(box StaticItem {
+                ident: li,
                 ty: lt,
                 mutability: lm,
                 expr: le,
@@ -339,16 +340,22 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 define_opaque: _,
             }),
             Static(box StaticItem {
+                ident: ri,
                 ty: rt,
                 mutability: rm,
                 expr: re,
                 safety: rs,
                 define_opaque: _,
             }),
-        ) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
+        ) => eq_id(*li, *ri)
+                && lm == rm
+                && ls == rs
+                && eq_ty(lt, rt)
+                && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Const(box ConstItem {
                 defaultness: ld,
+                ident: li,
                 generics: lg,
                 ty: lt,
                 expr: le,
@@ -356,16 +363,22 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
             }),
             Const(box ConstItem {
                 defaultness: rd,
+                ident: ri,
                 generics: rg,
                 ty: rt,
                 expr: re,
                 define_opaque: _,
             }),
-        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
+        ) => eq_defaultness(*ld, *rd)
+                && eq_id(*li, *ri)
+                && eq_generics(lg, rg)
+                && eq_ty(lt, rt)
+                && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Fn(box ast::Fn {
                 defaultness: ld,
                 sig: lf,
+                ident: li,
                 generics: lg,
                 contract: lc,
                 body: lb,
@@ -374,6 +387,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
+                ident: ri,
                 generics: rg,
                 contract: rc,
                 body: rb,
@@ -382,12 +396,14 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
+                && eq_id(*li, *ri)
                 && eq_generics(lg, rg)
                 && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
-        (Mod(lu, lmk), Mod(ru, rmk)) => {
-            lu == ru
+        (Mod(ls, li, lmk), Mod(rs, ri, rmk)) => {
+            ls == rs
+                && eq_id(*li, *ri)
                 && match (lmk, rmk) {
                     (ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => {
                         linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind))
@@ -421,33 +437,40 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 && over(lb, rb, eq_generic_bound)
                 && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
         },
-        (Enum(le, lg), Enum(re, rg)) => over(&le.variants, &re.variants, eq_variant) && eq_generics(lg, rg),
-        (Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
-            eq_variant_data(lv, rv) && eq_generics(lg, rg)
+        (Enum(li, le, lg), Enum(ri, re, rg)) => {
+            eq_id(*li, *ri) && over(&le.variants, &re.variants, eq_variant) && eq_generics(lg, rg)
+        }
+        (Struct(li, lv, lg), Struct(ri, rv, rg)) | (Union(li, lv, lg), Union(ri, rv, rg)) => {
+            eq_id(*li, *ri) && eq_variant_data(lv, rv) && eq_generics(lg, rg)
         },
         (
             Trait(box ast::Trait {
                 is_auto: la,
                 safety: lu,
+                ident: li,
                 generics: lg,
                 bounds: lb,
-                items: li,
+                items: lis,
             }),
             Trait(box ast::Trait {
                 is_auto: ra,
                 safety: ru,
+                ident: ri,
                 generics: rg,
                 bounds: rb,
-                items: ri,
+                items: ris,
             }),
         ) => {
             la == ra
                 && matches!(lu, Safety::Default) == matches!(ru, Safety::Default)
+                && eq_id(*li, *ri)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
-                && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
+                && over(lis, ris, |l, r| eq_item(l, r, eq_assoc_item_kind))
         },
-        (TraitAlias(lg, lb), TraitAlias(rg, rb)) => eq_generics(lg, rg) && over(lb, rb, eq_generic_bound),
+        (TraitAlias(li, lg, lb), TraitAlias(ri, rg, rb)) => {
+            eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound)
+        }
         (
             Impl(box ast::Impl {
                 safety: lu,
@@ -480,7 +503,9 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
         },
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
-        (MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_delim_args(&l.body, &r.body),
+        (MacroDef(li, ld), MacroDef(ri, rd)) => {
+            eq_id(*li, *ri) && ld.macro_rules == rd.macro_rules && eq_delim_args(&ld.body, &rd.body)
+        }
         _ => false,
     }
 }
@@ -490,6 +515,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
     match (l, r) {
         (
             Static(box StaticItem {
+                ident: li,
                 ty: lt,
                 mutability: lm,
                 expr: le,
@@ -497,17 +523,25 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 define_opaque: _,
             }),
             Static(box StaticItem {
+                ident: ri,
                 ty: rt,
                 mutability: rm,
                 expr: re,
                 safety: rs,
                 define_opaque: _,
             }),
-        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()) && ls == rs,
+        ) => {
+            eq_id(*li, *ri)
+                && eq_ty(lt, rt)
+                && lm == rm
+                && eq_expr_opt(le.as_ref(), re.as_ref())
+                && ls == rs
+        }
         (
             Fn(box ast::Fn {
                 defaultness: ld,
                 sig: lf,
+                ident: li,
                 generics: lg,
                 contract: lc,
                 body: lb,
@@ -516,6 +550,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
+                ident: ri,
                 generics: rg,
                 contract: rc,
                 body: rb,
@@ -524,6 +559,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
+                && eq_id(*li, *ri)
                 && eq_generics(lg, rg)
                 && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
@@ -531,20 +567,23 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
         (
             TyAlias(box ast::TyAlias {
                 defaultness: ld,
+                ident: li,
                 generics: lg,
+                where_clauses: _,
                 bounds: lb,
                 ty: lt,
-                ..
             }),
             TyAlias(box ast::TyAlias {
                 defaultness: rd,
+                ident: ri,
                 generics: rg,
+                where_clauses: _,
                 bounds: rb,
                 ty: rt,
-                ..
             }),
         ) => {
             eq_defaultness(*ld, *rd)
+                && eq_id(*li, *ri)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
                 && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
@@ -560,6 +599,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
         (
             Const(box ConstItem {
                 defaultness: ld,
+                ident: li,
                 generics: lg,
                 ty: lt,
                 expr: le,
@@ -567,16 +607,24 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
             }),
             Const(box ConstItem {
                 defaultness: rd,
+                ident: ri,
                 generics: rg,
                 ty: rt,
                 expr: re,
                 define_opaque: _,
             }),
-        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
+        ) => {
+            eq_defaultness(*ld, *rd)
+                && eq_id(*li, *ri)
+                && eq_generics(lg, rg)
+                && eq_ty(lt, rt)
+                && eq_expr_opt(le.as_ref(), re.as_ref())
+        }
         (
             Fn(box ast::Fn {
                 defaultness: ld,
                 sig: lf,
+                ident: li,
                 generics: lg,
                 contract: lc,
                 body: lb,
@@ -585,6 +633,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
+                ident: ri,
                 generics: rg,
                 contract: rc,
                 body: rb,
@@ -593,6 +642,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
+                && eq_id(*li, *ri)
                 && eq_generics(lg, rg)
                 && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
@@ -600,20 +650,23 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
         (
             Type(box TyAlias {
                 defaultness: ld,
+                ident: li,
                 generics: lg,
+                where_clauses: _,
                 bounds: lb,
                 ty: lt,
-                ..
             }),
             Type(box TyAlias {
                 defaultness: rd,
+                ident: ri,
                 generics: rg,
+                where_clauses: _,
                 bounds: rb,
                 ty: rt,
-                ..
             }),
         ) => {
             eq_defaultness(*ld, *rd)
+                && eq_id(*li, *ri)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
                 && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index dd149c4a29b..17751e824c0 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -15,7 +15,7 @@ use rustc_apfloat::ieee::{Half, Quad};
 use rustc_ast::ast::{self, LitFloatType, LitKind};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp,
+    BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp,
 };
 use rustc_lexer::tokenize;
 use rustc_lint::LateContext;
@@ -506,7 +506,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 UnOp::Deref => Some(if let Constant::Ref(r) = o { *r } else { o }),
             }),
             ExprKind::If(cond, then, ref otherwise) => self.ifthenelse(cond, then, *otherwise),
-            ExprKind::Binary(op, left, right) => self.binop(op, left, right),
+            ExprKind::Binary(op, left, right) => self.binop(op.node, left, right),
             ExprKind::Call(callee, []) => {
                 // We only handle a few const functions for now.
                 if let ExprKind::Path(qpath) = &callee.kind
@@ -744,7 +744,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
         }
     }
 
-    fn binop(&self, op: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> Option<Constant<'tcx>> {
+    fn binop(&self, op: BinOpKind, left: &Expr<'_>, right: &Expr<'_>) -> Option<Constant<'tcx>> {
         let l = self.expr(left)?;
         let r = self.expr(right);
         match (l, r) {
@@ -757,7 +757,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
 
                     // Using / or %, where the left-hand argument is the smallest integer of a signed integer type and
                     // the right-hand argument is -1 always panics, even with overflow-checks disabled
-                    if let BinOpKind::Div | BinOpKind::Rem = op.node
+                    if let BinOpKind::Div | BinOpKind::Rem = op
                         && l == ty_min_value
                         && r == -1
                     {
@@ -765,7 +765,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                     }
 
                     let zext = |n: i128| Constant::Int(unsext(self.tcx, n, ity));
-                    match op.node {
+                    match op {
                         // When +, * or binary - create a value greater than the maximum value, or less than
                         // the minimum value that can be stored, it panics.
                         BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(zext),
@@ -792,7 +792,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 ty::Uint(ity) => {
                     let bits = ity.bits();
 
-                    match op.node {
+                    match op {
                         BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),
                         BinOpKind::Sub => l.checked_sub(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),
                         BinOpKind::Mul => l.checked_mul(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),
@@ -815,7 +815,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 _ => None,
             },
             // FIXME(f16_f128): add these types when binary operations are available on all platforms
-            (Constant::F32(l), Some(Constant::F32(r))) => match op.node {
+            (Constant::F32(l), Some(Constant::F32(r))) => match op {
                 BinOpKind::Add => Some(Constant::F32(l + r)),
                 BinOpKind::Sub => Some(Constant::F32(l - r)),
                 BinOpKind::Mul => Some(Constant::F32(l * r)),
@@ -829,7 +829,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 BinOpKind::Gt => Some(Constant::Bool(l > r)),
                 _ => None,
             },
-            (Constant::F64(l), Some(Constant::F64(r))) => match op.node {
+            (Constant::F64(l), Some(Constant::F64(r))) => match op {
                 BinOpKind::Add => Some(Constant::F64(l + r)),
                 BinOpKind::Sub => Some(Constant::F64(l - r)),
                 BinOpKind::Mul => Some(Constant::F64(l * r)),
@@ -843,7 +843,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 BinOpKind::Gt => Some(Constant::Bool(l > r)),
                 _ => None,
             },
-            (l, r) => match (op.node, l, r) {
+            (l, r) => match (op, l, r) {
                 (BinOpKind::And, Constant::Bool(false), _) => Some(Constant::Bool(false)),
                 (BinOpKind::Or, Constant::Bool(true), _) => Some(Constant::Bool(true)),
                 (BinOpKind::And, Constant::Bool(true), Some(r)) | (BinOpKind::Or, Constant::Bool(false), Some(r)) => {
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 668b0cb69e2..6d2c2a2d692 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -114,6 +114,7 @@ use rustc_hir::{
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::place::PlaceBase;
+use rustc_middle::lint::LevelAndSource;
 use rustc_middle::mir::{AggregateKind, Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc_middle::ty::fast_reject::SimplifiedType;
@@ -1976,14 +1977,14 @@ pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl I
     let mut suppress_lint = false;
 
     for id in ids {
-        let (level, _) = cx.tcx.lint_level_at_node(lint, id);
-        if let Some(expectation) = level.get_expectation_id() {
+        let LevelAndSource { level, lint_id, .. } = cx.tcx.lint_level_at_node(lint, id);
+        if let Some(expectation) = lint_id {
             cx.fulfill_expectation(expectation);
         }
 
         match level {
-            Level::Allow | Level::Expect(_) => suppress_lint = true,
-            Level::Warn | Level::ForceWarn(_) | Level::Deny | Level::Forbid => {},
+            Level::Allow | Level::Expect => suppress_lint = true,
+            Level::Warn | Level::ForceWarn | Level::Deny | Level::Forbid => {},
         }
     }
 
@@ -1998,7 +1999,7 @@ pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl I
 /// make sure to use `span_lint_hir` functions to emit the lint. This ensures that
 /// expectations at the checked nodes will be fulfilled.
 pub fn is_lint_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> bool {
-    cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow
+    cx.tcx.lint_level_at_node(lint, id).level == Level::Allow
 }
 
 pub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> {
@@ -2990,7 +2991,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprU
         {
             adjustments = cx.typeck_results().expr_adjustments(e);
         }
-        same_ctxt &= cx.tcx.hir().span(parent_id).ctxt() == ctxt;
+        same_ctxt &= cx.tcx.hir_span(parent_id).ctxt() == ctxt;
         if let Node::Expr(e) = parent {
             match e.kind {
                 ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id != child_id => {
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 1a457bc7f21..dfb30b9c218 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -178,7 +178,6 @@ pub fn first_node_in_macro(cx: &LateContext<'_>, node: &impl HirNode) -> Option<
 
     // get the parent node, possibly skipping over a statement
     // if the parent is not found, it is sensible to return `Some(root)`
-    let hir = cx.tcx.hir();
     let mut parent_iter = cx.tcx.hir_parent_iter(node.hir_id());
     let (parent_id, _) = match parent_iter.next() {
         None => return Some(ExpnId::root()),
@@ -190,7 +189,7 @@ pub fn first_node_in_macro(cx: &LateContext<'_>, node: &impl HirNode) -> Option<
     };
 
     // get the macro expansion of the parent node
-    let parent_span = hir.span(parent_id);
+    let parent_span = cx.tcx.hir_span(parent_id);
     let Some(parent_macro_call) = macro_backtrace(parent_span).next() else {
         // the parent node is not in a macro
         return Some(ExpnId::root());
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 68a1de96a35..e92c0c79b25 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -357,7 +357,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
     match op {
         AssocOp::Binary(op) => format!("{lhs} {} {rhs}", op.as_str()),
         AssocOp::Assign => format!("{lhs} = {rhs}"),
-        AssocOp::AssignOp(op) => format!("{lhs} {}= {rhs}", op.as_str()),
+        AssocOp::AssignOp(op) => format!("{lhs} {} {rhs}", op.as_str()),
         AssocOp::Cast => format!("{lhs} as {rhs}"),
         AssocOp::Range(limits) => format!("{lhs}{}{rhs}", limits.as_str()),
     }
@@ -839,8 +839,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
 
     fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {
         if let PlaceBase::Local(id) = cmt.place.base {
-            let map = self.cx.tcx.hir();
-            let span = map.span(cmt.hir_id);
+            let span = self.cx.tcx.hir_span(cmt.hir_id);
             let start_span = Span::new(self.next_pos, span.lo(), span.ctxt(), None);
             let mut start_snip = snippet_with_applicability(self.cx, start_span, "..", &mut self.applicability);
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-1782.rs b/src/tools/clippy/tests/ui/crashes/ice-1782.rs
index fefdc405cce..4a1886c08af 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-1782.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-1782.rs
@@ -1,6 +1,6 @@
 //@ check-pass
 
-#![allow(dead_code, unused_variables)]
+#![allow(dead_code, unused_variables, invalid_null_arguments)]
 #![allow(clippy::unnecessary_cast, clippy::missing_transmute_annotations)]
 
 /// Should not trigger an ICE in `SpanlessEq` / `consts::constant`
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
deleted file mode 100644
index ce78e89ee82..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
+++ /dev/null
@@ -1,66 +0,0 @@
-fn main() {
-    unsafe {
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(std::mem::size_of::<A>(), 0);
-
-        let _a: A = std::ptr::read(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_unaligned(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_unaligned(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_volatile(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_volatile(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::replace(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
-
-        std::ptr::swap::<A>(std::ptr::NonNull::dangling().as_ptr(), &mut A);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap::<A>(&mut A, std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::swap_nonoverlapping::<A>(std::ptr::NonNull::dangling().as_ptr(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_unaligned(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_volatile(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_bytes::<usize>(std::ptr::NonNull::dangling().as_ptr(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
deleted file mode 100644
index 361865fbd96..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-fn main() {
-    unsafe {
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(std::mem::size_of::<A>(), 0);
-
-        let _a: A = std::ptr::read(std::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read(std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_unaligned(std::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_unaligned(std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_volatile(std::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_volatile(std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
-
-        std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap::<A>(&mut A, std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::swap_nonoverlapping::<A>(std::ptr::null_mut(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_unaligned(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_volatile(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_bytes::<usize>(std::ptr::null_mut(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
deleted file mode 100644
index 3f9d15b9040..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
+++ /dev/null
@@ -1,136 +0,0 @@
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:3:59
-   |
-LL |         let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), 0);
-   |                                                           ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-   |
-   = note: `#[deny(clippy::invalid_null_ptr_usage)]` on by default
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:5:59
-   |
-LL |         let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null_mut(), 0);
-   |                                                           ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:8:63
-   |
-LL |         let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0);
-   |                                                               ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:11:33
-   |
-LL |         std::ptr::copy::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                 ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:13:73
-   |
-LL |         std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-   |                                                                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:16:48
-   |
-LL |         std::ptr::copy_nonoverlapping::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                                ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:18:88
-   |
-LL |         std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-   |                                                                                        ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:24:36
-   |
-LL |         let _a: A = std::ptr::read(std::ptr::null());
-   |                                    ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:26:36
-   |
-LL |         let _a: A = std::ptr::read(std::ptr::null_mut());
-   |                                    ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:29:46
-   |
-LL |         let _a: A = std::ptr::read_unaligned(std::ptr::null());
-   |                                              ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:31:46
-   |
-LL |         let _a: A = std::ptr::read_unaligned(std::ptr::null_mut());
-   |                                              ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:34:45
-   |
-LL |         let _a: A = std::ptr::read_volatile(std::ptr::null());
-   |                                             ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:36:45
-   |
-LL |         let _a: A = std::ptr::read_volatile(std::ptr::null_mut());
-   |                                             ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:39:39
-   |
-LL |         let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
-   |                                       ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:44:29
-   |
-LL |         std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
-   |                             ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:46:37
-   |
-LL |         std::ptr::swap::<A>(&mut A, std::ptr::null_mut());
-   |                                     ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:49:44
-   |
-LL |         std::ptr::swap_nonoverlapping::<A>(std::ptr::null_mut(), &mut A, 0);
-   |                                            ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:51:52
-   |
-LL |         std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::null_mut(), 0);
-   |                                                    ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:54:25
-   |
-LL |         std::ptr::write(std::ptr::null_mut(), A);
-   |                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:57:35
-   |
-LL |         std::ptr::write_unaligned(std::ptr::null_mut(), A);
-   |                                   ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:60:34
-   |
-LL |         std::ptr::write_volatile(std::ptr::null_mut(), A);
-   |                                  ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:63:40
-   |
-LL |         std::ptr::write_bytes::<usize>(std::ptr::null_mut(), 42, 0);
-   |                                        ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: aborting due to 22 previous errors
-
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed
deleted file mode 100644
index df7ab166187..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed
+++ /dev/null
@@ -1,79 +0,0 @@
-#![no_std]
-#![feature(lang_items)]
-
-use core::panic::PanicInfo;
-
-#[lang = "eh_personality"]
-extern "C" fn eh_personality() {}
-
-#[panic_handler]
-fn panic(info: &PanicInfo) -> ! {
-    loop {}
-}
-
-fn main() {
-    unsafe {
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(core::mem::size_of::<A>(), 0);
-
-        let _a: A = core::ptr::read(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_unaligned(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_unaligned(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::replace(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts(core::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut(), 0);
-
-        core::ptr::swap::<A>(core::ptr::NonNull::dangling().as_ptr(), &mut A);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap::<A>(&mut A, core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::swap_nonoverlapping::<A>(core::ptr::NonNull::dangling().as_ptr(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap_nonoverlapping::<A>(&mut A, core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_unaligned(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_volatile(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_bytes::<usize>(core::ptr::NonNull::dangling().as_ptr(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs
deleted file mode 100644
index 38ddfff0553..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-#![no_std]
-#![feature(lang_items)]
-
-use core::panic::PanicInfo;
-
-#[lang = "eh_personality"]
-extern "C" fn eh_personality() {}
-
-#[panic_handler]
-fn panic(info: &PanicInfo) -> ! {
-    loop {}
-}
-
-fn main() {
-    unsafe {
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(core::mem::size_of::<A>(), 0);
-
-        let _a: A = core::ptr::read(core::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read(core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_unaligned(core::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_unaligned(core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_volatile(core::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_volatile(core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::replace(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts(core::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut(), 0);
-
-        core::ptr::swap::<A>(core::ptr::null_mut(), &mut A);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap::<A>(&mut A, core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::swap_nonoverlapping::<A>(core::ptr::null_mut(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap_nonoverlapping::<A>(&mut A, core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_unaligned(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_volatile(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_bytes::<usize>(core::ptr::null_mut(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr b/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr
deleted file mode 100644
index b5dd21ce624..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr
+++ /dev/null
@@ -1,136 +0,0 @@
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:16:60
-   |
-LL |         let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null(), 0);
-   |                                                            ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-   |
-   = note: `#[deny(clippy::invalid_null_ptr_usage)]` on by default
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:18:60
-   |
-LL |         let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null_mut(), 0);
-   |                                                            ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:21:64
-   |
-LL |         let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::null_mut(), 0);
-   |                                                                ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:24:34
-   |
-LL |         core::ptr::copy::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                  ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:26:75
-   |
-LL |         core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-   |                                                                           ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:29:49
-   |
-LL |         core::ptr::copy_nonoverlapping::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                                 ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:31:90
-   |
-LL |         core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-   |                                                                                          ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:37:37
-   |
-LL |         let _a: A = core::ptr::read(core::ptr::null());
-   |                                     ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:39:37
-   |
-LL |         let _a: A = core::ptr::read(core::ptr::null_mut());
-   |                                     ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:42:47
-   |
-LL |         let _a: A = core::ptr::read_unaligned(core::ptr::null());
-   |                                               ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:44:47
-   |
-LL |         let _a: A = core::ptr::read_unaligned(core::ptr::null_mut());
-   |                                               ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:47:46
-   |
-LL |         let _a: A = core::ptr::read_volatile(core::ptr::null());
-   |                                              ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:49:46
-   |
-LL |         let _a: A = core::ptr::read_volatile(core::ptr::null_mut());
-   |                                              ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:52:40
-   |
-LL |         let _a: A = core::ptr::replace(core::ptr::null_mut(), A);
-   |                                        ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:57:30
-   |
-LL |         core::ptr::swap::<A>(core::ptr::null_mut(), &mut A);
-   |                              ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:59:38
-   |
-LL |         core::ptr::swap::<A>(&mut A, core::ptr::null_mut());
-   |                                      ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:62:45
-   |
-LL |         core::ptr::swap_nonoverlapping::<A>(core::ptr::null_mut(), &mut A, 0);
-   |                                             ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:64:53
-   |
-LL |         core::ptr::swap_nonoverlapping::<A>(&mut A, core::ptr::null_mut(), 0);
-   |                                                     ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:67:26
-   |
-LL |         core::ptr::write(core::ptr::null_mut(), A);
-   |                          ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:70:36
-   |
-LL |         core::ptr::write_unaligned(core::ptr::null_mut(), A);
-   |                                    ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:73:35
-   |
-LL |         core::ptr::write_volatile(core::ptr::null_mut(), A);
-   |                                   ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:76:41
-   |
-LL |         core::ptr::write_bytes::<usize>(core::ptr::null_mut(), 42, 0);
-   |                                         ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: aborting due to 22 previous errors
-
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 501811fa491..79640470696 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -119,6 +119,7 @@
 #![warn(invalid_atomic_ordering)] //~ ERROR: lint `clippy::invalid_atomic_ordering`
 #![warn(invalid_value)] //~ ERROR: lint `clippy::invalid_ref`
 #![warn(invalid_from_utf8_unchecked)] //~ ERROR: lint `clippy::invalid_utf8_in_unchecked`
+#![warn(invalid_null_arguments)] //~ ERROR: lint `clippy::invalid_null_ptr_usage`
 #![warn(let_underscore_drop)] //~ ERROR: lint `clippy::let_underscore_drop`
 #![warn(unexpected_cfgs)] //~ ERROR: lint `clippy::maybe_misused_cfg`
 #![warn(enum_intrinsics_non_enums)] //~ ERROR: lint `clippy::mem_discriminant_non_enum`
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 7f4b8062e1b..aa7b905b4b8 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -119,6 +119,7 @@
 #![warn(clippy::invalid_atomic_ordering)] //~ ERROR: lint `clippy::invalid_atomic_ordering`
 #![warn(clippy::invalid_ref)] //~ ERROR: lint `clippy::invalid_ref`
 #![warn(clippy::invalid_utf8_in_unchecked)] //~ ERROR: lint `clippy::invalid_utf8_in_unchecked`
+#![warn(clippy::invalid_null_ptr_usage)] //~ ERROR: lint `clippy::invalid_null_ptr_usage`
 #![warn(clippy::let_underscore_drop)] //~ ERROR: lint `clippy::let_underscore_drop`
 #![warn(clippy::maybe_misused_cfg)] //~ ERROR: lint `clippy::maybe_misused_cfg`
 #![warn(clippy::mem_discriminant_non_enum)] //~ ERROR: lint `clippy::mem_discriminant_non_enum`
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index f24eaec3917..b3c88167c11 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -343,71 +343,77 @@ error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_fro
 LL | #![warn(clippy::invalid_utf8_in_unchecked)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
 
-error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
+error: lint `clippy::invalid_null_ptr_usage` has been renamed to `invalid_null_arguments`
   --> tests/ui/rename.rs:122:9
    |
+LL | #![warn(clippy::invalid_null_ptr_usage)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_null_arguments`
+
+error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
+  --> tests/ui/rename.rs:123:9
+   |
 LL | #![warn(clippy::let_underscore_drop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
 
 error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs`
-  --> tests/ui/rename.rs:123:9
+  --> tests/ui/rename.rs:124:9
    |
 LL | #![warn(clippy::maybe_misused_cfg)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
 
 error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> tests/ui/rename.rs:124:9
+  --> tests/ui/rename.rs:125:9
    |
 LL | #![warn(clippy::mem_discriminant_non_enum)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
 error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs`
-  --> tests/ui/rename.rs:125:9
+  --> tests/ui/rename.rs:126:9
    |
 LL | #![warn(clippy::mismatched_target_os)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
 
 error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
-  --> tests/ui/rename.rs:126:9
+  --> tests/ui/rename.rs:127:9
    |
 LL | #![warn(clippy::panic_params)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
 
 error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
-  --> tests/ui/rename.rs:127:9
+  --> tests/ui/rename.rs:128:9
    |
 LL | #![warn(clippy::positional_named_format_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
 
 error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`
-  --> tests/ui/rename.rs:128:9
+  --> tests/ui/rename.rs:129:9
    |
 LL | #![warn(clippy::temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`
 
 error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
-  --> tests/ui/rename.rs:129:9
+  --> tests/ui/rename.rs:130:9
    |
 LL | #![warn(clippy::undropped_manually_drops)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
 
 error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
-  --> tests/ui/rename.rs:130:9
+  --> tests/ui/rename.rs:131:9
    |
 LL | #![warn(clippy::unknown_clippy_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
 
 error: lint `clippy::unused_label` has been renamed to `unused_labels`
-  --> tests/ui/rename.rs:131:9
+  --> tests/ui/rename.rs:132:9
    |
 LL | #![warn(clippy::unused_label)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
 error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons`
-  --> tests/ui/rename.rs:132:9
+  --> tests/ui/rename.rs:133:9
    |
 LL | #![warn(clippy::vtable_address_comparisons)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons`
 
-error: aborting due to 68 previous errors
+error: aborting due to 69 previous errors
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 08d3c1c343e..9e35d2b4667 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -9,9 +9,9 @@ use std::{fmt, iter};
 use build_helper::git::GitConfig;
 use semver::Version;
 use serde::de::{Deserialize, Deserializer, Error as _};
-use test::{ColorConfig, OutputFormat};
 
 pub use self::Mode::*;
+use crate::executor::{ColorConfig, OutputFormat};
 use crate::util::{PathBufExt, add_dylib_path};
 
 macro_rules! string_enum {
@@ -178,6 +178,10 @@ pub struct Config {
     /// `true` to overwrite stderr/stdout files instead of complaining about changes in output.
     pub bless: bool,
 
+    /// Stop as soon as possible after any test fails.
+    /// May run a few more tests before stopping, due to threading.
+    pub fail_fast: bool,
+
     /// The library paths required for running the compiler.
     pub compile_lib_path: PathBuf,
 
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index c0566ef93b9..b68f817146f 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -122,13 +122,17 @@ fn parse_expected(
     //     //~|
     //     //~^
     //     //~^^^^^
+    //     //~v
+    //     //~vvvvv
     //     //~?
     //     //[rev1]~
     //     //[rev1,rev2]~^^
     static RE: OnceLock<Regex> = OnceLock::new();
 
     let captures = RE
-        .get_or_init(|| Regex::new(r"//(?:\[(?P<revs>[\w\-,]+)])?~(?P<adjust>\?|\||\^*)").unwrap())
+        .get_or_init(|| {
+            Regex::new(r"//(?:\[(?P<revs>[\w\-,]+)])?~(?P<adjust>\?|\||[v\^]*)").unwrap()
+        })
         .captures(line)?;
 
     match (test_revision, captures.name("revs")) {
@@ -164,6 +168,8 @@ fn parse_expected(
         (true, Some(last_nonfollow_error.expect("encountered //~| without preceding //~^ line")))
     } else if line_num_adjust == "?" {
         (false, None)
+    } else if line_num_adjust.starts_with('v') {
+        (false, Some(line_num + line_num_adjust.len()))
     } else {
         (false, Some(line_num - line_num_adjust.len()))
     };
diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs
new file mode 100644
index 00000000000..7588fee2b2b
--- /dev/null
+++ b/src/tools/compiletest/src/executor.rs
@@ -0,0 +1,156 @@
+//! This module encapsulates all of the code that interacts directly with
+//! libtest, to execute the collected tests.
+//!
+//! This will hopefully make it easier to migrate away from libtest someday.
+
+use std::borrow::Cow;
+use std::io;
+use std::sync::Arc;
+
+use crate::common::{Config, TestPaths};
+
+/// Delegates to libtest to run the list of collected tests.
+///
+/// Returns `Ok(true)` if all tests passed, or `Ok(false)` if one or more tests failed.
+pub(crate) fn execute_tests(config: &Config, tests: Vec<CollectedTest>) -> io::Result<bool> {
+    let opts = test_opts(config);
+    let tests = tests.into_iter().map(|t| t.into_libtest()).collect::<Vec<_>>();
+
+    test::run_tests_console(&opts, tests)
+}
+
+/// Information needed to create a `test::TestDescAndFn`.
+pub(crate) struct CollectedTest {
+    pub(crate) desc: CollectedTestDesc,
+    pub(crate) config: Arc<Config>,
+    pub(crate) testpaths: TestPaths,
+    pub(crate) revision: Option<String>,
+}
+
+/// Information needed to create a `test::TestDesc`.
+pub(crate) struct CollectedTestDesc {
+    pub(crate) name: String,
+    pub(crate) ignore: bool,
+    pub(crate) ignore_message: Option<Cow<'static, str>>,
+    pub(crate) should_panic: ShouldPanic,
+}
+
+impl CollectedTest {
+    fn into_libtest(self) -> test::TestDescAndFn {
+        let Self { desc, config, testpaths, revision } = self;
+        let CollectedTestDesc { name, ignore, ignore_message, should_panic } = desc;
+
+        // Libtest requires the ignore message to be a &'static str, so we might
+        // have to leak memory to create it. This is fine, as we only do so once
+        // per test, so the leak won't grow indefinitely.
+        let ignore_message = ignore_message.map(|msg| match msg {
+            Cow::Borrowed(s) => s,
+            Cow::Owned(s) => &*String::leak(s),
+        });
+
+        let desc = test::TestDesc {
+            name: test::DynTestName(name),
+            ignore,
+            ignore_message,
+            source_file: "",
+            start_line: 0,
+            start_col: 0,
+            end_line: 0,
+            end_col: 0,
+            should_panic: should_panic.to_libtest(),
+            compile_fail: false,
+            no_run: false,
+            test_type: test::TestType::Unknown,
+        };
+
+        // This closure is invoked when libtest returns control to compiletest
+        // to execute the test.
+        let testfn = test::DynTestFn(Box::new(move || {
+            crate::runtest::run(config, &testpaths, revision.as_deref());
+            Ok(())
+        }));
+
+        test::TestDescAndFn { desc, testfn }
+    }
+}
+
+/// Whether console output should be colored or not.
+#[derive(Copy, Clone, Default, Debug)]
+pub enum ColorConfig {
+    #[default]
+    AutoColor,
+    AlwaysColor,
+    NeverColor,
+}
+
+impl ColorConfig {
+    fn to_libtest(self) -> test::ColorConfig {
+        match self {
+            Self::AutoColor => test::ColorConfig::AutoColor,
+            Self::AlwaysColor => test::ColorConfig::AlwaysColor,
+            Self::NeverColor => test::ColorConfig::NeverColor,
+        }
+    }
+}
+
+/// Format of the test results output.
+#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
+pub enum OutputFormat {
+    /// Verbose output
+    Pretty,
+    /// Quiet output
+    #[default]
+    Terse,
+    /// JSON output
+    Json,
+}
+
+impl OutputFormat {
+    fn to_libtest(self) -> test::OutputFormat {
+        match self {
+            Self::Pretty => test::OutputFormat::Pretty,
+            Self::Terse => test::OutputFormat::Terse,
+            Self::Json => test::OutputFormat::Json,
+        }
+    }
+}
+
+/// Whether test is expected to panic or not.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub(crate) enum ShouldPanic {
+    No,
+    Yes,
+}
+
+impl ShouldPanic {
+    fn to_libtest(self) -> test::ShouldPanic {
+        match self {
+            Self::No => test::ShouldPanic::No,
+            Self::Yes => test::ShouldPanic::Yes,
+        }
+    }
+}
+
+fn test_opts(config: &Config) -> test::TestOpts {
+    test::TestOpts {
+        exclude_should_panic: false,
+        filters: config.filters.clone(),
+        filter_exact: config.filter_exact,
+        run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
+        format: config.format.to_libtest(),
+        logfile: config.logfile.clone(),
+        run_tests: true,
+        bench_benchmarks: true,
+        nocapture: config.nocapture,
+        color: config.color.to_libtest(),
+        shuffle: false,
+        shuffle_seed: None,
+        test_threads: None,
+        skip: config.skip.clone(),
+        list: false,
+        options: test::Options::new(),
+        time_options: None,
+        force_run_in_process: false,
+        fail_fast: config.fail_fast,
+    }
+}
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index d7a5f304d23..a0178f4bcc5 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -11,6 +11,7 @@ use tracing::*;
 
 use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
 use crate::debuggers::{extract_cdb_version, extract_gdb_version};
+use crate::executor::{CollectedTestDesc, ShouldPanic};
 use crate::header::auxiliary::{AuxProps, parse_and_update_aux};
 use crate::header::needs::CachedNeedsConditions;
 use crate::util::static_regex;
@@ -924,7 +925,14 @@ fn iter_header(
 
 impl Config {
     fn parse_and_update_revisions(&self, testfile: &Path, line: &str, existing: &mut Vec<String>) {
-        const FORBIDDEN_REVISION_NAMES: [&str; 9] =
+        const FORBIDDEN_REVISION_NAMES: [&str; 2] = [
+            // `//@ revisions: true false` Implying `--cfg=true` and `--cfg=false` makes it very
+            // weird for the test, since if the test writer wants a cfg of the same revision name
+            // they'd have to use `cfg(r#true)` and `cfg(r#false)`.
+            "true", "false",
+        ];
+
+        const FILECHECK_FORBIDDEN_REVISION_NAMES: [&str; 9] =
             ["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"];
 
         if let Some(raw) = self.parse_name_value_directive(line, "revisions") {
@@ -933,25 +941,38 @@ impl Config {
             }
 
             let mut duplicates: HashSet<_> = existing.iter().cloned().collect();
-            for revision in raw.split_whitespace().map(|r| r.to_string()) {
-                if !duplicates.insert(revision.clone()) {
+            for revision in raw.split_whitespace() {
+                if !duplicates.insert(revision.to_string()) {
                     panic!(
                         "duplicate revision: `{}` in line `{}`: {}",
                         revision,
                         raw,
                         testfile.display()
                     );
-                } else if matches!(self.mode, Mode::Assembly | Mode::Codegen | Mode::MirOpt)
-                    && FORBIDDEN_REVISION_NAMES.contains(&revision.as_str())
+                }
+
+                if FORBIDDEN_REVISION_NAMES.contains(&revision) {
+                    panic!(
+                        "revision name `{revision}` is not permitted: `{}` in line `{}`: {}",
+                        revision,
+                        raw,
+                        testfile.display()
+                    );
+                }
+
+                if matches!(self.mode, Mode::Assembly | Mode::Codegen | Mode::MirOpt)
+                    && FILECHECK_FORBIDDEN_REVISION_NAMES.contains(&revision)
                 {
                     panic!(
-                        "revision name `{revision}` is not permitted in a test suite that uses `FileCheck` annotations\n\
-                         as it is confusing when used as custom `FileCheck` prefix: `{revision}` in line `{}`: {}",
+                        "revision name `{revision}` is not permitted in a test suite that uses \
+                        `FileCheck` annotations as it is confusing when used as custom `FileCheck` \
+                        prefix: `{revision}` in line `{}`: {}",
                         raw,
                         testfile.display()
                     );
                 }
-                existing.push(revision);
+
+                existing.push(revision.to_string());
             }
         }
     }
@@ -1335,15 +1356,15 @@ where
     Some((min, max))
 }
 
-pub fn make_test_description<R: Read>(
+pub(crate) fn make_test_description<R: Read>(
     config: &Config,
     cache: &HeadersCache,
-    name: test::TestName,
+    name: String,
     path: &Path,
     src: R,
     test_revision: Option<&str>,
     poisoned: &mut bool,
-) -> test::TestDesc {
+) -> CollectedTestDesc {
     let mut ignore = false;
     let mut ignore_message = None;
     let mut should_fail = false;
@@ -1367,10 +1388,7 @@ pub fn make_test_description<R: Read>(
                     match $e {
                         IgnoreDecision::Ignore { reason } => {
                             ignore = true;
-                            // The ignore reason must be a &'static str, so we have to leak memory to
-                            // create it. This is fine, as the header is parsed only at the start of
-                            // compiletest so it won't grow indefinitely.
-                            ignore_message = Some(&*Box::leak(Box::<str>::from(reason)));
+                            ignore_message = Some(reason.into());
                         }
                         IgnoreDecision::Error { message } => {
                             eprintln!("error: {}:{line_number}: {message}", path.display());
@@ -1411,25 +1429,12 @@ pub fn make_test_description<R: Read>(
     // since we run the pretty printer across all tests by default.
     // If desired, we could add a `should-fail-pretty` annotation.
     let should_panic = match config.mode {
-        crate::common::Pretty => test::ShouldPanic::No,
-        _ if should_fail => test::ShouldPanic::Yes,
-        _ => test::ShouldPanic::No,
+        crate::common::Pretty => ShouldPanic::No,
+        _ if should_fail => ShouldPanic::Yes,
+        _ => ShouldPanic::No,
     };
 
-    test::TestDesc {
-        name,
-        ignore,
-        ignore_message,
-        source_file: "",
-        start_line: 0,
-        start_col: 0,
-        end_line: 0,
-        end_col: 0,
-        should_panic,
-        compile_fail: false,
-        no_run: false,
-        test_type: test::TestType::Unknown,
-    }
+    CollectedTestDesc { name, ignore, ignore_message, should_panic }
 }
 
 fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 007318be7cc..ff6bc49b72a 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -8,14 +8,15 @@ use super::{
     parse_normalize_rule,
 };
 use crate::common::{Config, Debugger, Mode};
+use crate::executor::{CollectedTestDesc, ShouldPanic};
 
 fn make_test_description<R: Read>(
     config: &Config,
-    name: test::TestName,
+    name: String,
     path: &Path,
     src: R,
     revision: Option<&str>,
-) -> test::TestDesc {
+) -> CollectedTestDesc {
     let cache = HeadersCache::load(config);
     let mut poisoned = false;
     let test = crate::header::make_test_description(
@@ -233,7 +234,7 @@ fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
 }
 
 fn check_ignore(config: &Config, contents: &str) -> bool {
-    let tn = test::DynTestName(String::new());
+    let tn = String::new();
     let p = Path::new("a.rs");
     let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
     d.ignore
@@ -242,13 +243,13 @@ fn check_ignore(config: &Config, contents: &str) -> bool {
 #[test]
 fn should_fail() {
     let config: Config = cfg().build();
-    let tn = test::DynTestName(String::new());
+    let tn = String::new();
     let p = Path::new("a.rs");
 
     let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
-    assert_eq!(d.should_panic, test::ShouldPanic::No);
+    assert_eq!(d.should_panic, ShouldPanic::No);
     let d = make_test_description(&config, tn, p, std::io::Cursor::new("//@ should-fail"), None);
-    assert_eq!(d.should_panic, test::ShouldPanic::Yes);
+    assert_eq!(d.should_panic, ShouldPanic::Yes);
 }
 
 #[test]
@@ -568,6 +569,13 @@ fn test_assembly_mode_forbidden_revisions() {
 }
 
 #[test]
+#[should_panic(expected = "revision name `true` is not permitted")]
+fn test_forbidden_revisions() {
+    let config = cfg().mode("ui").build();
+    parse_rs(&config, "//@ revisions: true");
+}
+
+#[test]
 #[should_panic(
     expected = "revision name `CHECK` is not permitted in a test suite that uses `FileCheck` annotations"
 )]
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 950566b2582..8145ae1c1bc 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -12,6 +12,7 @@ pub mod common;
 pub mod compute_diff;
 mod debuggers;
 pub mod errors;
+mod executor;
 pub mod header;
 mod json;
 mod raise_fd_limit;
@@ -32,7 +33,6 @@ use std::{env, fs, vec};
 
 use build_helper::git::{get_git_modified_files, get_git_untracked_files};
 use getopts::Options;
-use test::ColorConfig;
 use tracing::*;
 use walkdir::WalkDir;
 
@@ -41,6 +41,7 @@ use crate::common::{
     CompareMode, Config, Debugger, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path,
     output_base_dir, output_relative_path,
 };
+use crate::executor::{CollectedTest, ColorConfig, OutputFormat};
 use crate::header::HeadersCache;
 use crate::util::logv;
 
@@ -50,6 +51,12 @@ use crate::util::logv;
 /// some code here that inspects environment variables or even runs executables
 /// (e.g. when discovering debugger versions).
 pub fn parse_config(args: Vec<String>) -> Config {
+    if env::var("RUST_TEST_NOCAPTURE").is_ok() {
+        eprintln!(
+            "WARNING: RUST_TEST_NOCAPTURE is not supported. Use the `--no-capture` flag instead."
+        );
+    }
+
     let mut opts = Options::new();
     opts.reqopt("", "compile-lib-path", "path to host shared libraries", "PATH")
         .reqopt("", "run-lib-path", "path to target shared libraries", "PATH")
@@ -128,6 +135,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "bless",
             "overwrite stderr/stdout files instead of complaining about a mismatch",
         )
+        .optflag("", "fail-fast", "stop as soon as possible after any test fails")
         .optflag("", "quiet", "print one character per test instead of one line")
         .optopt("", "color", "coloring: auto, always, never", "WHEN")
         .optflag("", "json", "emit json output instead of plaintext output")
@@ -319,6 +327,9 @@ pub fn parse_config(args: Vec<String>) -> Config {
 
     Config {
         bless: matches.opt_present("bless"),
+        fail_fast: matches.opt_present("fail-fast")
+            || env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
+
         compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
         run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
         rustc_path: opt_path(matches, "rustc-path"),
@@ -392,9 +403,9 @@ pub fn parse_config(args: Vec<String>) -> Config {
         verbose: matches.opt_present("verbose"),
         format: match (matches.opt_present("quiet"), matches.opt_present("json")) {
             (true, true) => panic!("--quiet and --json are incompatible"),
-            (true, false) => test::OutputFormat::Terse,
-            (false, true) => test::OutputFormat::Json,
-            (false, false) => test::OutputFormat::Pretty,
+            (true, false) => OutputFormat::Terse,
+            (false, true) => OutputFormat::Json,
+            (false, false) => OutputFormat::Pretty,
         },
         only_modified: matches.opt_present("only-modified"),
         color,
@@ -525,8 +536,6 @@ pub fn run_tests(config: Arc<Config>) {
     // Let tests know which target they're running as
     env::set_var("TARGET", &config.target);
 
-    let opts = test_opts(&config);
-
     let mut configs = Vec::new();
     if let Mode::DebugInfo = config.mode {
         // Debugging emscripten code doesn't make sense today
@@ -553,12 +562,12 @@ pub fn run_tests(config: Arc<Config>) {
         tests.extend(collect_and_make_tests(c));
     }
 
-    tests.sort_by(|a, b| a.desc.name.as_slice().cmp(&b.desc.name.as_slice()));
+    tests.sort_by(|a, b| Ord::cmp(&a.desc.name, &b.desc.name));
 
     // Delegate to libtest to filter and run the big list of structures created
-    // during test discovery. When libtest decides to run a test, it will invoke
-    // the corresponding closure created by `make_test_closure`.
-    let res = test::run_tests_console(&opts, tests);
+    // during test discovery. When libtest decides to run a test, it will
+    // return control to compiletest by invoking a closure.
+    let res = crate::executor::execute_tests(&config, tests);
 
     // Check the outcome reported by libtest.
     match res {
@@ -602,37 +611,6 @@ pub fn run_tests(config: Arc<Config>) {
     }
 }
 
-pub fn test_opts(config: &Config) -> test::TestOpts {
-    if env::var("RUST_TEST_NOCAPTURE").is_ok() {
-        eprintln!(
-            "WARNING: RUST_TEST_NOCAPTURE is no longer used. \
-                   Use the `--nocapture` flag instead."
-        );
-    }
-
-    test::TestOpts {
-        exclude_should_panic: false,
-        filters: config.filters.clone(),
-        filter_exact: config.filter_exact,
-        run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
-        format: config.format,
-        logfile: config.logfile.clone(),
-        run_tests: true,
-        bench_benchmarks: true,
-        nocapture: config.nocapture,
-        color: config.color,
-        shuffle: false,
-        shuffle_seed: None,
-        test_threads: None,
-        skip: config.skip.clone(),
-        list: false,
-        options: test::Options::new(),
-        time_options: None,
-        force_run_in_process: false,
-        fail_fast: std::env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
-    }
-}
-
 /// Read-only context data used during test collection.
 struct TestCollectorCx {
     config: Arc<Config>,
@@ -643,17 +621,17 @@ struct TestCollectorCx {
 
 /// Mutable state used during test collection.
 struct TestCollector {
-    tests: Vec<test::TestDescAndFn>,
+    tests: Vec<CollectedTest>,
     found_path_stems: HashSet<PathBuf>,
     poisoned: bool,
 }
 
-/// Creates libtest structures for every test/revision in the test suite directory.
+/// Creates test structures for every test/revision in the test suite directory.
 ///
 /// This always inspects _all_ test files in the suite (e.g. all 17k+ ui tests),
 /// regardless of whether any filters/tests were specified on the command-line,
 /// because filtering is handled later by libtest.
-pub fn collect_and_make_tests(config: Arc<Config>) -> Vec<test::TestDescAndFn> {
+pub(crate) fn collect_and_make_tests(config: Arc<Config>) -> Vec<CollectedTest> {
     debug!("making tests from {}", config.src_test_suite_root.display());
     let common_inputs_stamp = common_inputs_stamp(&config);
     let modified_tests =
@@ -882,7 +860,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
     };
 
     // For each revision (or the sole dummy revision), create and append a
-    // `test::TestDescAndFn` that can be handed over to libtest.
+    // `CollectedTest` that can be handed over to the test executor.
     collector.tests.extend(revisions.into_iter().map(|revision| {
         // Create a test name and description to hand over to libtest.
         let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
@@ -905,13 +883,14 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
         if !cx.config.force_rerun && is_up_to_date(cx, testpaths, &early_props, revision) {
             desc.ignore = true;
             // Keep this in sync with the "up-to-date" message detected by bootstrap.
-            desc.ignore_message = Some("up-to-date");
+            desc.ignore_message = Some("up-to-date".into());
         }
 
-        // Create the callback that will run this test/revision when libtest calls it.
-        let testfn = make_test_closure(Arc::clone(&cx.config), testpaths, revision);
+        let config = Arc::clone(&cx.config);
+        let testpaths = testpaths.clone();
+        let revision = revision.map(str::to_owned);
 
-        test::TestDescAndFn { desc, testfn }
+        CollectedTest { desc, config, testpaths, revision }
     }));
 }
 
@@ -1043,11 +1022,7 @@ impl Stamp {
 }
 
 /// Creates a name for this test/revision that can be handed over to libtest.
-fn make_test_name(
-    config: &Config,
-    testpaths: &TestPaths,
-    revision: Option<&str>,
-) -> test::TestName {
+fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> String {
     // Print the name of the file, relative to the sources root.
     let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
     let debugger = match config.debugger {
@@ -1059,32 +1034,14 @@ fn make_test_name(
         None => String::new(),
     };
 
-    test::DynTestName(format!(
+    format!(
         "[{}{}{}] {}{}",
         config.mode,
         debugger,
         mode_suffix,
         path.display(),
         revision.map_or("".to_string(), |rev| format!("#{}", rev))
-    ))
-}
-
-/// Creates a callback for this test/revision that libtest will call when it
-/// decides to actually run the underlying test.
-fn make_test_closure(
-    config: Arc<Config>,
-    testpaths: &TestPaths,
-    revision: Option<&str>,
-) -> test::TestFn {
-    let testpaths = testpaths.clone();
-    let revision = revision.map(str::to_owned);
-
-    // This callback is the link between compiletest's test discovery code,
-    // and the parts of compiletest that know how to run an individual test.
-    test::DynTestFn(Box::new(move || {
-        runtest::run(config, &testpaths, revision.as_deref());
-        Ok(())
-    }))
+    )
 }
 
 /// Checks that test discovery didn't find any tests whose name stem is a prefix
diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs
index 9b5b8b56b60..974e5170465 100644
--- a/src/tools/compiletest/src/runtest/ui.rs
+++ b/src/tools/compiletest/src/runtest/ui.rs
@@ -169,16 +169,9 @@ impl TestCx<'_> {
             self.props.error_patterns
         );
 
-        let check_patterns = should_run == WillExecute::No
-            && (!self.props.error_patterns.is_empty()
-                || !self.props.regex_error_patterns.is_empty());
         if !explicit && self.config.compare_mode.is_none() {
-            let check_annotations = !check_patterns || !expected_errors.is_empty();
-
-            if check_annotations {
-                // "//~ERROR comments"
-                self.check_expected_errors(expected_errors, &proc_res);
-            }
+            // "//~ERROR comments"
+            self.check_expected_errors(expected_errors, &proc_res);
         } else if explicit && !expected_errors.is_empty() {
             let msg = format!(
                 "line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead",
@@ -188,7 +181,10 @@ impl TestCx<'_> {
             self.fatal(&msg);
         }
         let output_to_check = self.get_output(&proc_res);
-        if check_patterns {
+        if should_run == WillExecute::No
+            && (!self.props.error_patterns.is_empty()
+                || !self.props.regex_error_patterns.is_empty())
+        {
             // "// error-pattern" comments
             self.check_all_error_patterns(&output_to_check, &proc_res, pm);
         }
diff --git a/src/tools/miri/.github/workflows/sysroots.yml b/src/tools/miri/.github/workflows/sysroots.yml
index 6a4f44ddd50..11bcaec9255 100644
--- a/src/tools/miri/.github/workflows/sysroots.yml
+++ b/src/tools/miri/.github/workflows/sysroots.yml
@@ -16,6 +16,7 @@ jobs:
       - uses: actions/checkout@v4
       - name: Build the sysroots
         run: |
+          rustup toolchain install nightly
           cargo install -f rustup-toolchain-install-master
           ./miri toolchain -c rust-docs # Docs are the only place targets are separated by tier
           ./miri install
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 57a757f9085..b8100d0e7ad 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -1079,9 +1079,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 
 [[package]]
 name = "ui_test"
-version = "0.28.0"
+version = "0.29.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
+checksum = "14bf63f2931a28a04af0bd24c5f850223d29f3a40afae49ed6ce442a65eb8652"
 dependencies = [
  "annotate-snippets",
  "anyhow",
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index 728a7552fd8..5d8c9a86644 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -47,7 +47,7 @@ windows-sys = { version = "0.52", features = [
 ] }
 
 [dev-dependencies]
-ui_test = "0.28.0"
+ui_test = "0.29.1"
 colored = "2"
 rustc_version = "0.4"
 regex = "1.5.5"
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 4ae901be9b4..201aa1f5386 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -237,8 +237,7 @@ inherent interpreter slowdown and a loss of parallelism.
 You can get your test suite's parallelism back by running `cargo miri nextest run -jN`
 (note that you will need [`cargo-nextest`](https://nexte.st) installed).
 This works because `cargo-nextest` collects a list of all tests then launches a
-separate `cargo miri run` for each test. You will need to specify a `-j` or `--test-threads`;
-by default `cargo miri nextest run` runs one test at a time. For more details, see the
+separate `cargo miri run` for each test. For more information about nextest, see the
 [`cargo-nextest` Miri documentation](https://nexte.st/book/miri.html).
 
 Note: This one-test-per-process model means that `cargo miri test` is able to detect data
@@ -432,7 +431,8 @@ to Miri failing to detect cases of undefined behavior in a program.
 * `-Zmiri-track-weak-memory-loads` shows a backtrace when weak memory emulation returns an outdated
   value from a load. This can help diagnose problems that disappear under
   `-Zmiri-disable-weak-memory-emulation`.
-* `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the [Tree Borrows] rules.
+* <a name="-Zmiri-tree-borrows"><!-- The playground links here --></a>
+  `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the [Tree Borrows] rules.
   Tree Borrows is even more experimental than Stacked Borrows. While Tree Borrows
   is still sound in the sense of catching all aliasing violations that current versions
   of the compiler might exploit, it is likely that the eventual final aliasing model
diff --git a/src/tools/miri/bench-cargo-miri/mse/src/main.rs b/src/tools/miri/bench-cargo-miri/mse/src/main.rs
index e16ccd2c0d7..06d5487d1d4 100644
--- a/src/tools/miri/bench-cargo-miri/mse/src/main.rs
+++ b/src/tools/miri/bench-cargo-miri/mse/src/main.rs
@@ -10,7 +10,7 @@ fn main() {
 }
 
 fn read_i16(buffer: &[u8], index: usize) -> i16 {
-    const SIZE: usize = std::mem::size_of::<i16>();
+    const SIZE: usize = size_of::<i16>();
     let mut bytes: [u8; SIZE] = [0u8; SIZE];
     bytes.copy_from_slice(&buffer[(index * SIZE)..(index * SIZE + SIZE)]);
     unsafe { std::mem::transmute(bytes) }
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index d7b4421061c..71ea07f3463 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -467,7 +467,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
                 if let Some(i) = val.iter().position(|&s| s == "link") {
                     emit_link_hack = true;
                     val.remove(i);
-                    if !val.iter().any(|&s| s == "metadata") {
+                    if !val.contains(&"metadata") {
                         val.push("metadata");
                     }
                 }
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 3327ad17c44..7155d692ee5 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -166,7 +166,7 @@ case $HOST_TARGET in
     UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
     TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
     TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
-    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread epoll eventfd
+    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random sync concurrency thread epoll eventfd
     TEST_TARGET=wasm32-wasip2          run_tests_minimal $BASIC wasm
     TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
     TEST_TARGET=thumbv7em-none-eabihf  run_tests_minimal no_std
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index b3e207f53b8..cf36b6fd038 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-f5729cfed3c45e061e8a443677fc1d5ef9277df7
+4ac032f857b46037b55c1fc0fa702450aad37f43
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 0a2d3ac63a7..c263e86c082 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -170,20 +170,22 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // This ensures the interpreted program and native code have the same view of memory.
             let base_ptr = match info.kind {
                 AllocKind::LiveData => {
-                    if this.tcx.try_get_global_alloc(alloc_id).is_some() {
+                    if memory_kind == MiriMemoryKind::Global.into() {
                         // For new global allocations, we always pre-allocate the memory to be able use the machine address directly.
                         let prepared_bytes = MiriAllocBytes::zeroed(info.size, info.align)
                             .unwrap_or_else(|| {
                                 panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes", size = info.size)
                             });
                         let ptr = prepared_bytes.as_ptr();
-                        // Store prepared allocation space to be picked up for use later.
+                        // Store prepared allocation to be picked up for use later.
                         global_state
                             .prepared_alloc_bytes
                             .try_insert(alloc_id, prepared_bytes)
                             .unwrap();
                         ptr
                     } else {
+                        // Non-global allocations are already in memory at this point so
+                        // we can just get a pointer to where their data is stored.
                         this.get_alloc_bytes_unchecked_raw(alloc_id)?
                     }
                 }
@@ -381,6 +383,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         align: Align,
     ) -> InterpResult<'tcx, MiriAllocBytes> {
         let this = self.eval_context_ref();
+        assert!(this.tcx.try_get_global_alloc(id).is_some());
         if this.machine.native_lib.is_some() {
             // In native lib mode, MiriAllocBytes for global allocations are handled via `prepared_alloc_bytes`.
             // This additional call ensures that some `MiriAllocBytes` are always prepared, just in case
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs
index b1ca434361b..923031dbbd1 100644
--- a/src/tools/miri/src/concurrency/data_race.rs
+++ b/src/tools/miri/src/concurrency/data_race.rs
@@ -717,7 +717,7 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
         // The program didn't actually do a read, so suppress the memory access hooks.
         // This is also a very special exception where we just ignore an error -- if this read
         // was UB e.g. because the memory is uninitialized, we don't want to know!
-        let old_val = this.run_for_validation(|this| this.read_scalar(dest)).discard_err();
+        let old_val = this.run_for_validation_mut(|this| this.read_scalar(dest)).discard_err();
         this.allow_data_races_mut(move |this| this.write_scalar(val, dest))?;
         this.validate_atomic_store(dest, atomic)?;
         this.buffered_atomic_write(val, dest, atomic, old_val)
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index a8a2491304d..94629964ea6 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -1150,7 +1150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         loop {
             if CTRL_C_RECEIVED.load(Relaxed) {
                 this.machine.handle_abnormal_termination();
-                std::process::exit(1);
+                throw_machine_stop!(TerminationInfo::Interrupted);
             }
             match this.machine.threads.schedule(&this.machine.clock)? {
                 SchedulingAction::ExecuteStep => {
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 1a12d4139c7..014b1299f2d 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -16,6 +16,8 @@ pub enum TerminationInfo {
         leak_check: bool,
     },
     Abort(String),
+    /// Miri was interrupted by a Ctrl+C from the user
+    Interrupted,
     UnsupportedInIsolation(String),
     StackedBorrowsUb {
         msg: String,
@@ -63,6 +65,7 @@ impl fmt::Display for TerminationInfo {
         match self {
             Exit { code, .. } => write!(f, "the evaluated program completed with exit code {code}"),
             Abort(msg) => write!(f, "{msg}"),
+            Interrupted => write!(f, "interpretation was interrupted"),
             UnsupportedInIsolation(msg) => write!(f, "{msg}"),
             Int2PtrWithStrictProvenance =>
                 write!(
@@ -226,6 +229,7 @@ pub fn report_error<'tcx>(
         let title = match info {
             &Exit { code, leak_check } => return Some((code, leak_check)),
             Abort(_) => Some("abnormal termination"),
+            Interrupted => None,
             UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance | UnsupportedForeignItem(_) =>
                 Some("unsupported operation"),
             StackedBorrowsUb { .. } | TreeBorrowsUb { .. } | DataRace { .. } =>
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 36b15dbf623..ed13f670a90 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -434,7 +434,6 @@ pub fn create_ecx<'tcx>(
 /// Evaluates the entry function specified by `entry_id`.
 /// Returns `Some(return_code)` if program execution completed.
 /// Returns `None` if an evaluation error occurred.
-#[expect(clippy::needless_lifetimes)]
 pub fn eval_entry<'tcx>(
     tcx: TyCtxt<'tcx>,
     entry_id: DefId,
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 12e7d0f1a62..29ed94a2e4a 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -14,9 +14,10 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout};
-use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
+use rustc_middle::ty::{self, Binder, FloatTy, FnSig, IntTy, Ty, TyCtxt, UintTy};
 use rustc_session::config::CrateType;
 use rustc_span::{Span, Symbol};
+use rustc_symbol_mangling::mangle_internal_symbol;
 use rustc_target::callconv::{Conv, FnAbi};
 
 use crate::*;
@@ -994,10 +995,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         exp_abi: Conv,
         link_name: Symbol,
         args: &'a [OpTy<'tcx>],
-    ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]>
-    where
-        &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
-    {
+    ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> {
         self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
 
         if abi.c_variadic {
@@ -1015,6 +1013,80 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         )
     }
 
+    /// Check that the given `caller_fn_abi` matches the expected ABI described by
+    /// `callee_abi`, `callee_input_tys`, `callee_output_ty`, and the return the list of
+    /// arguments.
+    fn check_shim_abi<'a, const N: usize>(
+        &mut self,
+        link_name: Symbol,
+        caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
+        callee_abi: ExternAbi,
+        callee_input_tys: [Ty<'tcx>; N],
+        callee_output_ty: Ty<'tcx>,
+        caller_args: &'a [OpTy<'tcx>],
+    ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> {
+        let this = self.eval_context_mut();
+        let mut inputs_and_output = callee_input_tys.to_vec();
+        inputs_and_output.push(callee_output_ty);
+        let fn_sig_binder = Binder::dummy(FnSig {
+            inputs_and_output: this.machine.tcx.mk_type_list(&inputs_and_output),
+            c_variadic: false,
+            // This does not matter for the ABI.
+            safety: Safety::Safe,
+            abi: callee_abi,
+        });
+        let callee_fn_abi = this.fn_abi_of_fn_ptr(fn_sig_binder, Default::default())?;
+
+        this.check_abi_and_shim_symbol_clash(caller_fn_abi, callee_fn_abi.conv, link_name)?;
+
+        if caller_fn_abi.c_variadic {
+            throw_ub_format!(
+                "ABI mismatch: calling a non-variadic function with a variadic caller-side signature"
+            );
+        }
+
+        if callee_fn_abi.fixed_count != caller_fn_abi.fixed_count {
+            throw_ub_format!(
+                "ABI mismatch: expected {} arguments, found {} arguments ",
+                callee_fn_abi.fixed_count,
+                caller_fn_abi.fixed_count
+            );
+        }
+
+        if callee_fn_abi.can_unwind && !caller_fn_abi.can_unwind {
+            throw_ub_format!(
+                "ABI mismatch: callee may unwind, but caller-side signature prohibits unwinding",
+            );
+        }
+
+        if !this.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)? {
+            throw_ub!(AbiMismatchReturn {
+                caller_ty: caller_fn_abi.ret.layout.ty,
+                callee_ty: callee_fn_abi.ret.layout.ty
+            });
+        }
+
+        if let Some(index) = caller_fn_abi
+            .args
+            .iter()
+            .zip(callee_fn_abi.args.iter())
+            .map(|(caller_arg, callee_arg)| this.check_argument_compat(caller_arg, callee_arg))
+            .collect::<InterpResult<'tcx, Vec<bool>>>()?
+            .into_iter()
+            .position(|b| !b)
+        {
+            throw_ub!(AbiMismatchArgument {
+                caller_ty: caller_fn_abi.args[index].layout.ty,
+                callee_ty: callee_fn_abi.args[index].layout.ty
+            });
+        }
+
+        if let Ok(ops) = caller_args.try_into() {
+            return interp_ok(ops);
+        }
+        unreachable!()
+    }
+
     /// Check shim for variadic function.
     /// Returns a tuple that consisting of an array of fixed args, and a slice of varargs.
     fn check_shim_variadic<'a, const N: usize>(
@@ -1187,6 +1259,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         interp_ok(array)
     }
+
+    fn mangle_internal_symbol<'a>(&'a mut self, name: &'static str) -> &'a str
+    where
+        'tcx: 'a,
+    {
+        let this = self.eval_context_mut();
+        let tcx = *this.tcx;
+        this.machine
+            .mangle_internal_symbol_cache
+            .entry(name)
+            .or_insert_with(|| mangle_internal_symbol(tcx, name))
+    }
 }
 
 impl<'tcx> MiriMachine<'tcx> {
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 85fb280a9a9..a3525dcc77a 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -411,9 +411,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 };
                 let res = this.binary_op(op, &a, &b)?;
                 // `binary_op` already called `generate_nan` if needed.
-                // Apply a relative error of 16ULP to simulate non-deterministic precision loss
+                // Apply a relative error of 4ULP to simulate non-deterministic precision loss
                 // due to optimizations.
-                let res = apply_random_float_error_to_imm(this, res, 4 /* log2(16) */)?;
+                let res = apply_random_float_error_to_imm(this, res, 2 /* log2(4) */)?;
                 this.write_immediate(*res, dest)?;
             }
 
@@ -464,9 +464,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 if !float_finite(&res)? {
                     throw_ub_format!("`{intrinsic_name}` intrinsic produced non-finite value as result");
                 }
-                // Apply a relative error of 16ULP to simulate non-deterministic precision loss
+                // Apply a relative error of 4ULP to simulate non-deterministic precision loss
                 // due to optimizations.
-                let res = apply_random_float_error_to_imm(this, res, 4 /* log2(16) */)?;
+                let res = apply_random_float_error_to_imm(this, res, 2 /* log2(4) */)?;
                 this.write_immediate(*res, dest)?;
             }
 
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 9006190cbee..fb99bdc5176 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -611,6 +611,9 @@ pub struct MiriMachine<'tcx> {
     pub(crate) reject_in_isolation_warned: RefCell<FxHashSet<String>>,
     /// Remembers which int2ptr casts we have already warned about.
     pub(crate) int2ptr_warned: RefCell<FxHashSet<Span>>,
+
+    /// Cache for `mangle_internal_symbol`.
+    pub(crate) mangle_internal_symbol_cache: FxHashMap<&'static str, String>,
 }
 
 impl<'tcx> MiriMachine<'tcx> {
@@ -757,6 +760,7 @@ impl<'tcx> MiriMachine<'tcx> {
             native_call_mem_warned: Cell::new(false),
             reject_in_isolation_warned: Default::default(),
             int2ptr_warned: Default::default(),
+            mangle_internal_symbol_cache: Default::default(),
         }
     }
 
@@ -930,6 +934,7 @@ impl VisitProvenance for MiriMachine<'_> {
             native_call_mem_warned: _,
             reject_in_isolation_warned: _,
             int2ptr_warned: _,
+            mangle_internal_symbol_cache: _,
         } = self;
 
         threads.visit_provenance(visit);
@@ -1540,7 +1545,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     fn before_terminator(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
         ecx.machine.basic_block_count += 1u64; // a u64 that is only incremented by 1 will "never" overflow
         ecx.machine.since_gc += 1;
-        // Possibly report our progress.
+        // Possibly report our progress. This will point at the terminator we are about to execute.
         if let Some(report_progress) = ecx.machine.report_progress {
             if ecx.machine.basic_block_count % u64::from(report_progress) == 0 {
                 ecx.emit_diagnostic(NonHaltingDiagnostic::ProgressReport {
@@ -1559,6 +1564,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         }
 
         // These are our preemption points.
+        // (This will only take effect after the terminator has been executed.)
         ecx.maybe_preempt_active_thread();
 
         // Make sure some time passes.
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 03c6081e992..52c16a0c2e2 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -9,10 +9,9 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::AllocInit;
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{Instance, Ty};
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
-use rustc_symbol_mangling::mangle_internal_symbol;
 use rustc_target::callconv::{Conv, FnAbi};
 
 use self::helpers::{ToHost, ToSoft};
@@ -52,7 +51,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         // Some shims forward to other MIR bodies.
         match link_name.as_str() {
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_error_handler") => {
+            name if name == this.mangle_internal_symbol("__rust_alloc_error_handler") => {
                 // Forward to the right symbol that implements this function.
                 let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else {
                     // in real code, this symbol does not exist without an allocator
@@ -60,11 +59,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         "`__rust_alloc_error_handler` cannot be called when no alloc error handler is set"
                     );
                 };
-                let name =
-                    mangle_internal_symbol(*this.tcx, alloc_error_handler_name(handler_kind));
-                let handler = this
-                    .lookup_exported_symbol(Symbol::intern(&name))?
-                    .expect("missing alloc error handler symbol");
+                let name = Symbol::intern(
+                    this.mangle_internal_symbol(alloc_error_handler_name(handler_kind)),
+                );
+                let handler =
+                    this.lookup_exported_symbol(name)?.expect("missing alloc error handler symbol");
                 return interp_ok(Some(handler));
             }
             _ => {}
@@ -138,30 +137,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Find it if it was not cached.
                 let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None;
                 helpers::iter_exported_symbols(tcx, |cnum, def_id| {
+                    let attrs = tcx.codegen_fn_attrs(def_id);
+                    // Skip over imports of items.
                     if tcx.is_foreign_item(def_id) {
-                        // Skip over imports of items
                         return interp_ok(());
                     }
-
-                    let attrs = tcx.codegen_fn_attrs(def_id);
-                    // FIXME use tcx.symbol_name(instance) instead
-                    let symbol_name = if let Some(export_name) = attrs.export_name {
-                        export_name
-                    } else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
-                        || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
+                    // Skip over items without an explicitly defined symbol name.
+                    if !(attrs.export_name.is_some()
+                        || attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
+                        || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL))
                     {
-                        tcx.item_name(def_id)
-                    } else {
-                        // Skip over items without an explicitly defined symbol name.
                         return interp_ok(());
-                    };
-                    let symbol_name =
-                        if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
-                            Symbol::intern(&mangle_internal_symbol(tcx, symbol_name.as_str()))
-                        } else {
-                            symbol_name
-                        };
-                    if symbol_name == link_name {
+                    }
+
+                    let instance = Instance::mono(tcx, def_id);
+                    let symbol_name = tcx.symbol_name(instance).name;
+                    if symbol_name == link_name.as_str() {
                         if let Some((original_instance, original_cnum)) = instance_and_crate {
                             // Make sure we are consistent wrt what is 'first' and 'second'.
                             let original_span = tcx.def_span(original_instance.def_id()).data();
@@ -505,9 +496,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
 
             // Rust allocation
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc")
-                || name == "miri_alloc" =>
-            {
+            name if name == this.mangle_internal_symbol("__rust_alloc") || name == "miri_alloc" => {
                 let default = |ecx: &mut MiriInterpCx<'tcx>| {
                     // Only call `check_shim` when `#[global_allocator]` isn't used. When that
                     // macro is used, we act like no shim exists, so that the exported function can run.
@@ -540,7 +529,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     _ => return this.emulate_allocator(default),
                 }
             }
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_zeroed") => {
+            name if name == this.mangle_internal_symbol("__rust_alloc_zeroed") => {
                 return this.emulate_allocator(|this| {
                     // See the comment for `__rust_alloc` why `check_shim` is only called in the
                     // default case.
@@ -559,7 +548,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this.write_pointer(ptr, dest)
                 });
             }
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_dealloc")
+            name if name == this.mangle_internal_symbol("__rust_dealloc")
                 || name == "miri_dealloc" =>
             {
                 let default = |ecx: &mut MiriInterpCx<'tcx>| {
@@ -592,7 +581,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     _ => return this.emulate_allocator(default),
                 }
             }
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_realloc") => {
+            name if name == this.mangle_internal_symbol("__rust_realloc") => {
                 return this.emulate_allocator(|this| {
                     // See the comment for `__rust_alloc` why `check_shim` is only called in the
                     // default case.
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index fc58d88591f..18af8214876 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -144,7 +144,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Directly return to caller of `try`.
                 StackPopCleanup::Goto {
                     ret: catch_unwind.ret,
-                    unwind: mir::UnwindAction::Continue,
+                    // `catch_fn` must not unwind.
+                    unwind: mir::UnwindAction::Unreachable,
                 },
             )?;
 
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 09757071075..1770b99c0a2 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -1,7 +1,7 @@
 use std::ffi::OsStr;
 use std::str;
 
-use rustc_abi::Size;
+use rustc_abi::{ExternAbi, Size};
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_span::Symbol;
@@ -200,7 +200,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write(fd, buf, count, Some(offset), dest)?;
             }
             "close" => {
-                let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [fd] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.close(fd)?;
                 this.write_scalar(result, dest)?;
             }
diff --git a/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs b/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs
new file mode 100644
index 00000000000..eb8de04dcc4
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs
@@ -0,0 +1,21 @@
+//@ignore-target: windows # File handling is not implemented yet
+//@compile-flags: -Zmiri-disable-isolation
+use std::ffi::{CString, OsStr, c_char, c_int};
+use std::os::unix::ffi::OsStrExt;
+
+extern "C" {
+    fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
+    // correct fd type is i32
+    fn close(fd: u32) -> c_int;
+}
+
+fn main() {
+    let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed");
+    let fd = unsafe {
+        open(c_path.as_ptr(), /* value does not matter */ 0)
+    } as u32;
+    let _ = unsafe {
+        close(fd);
+        //~^ ERROR: calling a function with argument of type i32 passing data of type u32
+    };
+}
diff --git a/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr b/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr
new file mode 100644
index 00000000000..90d4ce78ad4
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr
@@ -0,0 +1,17 @@
+error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32
+  --> tests/fail/shims/input_arg_mismatch.rs:LL:CC
+   |
+LL |         close(fd);
+   |         ^^^^^^^^^ calling a function with argument of type i32 passing data of type u32
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
+   = help: if you think this code should be accepted anyway, please report an issue with Miri
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/shims/input_arg_mismatch.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/fail/shims/return_type_mismatch.rs b/src/tools/miri/tests/fail/shims/return_type_mismatch.rs
new file mode 100644
index 00000000000..6dbdd3f539b
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/return_type_mismatch.rs
@@ -0,0 +1,21 @@
+//@ignore-target: windows # File handling is not implemented yet
+//@compile-flags: -Zmiri-disable-isolation
+use std::ffi::{CString, OsStr, c_char, c_int, c_short};
+use std::os::unix::ffi::OsStrExt;
+
+extern "C" {
+    fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
+    // correct return type is i32
+    fn close(fd: c_int) -> c_short;
+}
+
+fn main() {
+    let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed");
+    let fd = unsafe {
+        open(c_path.as_ptr(), /* value does not matter */ 0)
+    };
+    let _ = unsafe {
+        close(fd);
+        //~^ ERROR: calling a function with return type i32 passing return place of type i16
+    };
+}
diff --git a/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr b/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr
new file mode 100644
index 00000000000..062aa7b4927
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr
@@ -0,0 +1,17 @@
+error: Undefined Behavior: calling a function with return type i32 passing return place of type i16
+  --> tests/fail/shims/return_type_mismatch.rs:LL:CC
+   |
+LL |         close(fd);
+   |         ^^^^^^^^^ calling a function with return type i32 passing return place of type i16
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
+   = help: if you think this code should be accepted anyway, please report an issue with Miri
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/shims/return_type_mismatch.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-dep/concurrency/linux-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
index 0ca13b5039d..f8f1c554f0d 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
@@ -64,7 +64,7 @@ fn wait_wrong_val() {
             ),
             -1,
         );
-        assert_eq!(*libc::__errno_location(), libc::EAGAIN);
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::EAGAIN);
     }
 }
 
@@ -85,7 +85,7 @@ fn wait_timeout() {
             ),
             -1,
         );
-        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
     }
 
     assert!((200..1000).contains(&start.elapsed().as_millis()));
@@ -124,7 +124,7 @@ fn wait_absolute_timeout() {
             ),
             -1,
         );
-        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
     }
 
     assert!((200..1000).contains(&start.elapsed().as_millis()));
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
index 01433edf9a3..d6072c2569e 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
@@ -56,8 +56,7 @@ fn test_pipe_threaded() {
         assert_eq!(res, 5);
         assert_eq!(buf, "abcde".as_bytes());
     });
-    // FIXME: we should yield here once blocking is implemented.
-    //thread::yield_now();
+    thread::yield_now();
     let data = "abcde".as_bytes().as_ptr();
     let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) };
     assert_eq!(res, 5);
@@ -65,14 +64,11 @@ fn test_pipe_threaded() {
 
     // Read and write from different direction
     let thread2 = thread::spawn(move || {
-        // FIXME: we should yield here once blocking is implemented.
-        //thread::yield_now();
+        thread::yield_now();
         let data = "12345".as_bytes().as_ptr();
         let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) };
         assert_eq!(res, 5);
     });
-    // FIXME: we should not yield here once blocking is implemented.
-    thread::yield_now();
     let mut buf: [u8; 5] = [0; 5];
     let res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) };
     assert_eq!(res, 5);
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index b3b6fe1a5d7..05ac5e82b56 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -1281,7 +1281,6 @@ fn test_non_determinism() {
     /// Ensure that the operation is non-deterministic
     #[track_caller]
     fn ensure_nondet<T: PartialEq + std::fmt::Debug>(f: impl Fn() -> T) {
-
         let rounds = 16;
         let first = f();
         for _ in 1..rounds {
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index 0e2239147f1..a7081d4f86a 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -22,12 +22,6 @@ pub fn bare_rustc() -> Rustc {
     Rustc::bare()
 }
 
-/// Construct a new `rustc` aux-build invocation.
-#[track_caller]
-pub fn aux_build() -> Rustc {
-    Rustc::new_aux_build()
-}
-
 /// A `rustc` invocation builder.
 #[derive(Debug)]
 #[must_use]
@@ -67,14 +61,6 @@ impl Rustc {
         Self { cmd }
     }
 
-    /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
-    #[track_caller]
-    pub fn new_aux_build() -> Self {
-        let mut cmd = setup_common();
-        cmd.arg("--crate-type=lib");
-        Self { cmd }
-    }
-
     // Argument provider methods
 
     /// Configure the compilation environment.
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index e0ad3ee9bed..c75d500d2f0 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -17,6 +17,7 @@ pub mod assertion_helpers;
 pub mod diff;
 pub mod env;
 pub mod external_deps;
+pub mod linker;
 pub mod path_helpers;
 pub mod run;
 pub mod scoped_run;
@@ -68,7 +69,7 @@ pub use llvm::{
     LlvmFilecheck, LlvmNm, LlvmObjcopy, LlvmObjdump, LlvmProfdata, LlvmReadobj,
 };
 pub use python::python_command;
-pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
+pub use rustc::{bare_rustc, rustc, rustc_path, Rustc};
 pub use rustdoc::{rustdoc, Rustdoc};
 
 /// [`diff`][mod@diff] is implemented in terms of the [similar] library.
diff --git a/src/tools/run-make-support/src/linker.rs b/src/tools/run-make-support/src/linker.rs
new file mode 100644
index 00000000000..89093cf0113
--- /dev/null
+++ b/src/tools/run-make-support/src/linker.rs
@@ -0,0 +1,36 @@
+use regex::Regex;
+
+use crate::{Rustc, is_msvc};
+
+/// Asserts that `rustc` uses LLD for linking when executed.
+pub fn assert_rustc_uses_lld(rustc: &mut Rustc) {
+    let stderr = get_stderr_with_linker_messages(rustc);
+    assert!(
+        has_lld_version_in_logs(&stderr),
+        "LLD version should be present in rustc stderr:\n{stderr}"
+    );
+}
+
+/// Asserts that `rustc` doesn't use LLD for linking when executed.
+pub fn assert_rustc_doesnt_use_lld(rustc: &mut Rustc) {
+    let stderr = get_stderr_with_linker_messages(rustc);
+    assert!(
+        !has_lld_version_in_logs(&stderr),
+        "LLD version should NOT be present in rustc stderr:\n{stderr}"
+    );
+}
+
+fn get_stderr_with_linker_messages(rustc: &mut Rustc) -> String {
+    // lld-link is used if msvc, otherwise a gnu-compatible lld is used.
+    let linker_version_flag = if is_msvc() { "--version" } else { "-Wl,-v" };
+
+    let output = rustc.arg("-Wlinker-messages").link_arg(linker_version_flag).run();
+    output.stderr_utf8()
+}
+
+fn has_lld_version_in_logs(stderr: &str) -> bool {
+    // Strip the `-Wlinker-messages` wrappers prefixing the linker output.
+    let stderr = Regex::new(r"warning: linker std(out|err):").unwrap().replace_all(&stderr, "");
+    let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
+    stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
+}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
index 9a7a1a01a09..4c4174e2680 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
@@ -665,10 +665,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
     rustc_attr!(TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
     rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing),
-    rustc_attr!(
-        TEST, rustc_error, Normal,
-        template!(Word, List: "delayed_bug_from_inside_query"), WarnFollowingWordOnly
-    ),
     rustc_attr!(TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing),
     rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
     rustc_attr!(
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
index 4e28aaced9b..7668f419040 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
@@ -110,7 +110,7 @@ pub fn read_version(obj: &object::File<'_>) -> io::Result<String> {
         ));
     }
     let version = u32::from_be_bytes([dot_rustc[4], dot_rustc[5], dot_rustc[6], dot_rustc[7]]);
-    // Last supported version is:
+    // Last breaking version change is:
     // https://github.com/rust-lang/rust/commit/b94cfefc860715fb2adf72a6955423d384c69318
     let (mut metadata_portion, bytes_before_version) = match version {
         8 => {
@@ -118,7 +118,7 @@ pub fn read_version(obj: &object::File<'_>) -> io::Result<String> {
             let data_len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize;
             (&dot_rustc[12..data_len + 12], 13)
         }
-        9 => {
+        9 | 10 => {
             let len_bytes = &dot_rustc[8..16];
             let data_len = u64::from_le_bytes(len_bytes.try_into().unwrap()) as usize;
             (&dot_rustc[16..data_len + 12], 17)
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index e54747c129a..08011e1d427 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -97,9 +97,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.95"
+version = "1.0.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
 
 [[package]]
 name = "autocfg"
@@ -124,9 +124,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.8.0"
+version = "2.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
 
 [[package]]
 name = "block-buffer"
@@ -155,16 +155,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
 
 [[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
-[[package]]
 name = "cc"
-version = "1.2.10"
+version = "1.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
+checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
 dependencies = [
  "shlex",
 ]
@@ -177,23 +171,23 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.39"
+version = "0.4.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
+checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
  "js-sys",
  "num-traits",
  "wasm-bindgen",
- "windows-targets",
+ "windows-link",
 ]
 
 [[package]]
 name = "clap"
-version = "4.5.27"
+version = "4.5.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
+checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -201,9 +195,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.27"
+version = "4.5.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
+checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8"
 dependencies = [
  "anstream",
  "anstyle",
@@ -214,18 +208,18 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.43"
+version = "4.5.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0952013545c9c6dca60f491602655b795c6c062ab180c9cb0bccb83135461861"
+checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6"
 dependencies = [
  "clap",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "4.5.24"
+version = "4.5.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
+checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -419,22 +413,22 @@ dependencies = [
 
 [[package]]
 name = "env_logger"
-version = "0.11.6"
+version = "0.11.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0"
+checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697"
 dependencies = [
  "anstream",
  "anstyle",
  "env_filter",
- "humantime",
+ "jiff",
  "log",
 ]
 
 [[package]]
 name = "equivalent"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
 
 [[package]]
 name = "errno"
@@ -461,9 +455,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
 name = "flate2"
-version = "1.0.35"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
+checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
 dependencies = [
  "crc32fast",
  "miniz_oxide",
@@ -515,20 +509,21 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.2.15"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
 dependencies = [
  "cfg-if",
  "libc",
+ "r-efi",
  "wasi",
 ]
 
 [[package]]
 name = "handlebars"
-version = "6.3.0"
+version = "6.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6b224b95c1e668ac0270325ad563b2eef1469fbbb8959bc7c692c844b813d9"
+checksum = "759e2d5aea3287cb1190c8ec394f42866cb5bf74fcbf213f354e3c856ea26098"
 dependencies = [
  "derive_builder",
  "log",
@@ -537,7 +532,7 @@ dependencies = [
  "pest_derive",
  "serde",
  "serde_json",
- "thiserror 2.0.11",
+ "thiserror 2.0.12",
 ]
 
 [[package]]
@@ -588,12 +583,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "humantime"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
-
-[[package]]
 name = "iana-time-zone"
 version = "0.1.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -763,9 +752,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.7.1"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
+checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -779,9 +768,33 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
 
 [[package]]
 name = "itoa"
-version = "1.0.14"
+version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "jiff"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260"
+dependencies = [
+ "jiff-static",
+ "log",
+ "portable-atomic",
+ "portable-atomic-util",
+ "serde",
+]
+
+[[package]]
+name = "jiff-static"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
 
 [[package]]
 name = "js-sys"
@@ -801,9 +814,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.169"
+version = "0.2.171"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
 
 [[package]]
 name = "libdbus-sys"
@@ -826,15 +839,15 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.15"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
 
 [[package]]
 name = "litemap"
-version = "0.7.4"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
+checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
 
 [[package]]
 name = "lock_api"
@@ -848,9 +861,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.25"
+version = "0.4.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
+checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
 
 [[package]]
 name = "mac"
@@ -880,9 +893,9 @@ dependencies = [
 
 [[package]]
 name = "mdbook"
-version = "0.4.47"
+version = "0.4.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e1a8fe3a4a01f28dab245c474cb7b95ccb4d3d2f17a5419a3d949f474c45e84"
+checksum = "8b6fbb4ac2d9fd7aa987c3510309ea3c80004a968d063c42f0d34fea070817c1"
 dependencies = [
  "ammonia",
  "anyhow",
@@ -910,17 +923,17 @@ dependencies = [
 
 [[package]]
 name = "mdbook-i18n-helpers"
-version = "0.3.5"
+version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cac78e4f518f326e5fc1ff95e79e7e0e58330cb8ac6e4b559d9659cf69bb1ab"
+checksum = "5644bf29b95683ea60979e30188221c374965c3a1dc0ad2d5c69e867dc0c09dc"
 dependencies = [
  "anyhow",
  "chrono",
  "dateparser",
  "mdbook",
  "polib",
- "pulldown-cmark 0.11.3",
- "pulldown-cmark-to-cmark 15.0.1",
+ "pulldown-cmark 0.12.2",
+ "pulldown-cmark-to-cmark 20.0.1",
  "regex",
  "semver",
  "serde_json",
@@ -956,7 +969,7 @@ dependencies = [
  "pulldown-cmark-to-cmark 19.0.1",
  "serde_json",
  "thiserror 1.0.69",
- "toml 0.8.19",
+ "toml 0.8.20",
 ]
 
 [[package]]
@@ -967,9 +980,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.3"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
+checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
 dependencies = [
  "adler2",
 ]
@@ -1015,9 +1028,9 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.20.2"
+version = "1.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
 
 [[package]]
 name = "onig"
@@ -1095,7 +1108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
 dependencies = [
  "memchr",
- "thiserror 2.0.11",
+ "thiserror 2.0.12",
  "ucd-trie",
 ]
 
@@ -1139,7 +1152,7 @@ version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
 dependencies = [
- "phf_shared 0.11.3",
+ "phf_shared",
 ]
 
 [[package]]
@@ -1148,18 +1161,8 @@ version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
 dependencies = [
- "phf_generator 0.11.3",
- "phf_shared 0.11.3",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
-dependencies = [
- "phf_shared 0.10.0",
- "rand",
+ "phf_generator",
+ "phf_shared",
 ]
 
 [[package]]
@@ -1168,33 +1171,24 @@ version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
 dependencies = [
- "phf_shared 0.11.3",
+ "phf_shared",
  "rand",
 ]
 
 [[package]]
 name = "phf_shared"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
-dependencies = [
- "siphasher 0.3.11",
-]
-
-[[package]]
-name = "phf_shared"
 version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
 dependencies = [
- "siphasher 1.0.1",
+ "siphasher",
 ]
 
 [[package]]
 name = "pkg-config"
-version = "0.3.31"
+version = "0.3.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
 
 [[package]]
 name = "polib"
@@ -1206,12 +1200,18 @@ dependencies = [
 ]
 
 [[package]]
-name = "ppv-lite86"
-version = "0.2.20"
+name = "portable-atomic"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
+
+[[package]]
+name = "portable-atomic-util"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
 dependencies = [
- "zerocopy",
+ "portable-atomic",
 ]
 
 [[package]]
@@ -1222,9 +1222,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.93"
+version = "1.0.94"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
 dependencies = [
  "unicode-ident",
 ]
@@ -1235,7 +1235,7 @@ version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993"
 dependencies = [
- "bitflags 2.8.0",
+ "bitflags 2.9.0",
  "memchr",
  "pulldown-cmark-escape 0.10.1",
  "unicase",
@@ -1243,23 +1243,11 @@ dependencies = [
 
 [[package]]
 name = "pulldown-cmark"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
-dependencies = [
- "bitflags 2.8.0",
- "memchr",
- "pulldown-cmark-escape 0.11.0",
- "unicase",
-]
-
-[[package]]
-name = "pulldown-cmark"
 version = "0.12.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
 dependencies = [
- "bitflags 2.8.0",
+ "bitflags 2.9.0",
  "getopts",
  "memchr",
  "pulldown-cmark-escape 0.11.0",
@@ -1280,49 +1268,43 @@ checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
 
 [[package]]
 name = "pulldown-cmark-to-cmark"
-version = "15.0.1"
+version = "19.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9c77db841443d89a57ae94f22d29c022f6d9f41b00bddbf1f4024dbaf4bdce1"
+checksum = "e84a87de49d1b6c63f0998da7ade299905387ae1feae350efc98e0632637f589"
 dependencies = [
- "pulldown-cmark 0.11.3",
+ "pulldown-cmark 0.12.2",
 ]
 
 [[package]]
 name = "pulldown-cmark-to-cmark"
-version = "19.0.1"
+version = "20.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e84a87de49d1b6c63f0998da7ade299905387ae1feae350efc98e0632637f589"
+checksum = "6c0f333311d2d8fda65bcf76af35054e9f38e253332a0289746156a59656988b"
 dependencies = [
  "pulldown-cmark 0.12.2",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
-name = "rand"
-version = "0.8.5"
+name = "r-efi"
+version = "5.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha",
- "rand_core",
-]
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
 
 [[package]]
-name = "rand_chacha"
-version = "0.3.1"
+name = "rand"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
- "ppv-lite86",
  "rand_core",
 ]
 
@@ -1331,17 +1313,14 @@ name = "rand_core"
 version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-dependencies = [
- "getrandom",
-]
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.8"
+version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
+checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
 dependencies = [
- "bitflags 2.8.0",
+ "bitflags 2.9.0",
 ]
 
 [[package]]
@@ -1387,11 +1366,11 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.44"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
+checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96"
 dependencies = [
- "bitflags 2.8.0",
+ "bitflags 2.9.0",
  "errno",
  "libc",
  "linux-raw-sys",
@@ -1400,15 +1379,15 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.19"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
+checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
 
 [[package]]
 name = "ryu"
-version = "1.0.19"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
 [[package]]
 name = "same-file"
@@ -1427,24 +1406,24 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
 [[package]]
 name = "semver"
-version = "1.0.25"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
+checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
 
 [[package]]
 name = "serde"
-version = "1.0.217"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.217"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1453,9 +1432,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.138"
+version = "1.0.140"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
 dependencies = [
  "itoa",
  "memchr",
@@ -1491,21 +1470,15 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
 name = "siphasher"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
-
-[[package]]
-name = "siphasher"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
 
 [[package]]
 name = "smallvec"
-version = "1.13.2"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
 
 [[package]]
 name = "stable_deref_trait"
@@ -1515,26 +1488,25 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 
 [[package]]
 name = "string_cache"
-version = "0.8.7"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
+checksum = "938d512196766101d333398efde81bc1f37b00cb42c2f8350e5df639f040bbbe"
 dependencies = [
  "new_debug_unreachable",
- "once_cell",
  "parking_lot",
- "phf_shared 0.10.0",
+ "phf_shared",
  "precomputed-hash",
  "serde",
 ]
 
 [[package]]
 name = "string_cache_codegen"
-version = "0.5.2"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
+checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
 dependencies = [
- "phf_generator 0.10.0",
- "phf_shared 0.10.0",
+ "phf_generator",
+ "phf_shared",
  "proc-macro2",
  "quote",
 ]
@@ -1547,9 +1519,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.96"
+version = "2.0.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1589,11 +1561,10 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.15.0"
+version = "3.19.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
 dependencies = [
- "cfg-if",
  "fastrand",
  "getrandom",
  "once_cell",
@@ -1614,9 +1585,9 @@ dependencies = [
 
 [[package]]
 name = "terminal_size"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9"
+checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed"
 dependencies = [
  "rustix",
  "windows-sys",
@@ -1624,9 +1595,9 @@ dependencies = [
 
 [[package]]
 name = "textwrap"
-version = "0.16.1"
+version = "0.16.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
+checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
 
 [[package]]
 name = "thiserror"
@@ -1639,11 +1610,11 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "2.0.11"
+version = "2.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
 dependencies = [
- "thiserror-impl 2.0.11",
+ "thiserror-impl 2.0.12",
 ]
 
 [[package]]
@@ -1659,9 +1630,9 @@ dependencies = [
 
 [[package]]
 name = "thiserror-impl"
-version = "2.0.11"
+version = "2.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1689,9 +1660,9 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.8.19"
+version = "0.8.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
+checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -1710,9 +1681,9 @@ dependencies = [
 
 [[package]]
 name = "toml_edit"
-version = "0.22.22"
+version = "0.22.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
+checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
 dependencies = [
  "indexmap",
  "serde",
@@ -1729,9 +1700,9 @@ checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d"
 
 [[package]]
 name = "typenum"
-version = "1.17.0"
+version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
 
 [[package]]
 name = "ucd-trie"
@@ -1747,9 +1718,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.16"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "unicode-width"
@@ -1810,9 +1781,12 @@ dependencies = [
 
 [[package]]
 name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+version = "0.14.2+wasi-0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
 
 [[package]]
 name = "wasm-bindgen"
@@ -1913,6 +1887,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "windows-link"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+
+[[package]]
 name = "windows-sys"
 version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1987,14 +1967,23 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
 name = "winnow"
-version = "0.6.25"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310"
+checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags 2.9.0",
+]
+
+[[package]]
 name = "write16"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2031,40 +2020,19 @@ dependencies = [
 ]
 
 [[package]]
-name = "zerocopy"
-version = "0.7.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
-dependencies = [
- "byteorder",
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.7.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
 name = "zerofrom"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
 dependencies = [
  "zerofrom-derive",
 ]
 
 [[package]]
 name = "zerofrom-derive"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index 831233e3065..a0b220c3557 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -15,6 +15,6 @@ mdbook-i18n-helpers = "0.3.3"
 mdbook-spec = { path = "../../doc/reference/mdbook-spec" }
 
 [dependencies.mdbook]
-version = "0.4.47"
+version = "0.4.48"
 default-features = false
 features = ["search"]
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index ea575f27799..f70fc917770 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -451,7 +451,7 @@ function loadSearchJS(doc_folder, resource_suffix) {
                         if (!Object.prototype.hasOwnProperty.call(entry, key)) {
                             continue;
                         }
-                        if (key === "displayTypeSignature") {
+                        if (key === "displayTypeSignature" && entry.displayTypeSignature !== null) {
                             const {type, mappedNames, whereClause} =
                                 await entry.displayTypeSignature;
                             entry.displayType = arrayToCode(type);
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index e866f13efc7..be6b483bfff 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -246,7 +246,7 @@ pub(crate) fn format_expr(
         | ast::ExprKind::Await(_, _)
         | ast::ExprKind::Yield(ast::YieldKind::Postfix(_)) => rewrite_chain(expr, context, shape),
         ast::ExprKind::MacCall(ref mac) => {
-            rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|_| {
+            rewrite_macro(mac, context, shape, MacroPosition::Expression).or_else(|_| {
                 wrap_str(
                     context.snippet(expr.span).to_owned(),
                     context.config.max_width(),
@@ -2058,7 +2058,7 @@ fn rewrite_assignment(
     context: &RewriteContext<'_>,
     lhs: &ast::Expr,
     rhs: &ast::Expr,
-    op: Option<&ast::BinOp>,
+    op: Option<&ast::AssignOp>,
     shape: Shape,
 ) -> RewriteResult {
     let operator_str = match op {
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 3fb3284e3d7..322af97d9dc 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -6,7 +6,7 @@ use std::cmp::{Ordering, max, min};
 use regex::Regex;
 use rustc_ast::visit;
 use rustc_ast::{ast, ptr};
-use rustc_span::{BytePos, DUMMY_SP, Span, symbol};
+use rustc_span::{BytePos, DUMMY_SP, Ident, Span, symbol};
 use tracing::debug;
 
 use crate::attr::filter_inline_attrs;
@@ -333,12 +333,12 @@ impl<'a> FnSig<'a> {
         defaultness: ast::Defaultness,
     ) -> FnSig<'a> {
         match *fn_kind {
-            visit::FnKind::Fn(visit::FnCtxt::Assoc(..), _, vis, ast::Fn { sig, generics, .. }) => {
+            visit::FnKind::Fn(visit::FnCtxt::Assoc(..), vis, ast::Fn { sig, generics, .. }) => {
                 let mut fn_sig = FnSig::from_method_sig(sig, generics, vis);
                 fn_sig.defaultness = defaultness;
                 fn_sig
             }
-            visit::FnKind::Fn(_, _, vis, ast::Fn { sig, generics, .. }) => FnSig {
+            visit::FnKind::Fn(_, vis, ast::Fn { sig, generics, .. }) => FnSig {
                 decl,
                 generics,
                 ext: sig.header.ext,
@@ -750,11 +750,10 @@ impl<'a> FmtVisitor<'a> {
                 (Type(lty), Type(rty))
                     if both_type(&lty.ty, &rty.ty) || both_opaque(&lty.ty, &rty.ty) =>
                 {
-                    a.ident.as_str().cmp(b.ident.as_str())
-                }
-                (Const(..), Const(..)) | (MacCall(..), MacCall(..)) => {
-                    a.ident.as_str().cmp(b.ident.as_str())
+                    lty.ident.as_str().cmp(rty.ident.as_str())
                 }
+                (Const(ca), Const(cb)) => ca.ident.as_str().cmp(cb.ident.as_str()),
+                (MacCall(..), MacCall(..)) => Ordering::Equal,
                 (Fn(..), Fn(..)) | (Delegation(..), Delegation(..)) => {
                     a.span.lo().cmp(&b.span.lo())
                 }
@@ -1105,14 +1104,16 @@ impl<'a> StructParts<'a> {
     }
 
     pub(crate) fn from_item(item: &'a ast::Item) -> Self {
-        let (prefix, def, generics) = match item.kind {
-            ast::ItemKind::Struct(ref def, ref generics) => ("struct ", def, generics),
-            ast::ItemKind::Union(ref def, ref generics) => ("union ", def, generics),
+        let (prefix, def, ident, generics) = match item.kind {
+            ast::ItemKind::Struct(ident, ref def, ref generics) => {
+                ("struct ", def, ident, generics)
+            }
+            ast::ItemKind::Union(ident, ref def, ref generics) => ("union ", def, ident, generics),
             _ => unreachable!(),
         };
         StructParts {
             prefix,
-            ident: item.ident,
+            ident,
             vis: &item.vis,
             def,
             generics: Some(generics),
@@ -1168,6 +1169,7 @@ pub(crate) fn format_trait(
     let ast::Trait {
         is_auto,
         safety,
+        ident,
         ref generics,
         ref bounds,
         ref items,
@@ -1186,13 +1188,13 @@ pub(crate) fn format_trait(
 
     let shape = Shape::indented(offset, context.config).offset_left(result.len())?;
     let generics_str =
-        rewrite_generics(context, rewrite_ident(context, item.ident), generics, shape).ok()?;
+        rewrite_generics(context, rewrite_ident(context, ident), generics, shape).ok()?;
     result.push_str(&generics_str);
 
     // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds.
     if !bounds.is_empty() {
         // Retrieve *unnormalized* ident (See #6069)
-        let source_ident = context.snippet(item.ident.span);
+        let source_ident = context.snippet(ident.span);
         let ident_hi = context.snippet_provider.span_after(item.span, source_ident);
         let bound_hi = bounds.last().unwrap().span().hi();
         let snippet = context.snippet(mk_sp(ident_hi, bound_hi));
@@ -1679,11 +1681,12 @@ fn format_tuple_struct(
     Some(result)
 }
 
-pub(crate) enum ItemVisitorKind<'a> {
-    Item(&'a ast::Item),
-    AssocTraitItem(&'a ast::AssocItem),
-    AssocImplItem(&'a ast::AssocItem),
-    ForeignItem(&'a ast::ForeignItem),
+#[derive(Clone, Copy)]
+pub(crate) enum ItemVisitorKind {
+    Item,
+    AssocTraitItem,
+    AssocImplItem,
+    ForeignItem,
 }
 
 struct TyAliasRewriteInfo<'c, 'g>(
@@ -1695,17 +1698,19 @@ struct TyAliasRewriteInfo<'c, 'g>(
     Span,
 );
 
-pub(crate) fn rewrite_type_alias<'a, 'b>(
+pub(crate) fn rewrite_type_alias<'a>(
     ty_alias_kind: &ast::TyAlias,
+    vis: &ast::Visibility,
     context: &RewriteContext<'a>,
     indent: Indent,
-    visitor_kind: &ItemVisitorKind<'b>,
+    visitor_kind: ItemVisitorKind,
     span: Span,
 ) -> RewriteResult {
     use ItemVisitorKind::*;
 
     let ast::TyAlias {
         defaultness,
+        ident,
         ref generics,
         ref bounds,
         ref ty,
@@ -1715,11 +1720,6 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
     let rhs_hi = ty
         .as_ref()
         .map_or(where_clauses.before.span.hi(), |ty| ty.span.hi());
-    let (ident, vis) = match visitor_kind {
-        Item(i) => (i.ident, &i.vis),
-        AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis),
-        ForeignItem(i) => (i.ident, &i.vis),
-    };
     let rw_info = &TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span);
     let op_ty = opaque_ty(ty);
     // Type Aliases are formatted slightly differently depending on the context
@@ -1727,14 +1727,14 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
     // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html
     // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases
     match (visitor_kind, &op_ty) {
-        (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(op_bounds)) => {
+        (Item | AssocTraitItem | ForeignItem, Some(op_bounds)) => {
             let op = OpaqueType { bounds: op_bounds };
             rewrite_ty(rw_info, Some(bounds), Some(&op), rhs_hi, vis)
         }
-        (Item(_) | AssocTraitItem(_) | ForeignItem(_), None) => {
+        (Item | AssocTraitItem | ForeignItem, None) => {
             rewrite_ty(rw_info, Some(bounds), ty_opt, rhs_hi, vis)
         }
-        (AssocImplItem(_), _) => {
+        (AssocImplItem, _) => {
             let result = if let Some(op_bounds) = op_ty {
                 let op = OpaqueType { bounds: op_bounds };
                 rewrite_ty(
@@ -2024,14 +2024,23 @@ pub(crate) struct StaticParts<'a> {
 
 impl<'a> StaticParts<'a> {
     pub(crate) fn from_item(item: &'a ast::Item) -> Self {
-        let (defaultness, prefix, safety, ty, mutability, expr, generics) = match &item.kind {
-            ast::ItemKind::Static(s) => {
-                (None, "static", s.safety, &s.ty, s.mutability, &s.expr, None)
-            }
+        let (defaultness, prefix, safety, ident, ty, mutability, expr, generics) = match &item.kind
+        {
+            ast::ItemKind::Static(s) => (
+                None,
+                "static",
+                s.safety,
+                s.ident,
+                &s.ty,
+                s.mutability,
+                &s.expr,
+                None,
+            ),
             ast::ItemKind::Const(c) => (
                 Some(c.defaultness),
                 "const",
                 ast::Safety::Default,
+                c.ident,
                 &c.ty,
                 ast::Mutability::Not,
                 &c.expr,
@@ -2043,7 +2052,7 @@ impl<'a> StaticParts<'a> {
             prefix,
             safety,
             vis: &item.vis,
-            ident: item.ident,
+            ident,
             generics,
             ty,
             mutability,
@@ -2053,7 +2062,7 @@ impl<'a> StaticParts<'a> {
         }
     }
 
-    pub(crate) fn from_trait_item(ti: &'a ast::AssocItem) -> Self {
+    pub(crate) fn from_trait_item(ti: &'a ast::AssocItem, ident: Ident) -> Self {
         let (defaultness, ty, expr_opt, generics) = match &ti.kind {
             ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)),
             _ => unreachable!(),
@@ -2062,7 +2071,7 @@ impl<'a> StaticParts<'a> {
             prefix: "const",
             safety: ast::Safety::Default,
             vis: &ti.vis,
-            ident: ti.ident,
+            ident,
             generics,
             ty,
             mutability: ast::Mutability::Not,
@@ -2072,7 +2081,7 @@ impl<'a> StaticParts<'a> {
         }
     }
 
-    pub(crate) fn from_impl_item(ii: &'a ast::AssocItem) -> Self {
+    pub(crate) fn from_impl_item(ii: &'a ast::AssocItem, ident: Ident) -> Self {
         let (defaultness, ty, expr, generics) = match &ii.kind {
             ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)),
             _ => unreachable!(),
@@ -2081,7 +2090,7 @@ impl<'a> StaticParts<'a> {
             prefix: "const",
             safety: ast::Safety::Default,
             vis: &ii.vis,
-            ident: ii.ident,
+            ident,
             generics,
             ty,
             mutability: ast::Mutability::Not,
@@ -3442,6 +3451,7 @@ impl Rewrite for ast::ForeignItem {
                 let ast::Fn {
                     defaultness,
                     ref sig,
+                    ident,
                     ref generics,
                     ref body,
                     ..
@@ -3453,7 +3463,8 @@ impl Rewrite for ast::ForeignItem {
                     let inner_attrs = inner_attributes(&self.attrs);
                     let fn_ctxt = visit::FnCtxt::Foreign;
                     visitor.visit_fn(
-                        visit::FnKind::Fn(fn_ctxt, &self.ident, &self.vis, fn_kind),
+                        ident,
+                        visit::FnKind::Fn(fn_ctxt, &self.vis, fn_kind),
                         &sig.decl,
                         self.span,
                         defaultness,
@@ -3464,7 +3475,7 @@ impl Rewrite for ast::ForeignItem {
                     rewrite_fn_base(
                         context,
                         shape.indent,
-                        self.ident,
+                        ident,
                         &FnSig::from_method_sig(sig, generics, &self.vis),
                         span,
                         FnBraceStyle::None,
@@ -3483,7 +3494,7 @@ impl Rewrite for ast::ForeignItem {
                     vis,
                     safety,
                     mut_str,
-                    rewrite_ident(context, self.ident)
+                    rewrite_ident(context, static_foreign_item.ident)
                 );
                 // 1 = ;
                 rewrite_assign_rhs(
@@ -3498,11 +3509,11 @@ impl Rewrite for ast::ForeignItem {
                 .map(|s| s + ";")
             }
             ast::ForeignItemKind::TyAlias(ref ty_alias) => {
-                let (kind, span) = (&ItemVisitorKind::ForeignItem(self), self.span);
-                rewrite_type_alias(ty_alias, context, shape.indent, kind, span)
+                let kind = ItemVisitorKind::ForeignItem;
+                rewrite_type_alias(ty_alias, &self.vis, context, shape.indent, kind, self.span)
             }
             ast::ForeignItemKind::MacCall(ref mac) => {
-                rewrite_macro(mac, None, context, shape, MacroPosition::Item)
+                rewrite_macro(mac, context, shape, MacroPosition::Item)
             }
         }?;
 
@@ -3562,12 +3573,13 @@ fn rewrite_attrs(
 pub(crate) fn rewrite_mod(
     context: &RewriteContext<'_>,
     item: &ast::Item,
+    ident: Ident,
     attrs_shape: Shape,
 ) -> Option<String> {
     let mut result = String::with_capacity(32);
     result.push_str(&*format_visibility(context, &item.vis));
     result.push_str("mod ");
-    result.push_str(rewrite_ident(context, item.ident));
+    result.push_str(rewrite_ident(context, ident));
     result.push(';');
     rewrite_attrs(context, item, &result, attrs_shape)
 }
@@ -3594,7 +3606,7 @@ pub(crate) fn rewrite_extern_crate(
 pub(crate) fn is_mod_decl(item: &ast::Item) -> bool {
     !matches!(
         item.kind,
-        ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _))
+        ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _))
     )
 }
 
diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs
index e239ff47c04..ddf3d2ce96a 100644
--- a/src/tools/rustfmt/src/macros.rs
+++ b/src/tools/rustfmt/src/macros.rs
@@ -16,10 +16,7 @@ use rustc_ast::token::{Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree};
 use rustc_ast::{ast, ptr};
 use rustc_ast_pretty::pprust;
-use rustc_span::{
-    BytePos, DUMMY_SP, Span, Symbol,
-    symbol::{self, kw},
-};
+use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol};
 use tracing::debug;
 
 use crate::comment::{
@@ -60,7 +57,7 @@ pub(crate) enum MacroArg {
     Ty(ptr::P<ast::Ty>),
     Pat(ptr::P<ast::Pat>),
     Item(ptr::P<ast::Item>),
-    Keyword(symbol::Ident, Span),
+    Keyword(Ident, Span),
 }
 
 impl MacroArg {
@@ -103,20 +100,12 @@ impl Rewrite for MacroArg {
 }
 
 /// Rewrite macro name without using pretty-printer if possible.
-fn rewrite_macro_name(
-    context: &RewriteContext<'_>,
-    path: &ast::Path,
-    extra_ident: Option<symbol::Ident>,
-) -> String {
-    let name = if path.segments.len() == 1 {
+fn rewrite_macro_name(context: &RewriteContext<'_>, path: &ast::Path) -> String {
+    if path.segments.len() == 1 {
         // Avoid using pretty-printer in the common case.
         format!("{}!", rewrite_ident(context, path.segments[0].ident))
     } else {
         format!("{}!", pprust::path_to_string(path))
-    };
-    match extra_ident {
-        Some(ident) if ident.name != kw::Empty => format!("{name} {ident}"),
-        _ => name,
     }
 }
 
@@ -165,7 +154,6 @@ fn return_macro_parse_failure_fallback(
 
 pub(crate) fn rewrite_macro(
     mac: &ast::MacCall,
-    extra_ident: Option<symbol::Ident>,
     context: &RewriteContext<'_>,
     shape: Shape,
     position: MacroPosition,
@@ -179,14 +167,7 @@ pub(crate) fn rewrite_macro(
     } else {
         let guard = context.enter_macro();
         let result = catch_unwind(AssertUnwindSafe(|| {
-            rewrite_macro_inner(
-                mac,
-                extra_ident,
-                context,
-                shape,
-                position,
-                guard.is_nested(),
-            )
+            rewrite_macro_inner(mac, context, shape, position, guard.is_nested())
         }));
         match result {
             Err(..) => {
@@ -207,7 +188,6 @@ pub(crate) fn rewrite_macro(
 
 fn rewrite_macro_inner(
     mac: &ast::MacCall,
-    extra_ident: Option<symbol::Ident>,
     context: &RewriteContext<'_>,
     shape: Shape,
     position: MacroPosition,
@@ -222,7 +202,7 @@ fn rewrite_macro_inner(
 
     let original_style = macro_style(mac, context);
 
-    let macro_name = rewrite_macro_name(context, &mac.path, extra_ident);
+    let macro_name = rewrite_macro_name(context, &mac.path);
     let is_forced_bracket = FORCED_BRACKET_MACROS.contains(&&macro_name[..]);
 
     let style = if is_forced_bracket && !is_nested_macro {
@@ -432,7 +412,7 @@ pub(crate) fn rewrite_macro_def(
     shape: Shape,
     indent: Indent,
     def: &ast::MacroDef,
-    ident: symbol::Ident,
+    ident: Ident,
     vis: &ast::Visibility,
     span: Span,
 ) -> RewriteResult {
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index a40ee7f66a9..bc5a6d3e704 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -152,7 +152,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
         let mut visitor = visitor::CfgIfVisitor::new(self.psess);
         visitor.visit_item(&item);
         for module_item in visitor.mods() {
-            if let ast::ItemKind::Mod(_, ref sub_mod_kind) = module_item.item.kind {
+            if let ast::ItemKind::Mod(_, _, ref sub_mod_kind) = module_item.item.kind {
                 self.visit_sub_mod(
                     &module_item.item,
                     Module::new(
@@ -178,7 +178,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
                 continue;
             }
 
-            if let ast::ItemKind::Mod(_, ref sub_mod_kind) = item.kind {
+            if let ast::ItemKind::Mod(_, _, ref sub_mod_kind) = item.kind {
                 let span = item.span;
                 self.visit_sub_mod(
                     &item,
@@ -204,7 +204,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
                 self.visit_cfg_if(Cow::Borrowed(item))?;
             }
 
-            if let ast::ItemKind::Mod(_, ref sub_mod_kind) = item.kind {
+            if let ast::ItemKind::Mod(_, _, ref sub_mod_kind) = item.kind {
                 let span = item.span;
                 self.visit_sub_mod(
                     item,
@@ -248,7 +248,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
         if is_mod_decl(item) {
             // mod foo;
             // Look for an extern file.
-            self.find_external_module(item.ident, &item.attrs, sub_mod)
+            self.find_external_module(item.kind.ident().unwrap(), &item.attrs, sub_mod)
         } else {
             // An internal module (`mod foo { /* ... */ }`);
             Ok(Some(SubModKind::Internal(item)))
@@ -291,7 +291,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
                 self.visit_sub_mod_after_directory_update(sub_mod, Some(directory))
             }
             SubModKind::Internal(item) => {
-                self.push_inline_mod_directory(item.ident, &item.attrs);
+                self.push_inline_mod_directory(item.kind.ident().unwrap(), &item.attrs);
                 self.visit_sub_mod_after_directory_update(sub_mod, None)
             }
             SubModKind::MultiExternal(mods) => {
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index bafed41e39f..8dc94574503 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -307,9 +307,7 @@ impl Rewrite for Pat {
                 context,
                 shape,
             ),
-            PatKind::MacCall(ref mac) => {
-                rewrite_macro(mac, None, context, shape, MacroPosition::Pat)
-            }
+            PatKind::MacCall(ref mac) => rewrite_macro(mac, context, shape, MacroPosition::Pat),
             PatKind::Paren(ref pat) => pat
                 .rewrite_result(
                     context,
diff --git a/src/tools/rustfmt/src/reorder.rs b/src/tools/rustfmt/src/reorder.rs
index 8a31e0ac816..2460b61698c 100644
--- a/src/tools/rustfmt/src/reorder.rs
+++ b/src/tools/rustfmt/src/reorder.rs
@@ -25,14 +25,17 @@ use crate::visitor::FmtVisitor;
 /// Choose the ordering between the given two items.
 fn compare_items(a: &ast::Item, b: &ast::Item) -> Ordering {
     match (&a.kind, &b.kind) {
-        (&ast::ItemKind::Mod(..), &ast::ItemKind::Mod(..)) => {
-            a.ident.as_str().cmp(b.ident.as_str())
+        (&ast::ItemKind::Mod(_, a_ident, _), &ast::ItemKind::Mod(_, b_ident, _)) => {
+            a_ident.as_str().cmp(b_ident.as_str())
         }
-        (&ast::ItemKind::ExternCrate(ref a_name), &ast::ItemKind::ExternCrate(ref b_name)) => {
+        (
+            &ast::ItemKind::ExternCrate(ref a_name, a_ident),
+            &ast::ItemKind::ExternCrate(ref b_name, b_ident),
+        ) => {
             // `extern crate foo as bar;`
             //               ^^^ Comparing this.
-            let a_orig_name = a_name.unwrap_or(a.ident.name);
-            let b_orig_name = b_name.unwrap_or(b.ident.name);
+            let a_orig_name = a_name.unwrap_or(a_ident.name);
+            let b_orig_name = b_name.unwrap_or(b_ident.name);
             let result = a_orig_name.as_str().cmp(b_orig_name.as_str());
             if result != Ordering::Equal {
                 return result;
@@ -44,7 +47,7 @@ fn compare_items(a: &ast::Item, b: &ast::Item) -> Ordering {
                 (Some(..), None) => Ordering::Greater,
                 (None, Some(..)) => Ordering::Less,
                 (None, None) => Ordering::Equal,
-                (Some(..), Some(..)) => a.ident.as_str().cmp(b.ident.as_str()),
+                (Some(..), Some(..)) => a_ident.as_str().cmp(b_ident.as_str()),
             }
         }
         _ => unreachable!(),
@@ -69,7 +72,7 @@ fn rewrite_reorderable_item(
 ) -> Option<String> {
     match item.kind {
         ast::ItemKind::ExternCrate(..) => rewrite_extern_crate(context, item, shape),
-        ast::ItemKind::Mod(..) => rewrite_mod(context, item, shape),
+        ast::ItemKind::Mod(_, ident, _) => rewrite_mod(context, item, ident, shape),
         _ => None,
     }
 }
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 06a67334086..75a5a8532b8 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -1018,7 +1018,7 @@ impl Rewrite for ast::Ty {
             ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape),
             ast::TyKind::Never => Ok(String::from("!")),
             ast::TyKind::MacCall(ref mac) => {
-                rewrite_macro(mac, None, context, shape, MacroPosition::Expression)
+                rewrite_macro(mac, context, shape, MacroPosition::Expression)
             }
             ast::TyKind::ImplicitSelf => Ok(String::from("")),
             ast::TyKind::ImplTrait(_, ref it) => {
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index 5749d8c63fa..16d1f5105d5 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -3,7 +3,7 @@ use std::rc::Rc;
 use std::sync::Arc;
 
 use rustc_ast::{ast, token::Delimiter, visit};
-use rustc_span::{BytePos, Pos, Span, symbol};
+use rustc_span::{BytePos, Ident, Pos, Span, symbol};
 use tracing::debug;
 
 use crate::attr::*;
@@ -172,7 +172,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                         get_span_without_attrs(stmt.as_ast_node()),
                     );
                 } else {
-                    self.visit_mac(&mac_stmt.mac, None, MacroPosition::Statement);
+                    self.visit_mac(&mac_stmt.mac, MacroPosition::Statement);
                 }
                 self.format_missing(stmt.span().hi());
             }
@@ -377,6 +377,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
     // on traits do not get handled here.
     pub(crate) fn visit_fn(
         &mut self,
+        ident: Ident,
         fk: visit::FnKind<'_>,
         fd: &ast::FnDecl,
         s: Span,
@@ -388,7 +389,6 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         let rewrite = match fk {
             visit::FnKind::Fn(
                 _,
-                ident,
                 _,
                 ast::Fn {
                     body: Some(ref b), ..
@@ -397,7 +397,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                 block = b;
                 self.rewrite_fn_before_block(
                     indent,
-                    *ident,
+                    ident,
                     &FnSig::from_fn_kind(&fk, fd, defaultness),
                     mk_sp(s.lo(), b.span.lo()),
                 )
@@ -444,7 +444,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
         let should_visit_node_again = match item.kind {
             // For use/extern crate items, skip rewriting attributes but check for a skip attribute.
-            ast::ItemKind::Use(..) | ast::ItemKind::ExternCrate(_) => {
+            ast::ItemKind::Use(..) | ast::ItemKind::ExternCrate(..) => {
                 if contains_skip(attrs) {
                     self.push_skipped_with_span(attrs.as_slice(), item.span(), item.span());
                     false
@@ -497,11 +497,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     let rw = self.with_context(|ctx| format_trait(ctx, item, block_indent));
                     self.push_rewrite(item.span, rw);
                 }
-                ast::ItemKind::TraitAlias(ref generics, ref generic_bounds) => {
+                ast::ItemKind::TraitAlias(ident, ref generics, ref generic_bounds) => {
                     let shape = Shape::indented(self.block_indent, self.config);
                     let rw = format_trait_alias(
                         &self.get_context(),
-                        item.ident,
+                        ident,
                         &item.vis,
                         generics,
                         generic_bounds,
@@ -509,7 +509,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     );
                     self.push_rewrite(item.span, rw);
                 }
-                ast::ItemKind::ExternCrate(_) => {
+                ast::ItemKind::ExternCrate(..) => {
                     let rw = rewrite_extern_crate(&self.get_context(), item, self.shape());
                     let span = if attrs.is_empty() {
                         item.span
@@ -521,17 +521,17 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                 ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => {
                     self.visit_struct(&StructParts::from_item(item));
                 }
-                ast::ItemKind::Enum(ref def, ref generics) => {
+                ast::ItemKind::Enum(ident, ref def, ref generics) => {
                     self.format_missing_with_indent(source!(self, item.span).lo());
-                    self.visit_enum(item.ident, &item.vis, def, generics, item.span);
+                    self.visit_enum(ident, &item.vis, def, generics, item.span);
                     self.last_pos = source!(self, item.span).hi();
                 }
-                ast::ItemKind::Mod(safety, ref mod_kind) => {
+                ast::ItemKind::Mod(safety, ident, ref mod_kind) => {
                     self.format_missing_with_indent(source!(self, item.span).lo());
-                    self.format_mod(mod_kind, safety, &item.vis, item.span, item.ident, attrs);
+                    self.format_mod(mod_kind, safety, &item.vis, item.span, ident, attrs);
                 }
                 ast::ItemKind::MacCall(ref mac) => {
-                    self.visit_mac(mac, Some(item.ident), MacroPosition::Item);
+                    self.visit_mac(mac, MacroPosition::Item);
                 }
                 ast::ItemKind::ForeignMod(ref foreign_mod) => {
                     self.format_missing_with_indent(source!(self, item.span).lo());
@@ -544,6 +544,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     let ast::Fn {
                         defaultness,
                         ref sig,
+                        ident,
                         ref generics,
                         ref body,
                         ..
@@ -555,7 +556,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                             _ => visit::FnCtxt::Foreign,
                         };
                         self.visit_fn(
-                            visit::FnKind::Fn(fn_ctxt, &item.ident, &item.vis, fn_kind),
+                            ident,
+                            visit::FnKind::Fn(fn_ctxt, &item.vis, fn_kind),
                             &sig.decl,
                             item.span,
                             defaultness,
@@ -564,28 +566,26 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     } else {
                         let indent = self.block_indent;
                         let rewrite = self
-                            .rewrite_required_fn(
-                                indent, item.ident, sig, &item.vis, generics, item.span,
-                            )
+                            .rewrite_required_fn(indent, ident, sig, &item.vis, generics, item.span)
                             .ok();
                         self.push_rewrite(item.span, rewrite);
                     }
                 }
                 ast::ItemKind::TyAlias(ref ty_alias) => {
                     use ItemVisitorKind::Item;
-                    self.visit_ty_alias_kind(ty_alias, &Item(item), item.span);
+                    self.visit_ty_alias_kind(ty_alias, &item.vis, Item, item.span);
                 }
                 ast::ItemKind::GlobalAsm(..) => {
                     let snippet = Some(self.snippet(item.span).to_owned());
                     self.push_rewrite(item.span, snippet);
                 }
-                ast::ItemKind::MacroDef(ref def) => {
+                ast::ItemKind::MacroDef(ident, ref def) => {
                     let rewrite = rewrite_macro_def(
                         &self.get_context(),
                         self.shape(),
                         self.block_indent,
                         def,
-                        item.ident,
+                        ident,
                         &item.vis,
                         item.span,
                     )
@@ -605,11 +605,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
     fn visit_ty_alias_kind(
         &mut self,
         ty_kind: &ast::TyAlias,
-        visitor_kind: &ItemVisitorKind<'_>,
+        vis: &ast::Visibility,
+        visitor_kind: ItemVisitorKind,
         span: Span,
     ) {
         let rewrite = rewrite_type_alias(
             ty_kind,
+            vis,
             &self.get_context(),
             self.block_indent,
             visitor_kind,
@@ -619,15 +621,16 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         self.push_rewrite(span, rewrite);
     }
 
-    fn visit_assoc_item(&mut self, visitor_kind: &ItemVisitorKind<'_>) {
+    fn visit_assoc_item(&mut self, ai: &ast::AssocItem, visitor_kind: ItemVisitorKind) {
         use ItemVisitorKind::*;
-        // TODO(calebcartwright): Not sure the skip spans are correct
-        let (ai, skip_span, assoc_ctxt) = match visitor_kind {
-            AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait),
+        let assoc_ctxt = match visitor_kind {
+            AssocTraitItem => visit::AssocCtxt::Trait,
             // There is no difference between trait and inherent assoc item formatting
-            AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl { of_trait: false }),
+            AssocImplItem => visit::AssocCtxt::Impl { of_trait: false },
             _ => unreachable!(),
         };
+        // TODO(calebcartwright): Not sure the skip spans are correct
+        let skip_span = ai.span;
         skip_out_of_file_lines_range_visitor!(self, ai.span);
 
         if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) {
@@ -637,16 +640,17 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
         // TODO(calebcartwright): consider enabling box_patterns feature gate
         match (&ai.kind, visitor_kind) {
-            (ast::AssocItemKind::Const(..), AssocTraitItem(_)) => {
-                self.visit_static(&StaticParts::from_trait_item(ai))
+            (ast::AssocItemKind::Const(c), AssocTraitItem) => {
+                self.visit_static(&StaticParts::from_trait_item(ai, c.ident))
             }
-            (ast::AssocItemKind::Const(..), AssocImplItem(_)) => {
-                self.visit_static(&StaticParts::from_impl_item(ai))
+            (ast::AssocItemKind::Const(c), AssocImplItem) => {
+                self.visit_static(&StaticParts::from_impl_item(ai, c.ident))
             }
             (ast::AssocItemKind::Fn(ref fn_kind), _) => {
                 let ast::Fn {
                     defaultness,
                     ref sig,
+                    ident,
                     ref generics,
                     ref body,
                     ..
@@ -655,7 +659,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     let inner_attrs = inner_attributes(&ai.attrs);
                     let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt);
                     self.visit_fn(
-                        visit::FnKind::Fn(fn_ctxt, &ai.ident, &ai.vis, fn_kind),
+                        ident,
+                        visit::FnKind::Fn(fn_ctxt, &ai.vis, fn_kind),
                         &sig.decl,
                         ai.span,
                         defaultness,
@@ -664,35 +669,35 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                 } else {
                     let indent = self.block_indent;
                     let rewrite = self
-                        .rewrite_required_fn(indent, ai.ident, sig, &ai.vis, generics, ai.span)
+                        .rewrite_required_fn(indent, fn_kind.ident, sig, &ai.vis, generics, ai.span)
                         .ok();
                     self.push_rewrite(ai.span, rewrite);
                 }
             }
             (ast::AssocItemKind::Type(ref ty_alias), _) => {
-                self.visit_ty_alias_kind(ty_alias, visitor_kind, ai.span);
+                self.visit_ty_alias_kind(ty_alias, &ai.vis, visitor_kind, ai.span);
             }
             (ast::AssocItemKind::MacCall(ref mac), _) => {
-                self.visit_mac(mac, Some(ai.ident), MacroPosition::Item);
+                self.visit_mac(mac, MacroPosition::Item);
             }
             _ => unreachable!(),
         }
     }
 
     pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) {
-        self.visit_assoc_item(&ItemVisitorKind::AssocTraitItem(ti));
+        self.visit_assoc_item(ti, ItemVisitorKind::AssocTraitItem);
     }
 
     pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) {
-        self.visit_assoc_item(&ItemVisitorKind::AssocImplItem(ii));
+        self.visit_assoc_item(ii, ItemVisitorKind::AssocImplItem);
     }
 
-    fn visit_mac(&mut self, mac: &ast::MacCall, ident: Option<symbol::Ident>, pos: MacroPosition) {
+    fn visit_mac(&mut self, mac: &ast::MacCall, pos: MacroPosition) {
         skip_out_of_file_lines_range_visitor!(self, mac.span());
 
         // 1 = ;
         let shape = self.shape().saturating_sub_width(1);
-        let rewrite = self.with_context(|ctx| rewrite_macro(mac, ident, ctx, shape, pos).ok());
+        let rewrite = self.with_context(|ctx| rewrite_macro(mac, ctx, shape, pos).ok());
         // As of v638 of the rustc-ap-* crates, the associated span no longer includes
         // the trailing semicolon. This determines the correct span to ensure scenarios
         // with whitespace between the delimiters and trailing semi (i.e. `foo!(abc)     ;`)
diff --git a/src/tools/rustfmt/tests/source/pattern.rs b/src/tools/rustfmt/tests/source/pattern.rs
index ed6ad690fa9..0e5abb52394 100644
--- a/src/tools/rustfmt/tests/source/pattern.rs
+++ b/src/tools/rustfmt/tests/source/pattern.rs
@@ -91,7 +91,7 @@ fn issue3728() {
 
 fn literals() {
     match 42 {
-        const { 1 + 2 } | 4
+        1 | 2 | 4
         | 6 => {}
         10 | 11 | 12
         | 13 | 14 => {}
diff --git a/src/tools/rustfmt/tests/target/pattern.rs b/src/tools/rustfmt/tests/target/pattern.rs
index e867f65929d..483725f95c4 100644
--- a/src/tools/rustfmt/tests/target/pattern.rs
+++ b/src/tools/rustfmt/tests/target/pattern.rs
@@ -99,7 +99,7 @@ fn issue3728() {
 
 fn literals() {
     match 42 {
-        const { 1 + 2 } | 4 | 6 => {}
+        1 | 2 | 4 | 6 => {}
         10 | 11 | 12 | 13 | 14 => {}
         _ => {}
     }
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 1a6550691ee..8f761d349cc 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -181,6 +181,8 @@ const EXCEPTIONS_RUSTBOOK: ExceptionList = &[
 
 const EXCEPTIONS_CRANELIFT: ExceptionList = &[
     // tidy-alphabetical-start
+    ("cranelift-assembler-x64", "Apache-2.0 WITH LLVM-exception"),
+    ("cranelift-assembler-x64-meta", "Apache-2.0 WITH LLVM-exception"),
     ("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"),
     ("cranelift-bitset", "Apache-2.0 WITH LLVM-exception"),
     ("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"),
@@ -252,7 +254,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "blake3",
     "block-buffer",
     "bstr",
-    "byteorder", // via ruzstd in object in thorin-dwp
     "cc",
     "cfg-if",
     "cfg_aliases",
@@ -349,6 +350,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "pulldown-cmark-escape",
     "punycode",
     "quote",
+    "r-efi",
     "rand",
     "rand_chacha",
     "rand_core",
@@ -432,6 +434,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "windows-core",
     "windows-implement",
     "windows-interface",
+    "windows-link",
     "windows-result",
     "windows-strings",
     "windows-sys",
@@ -444,7 +447,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "windows_x86_64_gnu",
     "windows_x86_64_gnullvm",
     "windows_x86_64_msvc",
-    "wit-bindgen-rt@0.33.0", // via wasi
+    "wit-bindgen-rt@0.39.0", // pinned to a specific version due to using a binary blob: <https://github.com/rust-lang/rust/pull/136395#issuecomment-2692769062>
     "writeable",
     "yoke",
     "yoke-derive",
@@ -512,6 +515,8 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
     "bitflags",
     "bumpalo",
     "cfg-if",
+    "cranelift-assembler-x64",
+    "cranelift-assembler-x64-meta",
     "cranelift-bforest",
     "cranelift-bitset",
     "cranelift-codegen",
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index a33e03d5861..d2ae9b1f6ef 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -2873,7 +2873,6 @@ ui/macros/rfc-3086-metavar-expr/issue-111904.rs
 ui/malformed/issue-107423-unused-delim-only-one-no-pair.rs
 ui/malformed/issue-69341-malformed-derive-inert.rs
 ui/marker_trait_attr/issue-61651-type-mismatch.rs
-ui/match/issue-112438.rs
 ui/match/issue-113012.rs
 ui/match/issue-11319.rs
 ui/match/issue-114691.rs
diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs
index 708e4ef8085..90ef36d5882 100644
--- a/src/tools/tidy/src/unit_tests.rs
+++ b/src/tools/tidy/src/unit_tests.rs
@@ -1,11 +1,13 @@
-//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside `core`.
+//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside
+//! `core` or `alloc`.
 //!
-//! `#![no_core]` libraries cannot be tested directly due to duplicating lang
-//! items. All tests and benchmarks must be written externally in `core/{tests,benches}`.
+//! `core` and `alloc` cannot be tested directly due to duplicating lang items.
+//! All tests and benchmarks must be written externally in
+//! `{coretests,alloctests}/{tests,benches}`.
 //!
-//! Outside of core tests and benchmarks should be outlined into separate files
-//! named `tests.rs` or `benches.rs`, or directories named `tests` or `benches` unconfigured
-//! during normal build.
+//! Outside of `core` and `alloc`, tests and benchmarks should be outlined into
+//! separate files named `tests.rs` or `benches.rs`, or directories named
+//! `tests` or `benches` unconfigured during normal build.
 
 use std::path::Path;
 
@@ -14,40 +16,51 @@ use crate::walk::{filter_dirs, walk};
 pub fn check(root_path: &Path, bad: &mut bool) {
     let core = root_path.join("core");
     let core_copy = core.clone();
-    let core_tests = core.join("tests");
-    let core_benches = core.join("benches");
-    let is_core = move |path: &Path| {
-        path.starts_with(&core)
-            && !(path.starts_with(&core_tests) || path.starts_with(&core_benches))
-    };
+    let is_core = move |path: &Path| path.starts_with(&core);
+    let alloc = root_path.join("alloc");
+    let alloc_copy = alloc.clone();
+    let is_alloc = move |path: &Path| path.starts_with(&alloc);
 
     let skip = move |path: &Path, is_dir| {
         let file_name = path.file_name().unwrap_or_default();
         if is_dir {
             filter_dirs(path)
                 || path.ends_with("src/doc")
-                || (file_name == "tests" || file_name == "benches") && !is_core(path)
+                || (file_name == "tests" || file_name == "benches")
+                    && !is_core(path)
+                    && !is_alloc(path)
         } else {
             let extension = path.extension().unwrap_or_default();
             extension != "rs"
-                || (file_name == "tests.rs" || file_name == "benches.rs") && !is_core(path)
-                // UI tests with different names
-                || path.ends_with("src/thread/local/dynamic_tests.rs")
-                || path.ends_with("src/sync/mpsc/sync_tests.rs")
+                || (file_name == "tests.rs" || file_name == "benches.rs")
+                    && !is_core(path)
+                    && !is_alloc(path)
+                // Tests which use non-public internals and, as such, need to
+                // have the types in the same crate as the tests themselves. See
+                // the comment in alloctests/lib.rs.
+                || path.ends_with("library/alloc/src/collections/btree/borrow/tests.rs")
+                || path.ends_with("library/alloc/src/collections/btree/map/tests.rs")
+                || path.ends_with("library/alloc/src/collections/btree/node/tests.rs")
+                || path.ends_with("library/alloc/src/collections/btree/set/tests.rs")
+                || path.ends_with("library/alloc/src/collections/linked_list/tests.rs")
+                || path.ends_with("library/alloc/src/collections/vec_deque/tests.rs")
+                || path.ends_with("library/alloc/src/raw_vec/tests.rs")
         }
     };
 
     walk(root_path, skip, &mut |entry, contents| {
         let path = entry.path();
         let is_core = path.starts_with(&core_copy);
+        let is_alloc = path.starts_with(&alloc_copy);
         for (i, line) in contents.lines().enumerate() {
             let line = line.trim();
             let is_test = || line.contains("#[test]") && !line.contains("`#[test]");
             let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]");
             if !line.starts_with("//") && (is_test() || is_bench()) {
                 let explanation = if is_core {
-                    "core unit tests and benchmarks must be placed into \
-                         `core/tests` or `core/benches`"
+                    "`core` unit tests and benchmarks must be placed into `coretests`"
+                } else if is_alloc {
+                    "`alloc` unit tests and benchmarks must be placed into `alloctests`"
                 } else {
                     "unit tests and benchmarks must be placed into \
                          separate files or directories named \
diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs
index 8be25b98df0..a2453a6c960 100644
--- a/src/tools/tidy/src/unstable_book.rs
+++ b/src/tools/tidy/src/unstable_book.rs
@@ -72,6 +72,19 @@ fn collect_unstable_book_lib_features_section_file_names(base_src_path: &Path) -
     collect_unstable_book_section_file_names(&unstable_book_lib_features_path(base_src_path))
 }
 
+/// Would switching underscores for dashes work?
+fn maybe_suggest_dashes(names: &BTreeSet<String>, feature_name: &str, bad: &mut bool) {
+    let with_dashes = feature_name.replace('_', "-");
+    if names.contains(&with_dashes) {
+        tidy_error!(
+            bad,
+            "the file `{}.md` contains underscores; use dashes instead: `{}.md`",
+            feature_name,
+            with_dashes,
+        );
+    }
+}
+
 pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
     let lang_features = features.lang;
     let lib_features = features
@@ -93,14 +106,13 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
     // Check for Unstable Book sections that don't have a corresponding unstable feature
     for feature_name in &unstable_book_lib_features_section_file_names - &unstable_lib_feature_names
     {
-        if !unstable_lang_feature_names.contains(&feature_name) {
-            tidy_error!(
-                bad,
-                "The Unstable Book has a 'library feature' section '{}' which doesn't \
+        tidy_error!(
+            bad,
+            "The Unstable Book has a 'library feature' section '{}' which doesn't \
                          correspond to an unstable library feature",
-                feature_name
-            );
-        }
+            feature_name
+        );
+        maybe_suggest_dashes(&unstable_lib_feature_names, &feature_name, bad);
     }
 
     // Check for Unstable Book sections that don't have a corresponding unstable feature.
@@ -112,7 +124,8 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
             "The Unstable Book has a 'language feature' section '{}' which doesn't \
                      correspond to an unstable language feature",
             feature_name
-        )
+        );
+        maybe_suggest_dashes(&unstable_lang_feature_names, &feature_name, bad);
     }
 
     // List unstable features that don't have Unstable Book sections.
diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/src/tools/unicode-table-generator/src/range_search.rs
index 9a51979a2f0..02f9cf16d4d 100644
--- a/src/tools/unicode-table-generator/src/range_search.rs
+++ b/src/tools/unicode-table-generator/src/range_search.rs
@@ -45,45 +45,78 @@ const fn bitset_search<
     (word & (1 << (needle % 64) as u64)) != 0
 }
 
-fn decode_prefix_sum(short_offset_run_header: u32) -> u32 {
-    short_offset_run_header & ((1 << 21) - 1)
-}
+#[repr(transparent)]
+struct ShortOffsetRunHeader(u32);
+
+impl ShortOffsetRunHeader {
+    const fn new(start_index: usize, prefix_sum: u32) -> Self {
+        assert!(start_index < (1 << 11));
+        assert!(prefix_sum < (1 << 21));
 
-fn decode_length(short_offset_run_header: u32) -> usize {
-    (short_offset_run_header >> 21) as usize
+        Self((start_index as u32) << 21 | prefix_sum)
+    }
+
+    #[inline]
+    const fn start_index(&self) -> usize {
+        (self.0 >> 21) as usize
+    }
+
+    #[inline]
+    const fn prefix_sum(&self) -> u32 {
+        self.0 & ((1 << 21) - 1)
+    }
 }
 
+/// # Safety
+///
+/// - The last element of `short_offset_runs` must be greater than `std::char::MAX`.
+/// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`.
 #[inline(always)]
-fn skip_search<const SOR: usize, const OFFSETS: usize>(
-    needle: u32,
-    short_offset_runs: &[u32; SOR],
+unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
+    needle: char,
+    short_offset_runs: &[ShortOffsetRunHeader; SOR],
     offsets: &[u8; OFFSETS],
 ) -> bool {
-    // Note that this *cannot* be past the end of the array, as the last
-    // element is greater than std::char::MAX (the largest possible needle).
-    //
-    // So, we cannot have found it (i.e. Ok(idx) + 1 != length) and the correct
-    // location cannot be past it, so Err(idx) != length either.
-    //
-    // This means that we can avoid bounds checking for the accesses below, too.
+    let needle = needle as u32;
+
     let last_idx =
-        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header << 11) {
+        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) {
             Ok(idx) => idx + 1,
             Err(idx) => idx,
         };
+    // SAFETY: `last_idx` *cannot* be past the end of the array, as the last
+    // element is greater than `std::char::MAX` (the largest possible needle)
+    // as guaranteed by the caller.
+    //
+    // So, we cannot have found it (i.e. `Ok(idx) => idx + 1 != length`) and the
+    // correct location cannot be past it, so `Err(idx) => idx != length` either.
+    //
+    // This means that we can avoid bounds checking for the accesses below, too.
+    //
+    // We need to use `intrinsics::assume` since the `panic_nounwind` contained
+    // in `hint::assert_unchecked` may not be optimized out.
+    unsafe { crate::intrinsics::assume(last_idx < SOR) };
 
-    let mut offset_idx = decode_length(short_offset_runs[last_idx]);
+    let mut offset_idx = short_offset_runs[last_idx].start_index();
     let length = if let Some(next) = short_offset_runs.get(last_idx + 1) {
-        decode_length(*next) - offset_idx
+        (*next).start_index() - offset_idx
     } else {
         offsets.len() - offset_idx
     };
+
     let prev =
-        last_idx.checked_sub(1).map(|prev| decode_prefix_sum(short_offset_runs[prev])).unwrap_or(0);
+        last_idx.checked_sub(1).map(|prev| short_offset_runs[prev].prefix_sum()).unwrap_or(0);
 
     let total = needle - prev;
     let mut prefix_sum = 0;
     for _ in 0..(length - 1) {
+        // SAFETY: It is guaranteed that `length <= OFFSETS - offset_idx`,
+        // so it follows that `length - 1 + offset_idx < OFFSETS`, therefore
+        // `offset_idx < OFFSETS` is always true in this loop.
+        //
+        // We need to use `intrinsics::assume` since the `panic_nounwind` contained
+        // in `hint::assert_unchecked` may not be optimized out.
+        unsafe { crate::intrinsics::assume(offset_idx < OFFSETS) };
         let offset = offsets[offset_idx];
         prefix_sum += offset as u32;
         if prefix_sum > total {
diff --git a/src/tools/unicode-table-generator/src/skiplist.rs b/src/tools/unicode-table-generator/src/skiplist.rs
index 8ca18ddc91a..34c9802e122 100644
--- a/src/tools/unicode-table-generator/src/skiplist.rs
+++ b/src/tools/unicode-table-generator/src/skiplist.rs
@@ -1,26 +1,23 @@
-use std::fmt::Write as _;
+use std::fmt::{self, Write as _};
 use std::ops::Range;
 
 use crate::fmt_list;
 use crate::raw_emitter::RawEmitter;
 
 /// This will get packed into a single u32 before inserting into the data set.
-#[derive(Debug, PartialEq)]
+#[derive(PartialEq)]
 struct ShortOffsetRunHeader {
-    /// Note, we only allow for 21 bits here.
-    prefix_sum: u32,
-
     /// Note, we actually only allow for 11 bits here. This should be enough --
     /// our largest sets are around ~1400 offsets long.
-    start_idx: u16,
-}
+    start_index: u16,
 
-impl ShortOffsetRunHeader {
-    fn pack(&self) -> u32 {
-        assert!(self.start_idx < (1 << 11));
-        assert!(self.prefix_sum < (1 << 21));
+    /// Note, we only allow for 21 bits here.
+    prefix_sum: u32,
+}
 
-        (self.start_idx as u32) << 21 | self.prefix_sum
+impl fmt::Debug for ShortOffsetRunHeader {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "ShortOffsetRunHeader::new({}, {})", self.start_index, self.prefix_sum)
     }
 }
 
@@ -53,7 +50,7 @@ impl RawEmitter {
                     coded_offsets.push(offset);
                 } else {
                     short_offset_runs.push(ShortOffsetRunHeader {
-                        start_idx: start.try_into().unwrap(),
+                        start_index: start.try_into().unwrap(),
                         prefix_sum,
                     });
                     // This is just needed to maintain indices even/odd
@@ -71,11 +68,12 @@ impl RawEmitter {
             assert!(inserted);
         }
 
+        writeln!(&mut self.file, "use super::ShortOffsetRunHeader;\n").unwrap();
         writeln!(
             &mut self.file,
-            "static SHORT_OFFSET_RUNS: [u32; {}] = [{}];",
+            "static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; {}] = [{}];",
             short_offset_runs.len(),
-            fmt_list(short_offset_runs.iter().map(|v| v.pack()))
+            fmt_list(short_offset_runs.iter())
         )
         .unwrap();
         self.bytes_used += 4 * short_offset_runs.len();
@@ -104,15 +102,43 @@ impl RawEmitter {
             writeln!(&mut self.file, "    (c as u32) >= {first_code_point:#04x} && lookup_slow(c)")
                 .unwrap();
             writeln!(&mut self.file, "}}").unwrap();
+            writeln!(&mut self.file).unwrap();
+            writeln!(&mut self.file, "#[inline(never)]").unwrap();
             writeln!(&mut self.file, "fn lookup_slow(c: char) -> bool {{").unwrap();
         } else {
             writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap();
         }
-        writeln!(&mut self.file, "    super::skip_search(",).unwrap();
-        writeln!(&mut self.file, "        c as u32,").unwrap();
-        writeln!(&mut self.file, "        &SHORT_OFFSET_RUNS,").unwrap();
-        writeln!(&mut self.file, "        &OFFSETS,").unwrap();
-        writeln!(&mut self.file, "    )").unwrap();
+        writeln!(&mut self.file, "    const {{").unwrap();
+        writeln!(
+            &mut self.file,
+            "        assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);",
+        )
+        .unwrap();
+        writeln!(&mut self.file, "        let mut i = 0;").unwrap();
+        writeln!(&mut self.file, "        while i < SHORT_OFFSET_RUNS.len() {{").unwrap();
+        writeln!(
+            &mut self.file,
+            "            assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());",
+        )
+        .unwrap();
+        writeln!(&mut self.file, "            i += 1;").unwrap();
+        writeln!(&mut self.file, "        }}").unwrap();
+        writeln!(&mut self.file, "    }}").unwrap();
+        writeln!(
+            &mut self.file,
+            "    // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`",
+        )
+        .unwrap();
+        writeln!(
+            &mut self.file,
+            "    // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.",
+        )
+        .unwrap();
+        writeln!(
+            &mut self.file,
+            "    unsafe {{ super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }}"
+        )
+        .unwrap();
         writeln!(&mut self.file, "}}").unwrap();
     }
 }
diff --git a/src/version b/src/version
index f6342716723..59be592144c 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.87.0
+1.88.0
diff --git a/tests/assembly/aarch64-pointer-auth.rs b/tests/assembly/aarch64-pointer-auth.rs
index 8c006982679..56a26df469f 100644
--- a/tests/assembly/aarch64-pointer-auth.rs
+++ b/tests/assembly/aarch64-pointer-auth.rs
@@ -8,7 +8,6 @@
 //@ [PACRET] compile-flags: -Z branch-protection=pac-ret,leaf
 //@ [PAUTHLR_NOP] compile-flags: -Z branch-protection=pac-ret,pc,leaf
 //@ [PAUTHLR] compile-flags: -C target-feature=+pauth-lr -Z branch-protection=pac-ret,pc,leaf
-//@ min-llvm-version: 19
 
 #![feature(no_core, lang_items)]
 #![no_std]
diff --git a/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs b/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs
new file mode 100644
index 00000000000..b3b623b509b
--- /dev/null
+++ b/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs
@@ -0,0 +1,61 @@
+// Verifies that KCFI arity indicator is emitted.
+//
+//@ add-core-stubs
+//@ revisions: x86_64
+//@ assembly-output: emit-asm
+//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu -Cllvm-args=-x86-asm-syntax=intel -Ctarget-feature=-crt-static -Cpanic=abort -Zsanitizer=kcfi -Zsanitizer-kcfi-arity -Copt-level=0
+//@ [x86_64] needs-llvm-components: x86
+//@ min-llvm-version: 21.0.0
+
+#![crate_type = "lib"]
+
+pub fn add_one(x: i32) -> i32 {
+    // CHECK-LABEL: __cfi__{{.*}}7add_one{{.*}}:
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  mov ecx, 2628068948
+    x + 1
+}
+
+pub fn add_two(x: i32, _y: i32) -> i32 {
+    // CHECK-LABEL: __cfi__{{.*}}7add_two{{.*}}:
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  mov edx, 2505940310
+    x + 2
+}
+
+pub fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
+    // CHECK-LABEL: __cfi__{{.*}}8do_twice{{.*}}:
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  nop
+    // CHECK-NEXT:  mov edx, 653723426
+    f(arg) + f(arg)
+}
diff --git a/tests/assembly/static-relocation-model.rs b/tests/assembly/static-relocation-model.rs
index 53fa18852b6..35ad94133b2 100644
--- a/tests/assembly/static-relocation-model.rs
+++ b/tests/assembly/static-relocation-model.rs
@@ -25,7 +25,7 @@ extern "C" {
 }
 
 // CHECK-LABEL: banana:
-// On the next line LLVM 14 produces a `movb`, whereas LLVM 15+ produces a `movzbl`.
+// LLVM may produce either kind of `mov` here, depending on version and optimization level.
 // x64: {{movb|movzbl}}   chaenomeles{{(\(%[a-z0-9]+\))?}}, %{{[a-z0-9]+}}
 // A64:      adrp    [[REG:[a-z0-9]+]], chaenomeles
 // A64-NEXT: ldrb    {{[a-z0-9]+}}, {{\[}}[[REG]], :lo12:chaenomeles]
diff --git a/tests/codegen/autodiff.rs b/tests/codegen/autodiff.rs
index cace0edb2b5..85358f5fcb6 100644
--- a/tests/codegen/autodiff.rs
+++ b/tests/codegen/autodiff.rs
@@ -11,7 +11,7 @@ fn square(x: &f64) -> f64 {
     x * x
 }
 
-// CHECK:define internal fastcc double @diffesquare(double %x.0.val, ptr nocapture align 8 %"x'"
+// CHECK:define internal fastcc double @diffesquare(double %x.0.val, ptr nocapture nonnull align 8 %"x'"
 // CHECK-NEXT:invertstart:
 // CHECK-NEXT:  %_0 = fmul double %x.0.val, %x.0.val
 // CHECK-NEXT:  %0 = fadd fast double %x.0.val, %x.0.val
@@ -22,7 +22,7 @@ fn square(x: &f64) -> f64 {
 // CHECK-NEXT:}
 
 fn main() {
-    let x = 3.0;
+    let x = std::hint::black_box(3.0);
     let output = square(&x);
     assert_eq!(9.0, output);
 
diff --git a/tests/codegen/autodiffv.rs b/tests/codegen/autodiffv.rs
new file mode 100644
index 00000000000..e0047116405
--- /dev/null
+++ b/tests/codegen/autodiffv.rs
@@ -0,0 +1,116 @@
+//@ compile-flags: -Zautodiff=Enable -C opt-level=3  -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+//
+// In Enzyme, we test against a large range of LLVM versions (5+) and don't have overly many
+// breakages. One benefit is that we match the IR generated by Enzyme only after running it
+// through LLVM's O3 pipeline, which will remove most of the noise.
+// However, our integration test could also be affected by changes in how rustc lowers MIR into
+// LLVM-IR, which could cause additional noise and thus breakages. If that's the case, we should
+// reduce this test to only match the first lines and the ret instructions.
+
+#![feature(autodiff)]
+
+use std::autodiff::autodiff;
+
+#[autodiff(d_square3, Forward, Dual, DualOnly)]
+#[autodiff(d_square2, Forward, 4, Dual, DualOnly)]
+#[autodiff(d_square1, Forward, 4, Dual, Dual)]
+#[no_mangle]
+fn square(x: &f32) -> f32 {
+    x * x
+}
+
+// d_sqaure2
+// CHECK: define internal fastcc [4 x float] @fwddiffe4square(float %x.0.val, [4 x ptr] %"x'")
+// CHECK-NEXT: start:
+// CHECK-NEXT:   %0 = extractvalue [4 x ptr] %"x'", 0
+// CHECK-NEXT:   %"_2'ipl" = load float, ptr %0, align 4
+// CHECK-NEXT:   %1 = extractvalue [4 x ptr] %"x'", 1
+// CHECK-NEXT:   %"_2'ipl1" = load float, ptr %1, align 4
+// CHECK-NEXT:   %2 = extractvalue [4 x ptr] %"x'", 2
+// CHECK-NEXT:   %"_2'ipl2" = load float, ptr %2, align 4
+// CHECK-NEXT:   %3 = extractvalue [4 x ptr] %"x'", 3
+// CHECK-NEXT:   %"_2'ipl3" = load float, ptr %3, align 4
+// CHECK-NEXT:   %4 = insertelement <4 x float> poison, float %"_2'ipl", i64 0
+// CHECK-NEXT:   %5 = insertelement <4 x float> %4, float %"_2'ipl1", i64 1
+// CHECK-NEXT:   %6 = insertelement <4 x float> %5, float %"_2'ipl2", i64 2
+// CHECK-NEXT:   %7 = insertelement <4 x float> %6, float %"_2'ipl3", i64 3
+// CHECK-NEXT:   %8 = fadd fast <4 x float> %7, %7
+// CHECK-NEXT:   %9 = insertelement <4 x float> poison, float %x.0.val, i64 0
+// CHECK-NEXT:   %10 = shufflevector <4 x float> %9, <4 x float> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:   %11 = fmul fast <4 x float> %8, %10
+// CHECK-NEXT:   %12 = extractelement <4 x float> %11, i64 0
+// CHECK-NEXT:   %13 = insertvalue [4 x float] undef, float %12, 0
+// CHECK-NEXT:   %14 = extractelement <4 x float> %11, i64 1
+// CHECK-NEXT:   %15 = insertvalue [4 x float] %13, float %14, 1
+// CHECK-NEXT:   %16 = extractelement <4 x float> %11, i64 2
+// CHECK-NEXT:   %17 = insertvalue [4 x float] %15, float %16, 2
+// CHECK-NEXT:   %18 = extractelement <4 x float> %11, i64 3
+// CHECK-NEXT:   %19 = insertvalue [4 x float] %17, float %18, 3
+// CHECK-NEXT:   ret [4 x float] %19
+// CHECK-NEXT: }
+
+// d_square3, the extra float is the original return value (x * x)
+// CHECK: define internal fastcc { float, [4 x float] } @fwddiffe4square.1(float %x.0.val, [4 x ptr] %"x'")
+// CHECK-NEXT: start:
+// CHECK-NEXT:   %0 = extractvalue [4 x ptr] %"x'", 0
+// CHECK-NEXT:   %"_2'ipl" = load float, ptr %0, align 4
+// CHECK-NEXT:   %1 = extractvalue [4 x ptr] %"x'", 1
+// CHECK-NEXT:   %"_2'ipl1" = load float, ptr %1, align 4
+// CHECK-NEXT:   %2 = extractvalue [4 x ptr] %"x'", 2
+// CHECK-NEXT:   %"_2'ipl2" = load float, ptr %2, align 4
+// CHECK-NEXT:   %3 = extractvalue [4 x ptr] %"x'", 3
+// CHECK-NEXT:   %"_2'ipl3" = load float, ptr %3, align 4
+// CHECK-NEXT:   %_0 = fmul float %x.0.val, %x.0.val
+// CHECK-NEXT:   %4 = insertelement <4 x float> poison, float %"_2'ipl", i64 0
+// CHECK-NEXT:   %5 = insertelement <4 x float> %4, float %"_2'ipl1", i64 1
+// CHECK-NEXT:   %6 = insertelement <4 x float> %5, float %"_2'ipl2", i64 2
+// CHECK-NEXT:   %7 = insertelement <4 x float> %6, float %"_2'ipl3", i64 3
+// CHECK-NEXT:   %8 = fadd fast <4 x float> %7, %7
+// CHECK-NEXT:   %9 = insertelement <4 x float> poison, float %x.0.val, i64 0
+// CHECK-NEXT:   %10 = shufflevector <4 x float> %9, <4 x float> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:   %11 = fmul fast <4 x float> %8, %10
+// CHECK-NEXT:   %12 = extractelement <4 x float> %11, i64 0
+// CHECK-NEXT:   %13 = insertvalue [4 x float] undef, float %12, 0
+// CHECK-NEXT:   %14 = extractelement <4 x float> %11, i64 1
+// CHECK-NEXT:   %15 = insertvalue [4 x float] %13, float %14, 1
+// CHECK-NEXT:   %16 = extractelement <4 x float> %11, i64 2
+// CHECK-NEXT:   %17 = insertvalue [4 x float] %15, float %16, 2
+// CHECK-NEXT:   %18 = extractelement <4 x float> %11, i64 3
+// CHECK-NEXT:   %19 = insertvalue [4 x float] %17, float %18, 3
+// CHECK-NEXT:   %20 = insertvalue { float, [4 x float] } undef, float %_0, 0
+// CHECK-NEXT:   %21 = insertvalue { float, [4 x float] } %20, [4 x float] %19, 1
+// CHECK-NEXT:   ret { float, [4 x float] } %21
+// CHECK-NEXT: }
+
+fn main() {
+    let x = std::hint::black_box(3.0);
+    let output = square(&x);
+    dbg!(&output);
+    assert_eq!(9.0, output);
+    dbg!(square(&x));
+
+    let mut df_dx1 = 1.0;
+    let mut df_dx2 = 2.0;
+    let mut df_dx3 = 3.0;
+    let mut df_dx4 = 0.0;
+    let [o1, o2, o3, o4] = d_square2(&x, &mut df_dx1, &mut df_dx2, &mut df_dx3, &mut df_dx4);
+    dbg!(o1, o2, o3, o4);
+    let [output2, o1, o2, o3, o4] =
+        d_square1(&x, &mut df_dx1, &mut df_dx2, &mut df_dx3, &mut df_dx4);
+    dbg!(o1, o2, o3, o4);
+    assert_eq!(output, output2);
+    assert!((6.0 - o1).abs() < 1e-10);
+    assert!((12.0 - o2).abs() < 1e-10);
+    assert!((18.0 - o3).abs() < 1e-10);
+    assert!((0.0 - o4).abs() < 1e-10);
+    assert_eq!(1.0, df_dx1);
+    assert_eq!(2.0, df_dx2);
+    assert_eq!(3.0, df_dx3);
+    assert_eq!(0.0, df_dx4);
+    assert_eq!(d_square3(&x, &mut df_dx1), 2.0 * o1);
+    assert_eq!(d_square3(&x, &mut df_dx2), 2.0 * o2);
+    assert_eq!(d_square3(&x, &mut df_dx3), 2.0 * o3);
+    assert_eq!(d_square3(&x, &mut df_dx4), 2.0 * o4);
+}
diff --git a/tests/codegen/branch-protection-old-llvm.rs b/tests/codegen/branch-protection-old-llvm.rs
deleted file mode 100644
index 14b34ac5018..00000000000
--- a/tests/codegen/branch-protection-old-llvm.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Test that the correct module flags are emitted with different branch protection flags.
-
-//@ add-core-stubs
-//@ revisions: BTI PACRET LEAF BKEY NONE
-//@ needs-llvm-components: aarch64
-//@ [BTI] compile-flags: -Z branch-protection=bti
-//@ [PACRET] compile-flags: -Z branch-protection=pac-ret
-//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
-//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
-//@ compile-flags: --target aarch64-unknown-linux-gnu
-//@ max-llvm-major-version: 18
-
-#![crate_type = "lib"]
-#![feature(no_core, lang_items)]
-#![no_core]
-
-extern crate minicore;
-use minicore::*;
-
-// A basic test function.
-pub fn test() {}
-
-// BTI: !"branch-target-enforcement", i32 1
-// BTI: !"sign-return-address", i32 0
-// BTI: !"sign-return-address-all", i32 0
-// BTI: !"sign-return-address-with-bkey", i32 0
-
-// PACRET: !"branch-target-enforcement", i32 0
-// PACRET: !"sign-return-address", i32 1
-// PACRET: !"sign-return-address-all", i32 0
-// PACRET: !"sign-return-address-with-bkey", i32 0
-
-// LEAF: !"branch-target-enforcement", i32 0
-// LEAF: !"sign-return-address", i32 1
-// LEAF: !"sign-return-address-all", i32 1
-// LEAF: !"sign-return-address-with-bkey", i32 0
-
-// BKEY: !"branch-target-enforcement", i32 0
-// BKEY: !"sign-return-address", i32 1
-// BKEY: !"sign-return-address-all", i32 0
-// BKEY: !"sign-return-address-with-bkey", i32 1
-
-// NONE-NOT: branch-target-enforcement
-// NONE-NOT: sign-return-address
-// NONE-NOT: sign-return-address-all
-// NONE-NOT: sign-return-address-with-bkey
diff --git a/tests/codegen/branch-protection.rs b/tests/codegen/branch-protection.rs
index ae14eae9ae0..d67e494cc0d 100644
--- a/tests/codegen/branch-protection.rs
+++ b/tests/codegen/branch-protection.rs
@@ -12,7 +12,6 @@
 //@ [PAUTHLR_LEAF] compile-flags: -Z branch-protection=pac-ret,pc,leaf
 //@ [PAUTHLR_BTI] compile-flags: -Z branch-protection=bti,pac-ret,pc
 //@ compile-flags: --target aarch64-unknown-linux-gnu
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 #![feature(no_core, lang_items)]
diff --git a/tests/codegen/call-metadata.rs b/tests/codegen/call-metadata.rs
deleted file mode 100644
index 7ad3ded2f09..00000000000
--- a/tests/codegen/call-metadata.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Checks that range metadata gets emitted on calls to functions returning a
-// scalar value.
-
-//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@ max-llvm-major-version: 18
-
-#![crate_type = "lib"]
-
-pub fn test() {
-    // CHECK: call noundef i8 @some_true(){{( #[0-9]+)?}}, !range [[R0:![0-9]+]]
-    // CHECK: [[R0]] = !{i8 0, i8 3}
-    some_true();
-}
-
-#[no_mangle]
-fn some_true() -> Option<bool> {
-    Some(true)
-}
diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs
index 186198bc631..cbd49e2f022 100644
--- a/tests/codegen/cast-target-abi.rs
+++ b/tests/codegen/cast-target-abi.rs
@@ -1,8 +1,7 @@
 // ignore-tidy-linelength
 //@ add-core-stubs
 //@ revisions:aarch64 loongarch64 powerpc64 sparc64 x86_64
-//@ min-llvm-version: 19
-//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Zlint-llvm-ir -Cllvm-args=-lint-abort-on-error
+//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Zlint-llvm-ir
 
 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
 //@[aarch64] needs-llvm-components: arm
diff --git a/tests/codegen/cffi/ffi-const.rs b/tests/codegen/cffi/ffi-const.rs
index 564b8f7f8d8..6c90902e89f 100644
--- a/tests/codegen/cffi/ffi-const.rs
+++ b/tests/codegen/cffi/ffi-const.rs
@@ -9,8 +9,7 @@ pub fn bar() {
 extern "C" {
     // CHECK-LABEL: declare{{.*}}void @foo()
     // CHECK-SAME: [[ATTRS:#[0-9]+]]
-    // The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
-    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
+    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}memory(none){{.*}} }
     #[ffi_const]
     pub fn foo();
 }
diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
index 404f6237849..859386d2df8 100644
--- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
+++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
@@ -1,7 +1,6 @@
 //@ add-core-stubs
 //@ revisions: linux apple
-//@ min-llvm-version: 19
-//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir -Cllvm-args=-lint-abort-on-error
+//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir
 
 //@[linux] compile-flags: --target x86_64-unknown-linux-gnu
 //@[linux] needs-llvm-components: x86
diff --git a/tests/codegen/cffi/ffi-pure.rs b/tests/codegen/cffi/ffi-pure.rs
index 601509d5c90..2c5d5f5b4b1 100644
--- a/tests/codegen/cffi/ffi-pure.rs
+++ b/tests/codegen/cffi/ffi-pure.rs
@@ -9,8 +9,7 @@ pub fn bar() {
 extern "C" {
     // CHECK-LABEL: declare{{.*}}void @foo()
     // CHECK-SAME: [[ATTRS:#[0-9]+]]
-    // The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
-    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
+    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}memory(read){{.*}} }
     #[ffi_pure]
     pub fn foo();
 }
diff --git a/tests/codegen/char-escape-debug-no-bounds-check.rs b/tests/codegen/char-escape-debug-no-bounds-check.rs
new file mode 100644
index 00000000000..cfde46045e5
--- /dev/null
+++ b/tests/codegen/char-escape-debug-no-bounds-check.rs
@@ -0,0 +1,14 @@
+//@ compile-flags: -Copt-level=3
+#![crate_type = "lib"]
+
+use std::char::EscapeDebug;
+
+// Make sure no bounds checks are emitted when escaping a character.
+
+// CHECK-LABEL: @char_escape_debug_no_bounds_check
+#[no_mangle]
+pub fn char_escape_debug_no_bounds_check(c: char) -> EscapeDebug {
+    // CHECK-NOT: panic
+    // CHECK-NOT: panic_bounds_check
+    c.escape_debug()
+}
diff --git a/tests/codegen/clone_as_copy.rs b/tests/codegen/clone_as_copy.rs
index c39f120044c..ef834ef5912 100644
--- a/tests/codegen/clone_as_copy.rs
+++ b/tests/codegen/clone_as_copy.rs
@@ -1,6 +1,4 @@
 //@ revisions: DEBUGINFO NODEBUGINFO
-//@ compile-flags: -Zunsound-mir-opts
-// FIXME: see <https://github.com/rust-lang/rust/issues/132353>
 //@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes
 //@ [DEBUGINFO] compile-flags: -Cdebuginfo=full
 
diff --git a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
index 0f6e99f9b1e..7530689d574 100644
--- a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
+++ b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
@@ -1,4 +1,3 @@
-//@ min-llvm-version: 19
 //@ compile-flags: -Cdebuginfo=2 -Copt-level=0 -Zmir-enable-passes=+Inline
 // MSVC is different because of the individual allocas.
 //@ ignore-msvc
diff --git a/tests/codegen/dont-shuffle-bswaps.rs b/tests/codegen/dont-shuffle-bswaps.rs
index 0e712bc3a4e..e100474f606 100644
--- a/tests/codegen/dont-shuffle-bswaps.rs
+++ b/tests/codegen/dont-shuffle-bswaps.rs
@@ -3,7 +3,6 @@
 //@[OPT3] compile-flags: -C opt-level=3
 // some targets don't do the opt we are looking for
 //@[OPT3] only-64bit
-//@ min-llvm-version: 18.1.3
 
 #![crate_type = "lib"]
 #![no_std]
diff --git a/tests/codegen/enum/enum-two-variants-match.rs b/tests/codegen/enum/enum-two-variants-match.rs
index c1f208d7909..21ae1f96bca 100644
--- a/tests/codegen/enum/enum-two-variants-match.rs
+++ b/tests/codegen/enum/enum-two-variants-match.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@ min-llvm-version: 19 (for trunc nuw)
 //@ only-x86_64 (because these discriminants are isize)
 
 #![crate_type = "lib"]
diff --git a/tests/codegen/float/algebraic.rs b/tests/codegen/float/algebraic.rs
new file mode 100644
index 00000000000..818a4bcdfe3
--- /dev/null
+++ b/tests/codegen/float/algebraic.rs
@@ -0,0 +1,149 @@
+// Verify that algebraic intrinsics generate the correct LLVM calls
+
+// Ensure operations get inlined
+//@ compile-flags: -Copt-level=1
+
+#![crate_type = "lib"]
+#![feature(f16)]
+#![feature(f128)]
+#![feature(float_algebraic)]
+
+// CHECK-LABEL: @f16_algebraic_add
+#[no_mangle]
+pub fn f16_algebraic_add(a: f16, b: f16) -> f16 {
+    // CHECK: fadd reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_sub
+#[no_mangle]
+pub fn f16_algebraic_sub(a: f16, b: f16) -> f16 {
+    // CHECK: fsub reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_mul
+#[no_mangle]
+pub fn f16_algebraic_mul(a: f16, b: f16) -> f16 {
+    // CHECK: fmul reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_div
+#[no_mangle]
+pub fn f16_algebraic_div(a: f16, b: f16) -> f16 {
+    // CHECK: fdiv reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_rem
+#[no_mangle]
+pub fn f16_algebraic_rem(a: f16, b: f16) -> f16 {
+    // CHECK: frem reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_add
+#[no_mangle]
+pub fn f32_algebraic_add(a: f32, b: f32) -> f32 {
+    // CHECK: fadd reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_sub
+#[no_mangle]
+pub fn f32_algebraic_sub(a: f32, b: f32) -> f32 {
+    // CHECK: fsub reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_mul
+#[no_mangle]
+pub fn f32_algebraic_mul(a: f32, b: f32) -> f32 {
+    // CHECK: fmul reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_div
+#[no_mangle]
+pub fn f32_algebraic_div(a: f32, b: f32) -> f32 {
+    // CHECK: fdiv reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_rem
+#[no_mangle]
+pub fn f32_algebraic_rem(a: f32, b: f32) -> f32 {
+    // CHECK: frem reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_add
+#[no_mangle]
+pub fn f64_algebraic_add(a: f64, b: f64) -> f64 {
+    // CHECK: fadd reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_sub
+#[no_mangle]
+pub fn f64_algebraic_sub(a: f64, b: f64) -> f64 {
+    // CHECK: fsub reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_mul
+#[no_mangle]
+pub fn f64_algebraic_mul(a: f64, b: f64) -> f64 {
+    // CHECK: fmul reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_div
+#[no_mangle]
+pub fn f64_algebraic_div(a: f64, b: f64) -> f64 {
+    // CHECK: fdiv reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_rem
+#[no_mangle]
+pub fn f64_algebraic_rem(a: f64, b: f64) -> f64 {
+    // CHECK: frem reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_add
+#[no_mangle]
+pub fn f128_algebraic_add(a: f128, b: f128) -> f128 {
+    // CHECK: fadd reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_sub
+#[no_mangle]
+pub fn f128_algebraic_sub(a: f128, b: f128) -> f128 {
+    // CHECK: fsub reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_mul
+#[no_mangle]
+pub fn f128_algebraic_mul(a: f128, b: f128) -> f128 {
+    // CHECK: fmul reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_div
+#[no_mangle]
+pub fn f128_algebraic_div(a: f128, b: f128) -> f128 {
+    // CHECK: fdiv reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_rem
+#[no_mangle]
+pub fn f128_algebraic_rem(a: f128, b: f128) -> f128 {
+    // CHECK: frem reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
diff --git a/tests/codegen/float_math.rs b/tests/codegen/float_math.rs
index 31387ec82b9..9a1e0b4d2d0 100644
--- a/tests/codegen/float_math.rs
+++ b/tests/codegen/float_math.rs
@@ -3,7 +3,10 @@
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
 
-use std::intrinsics::{fadd_fast, fdiv_fast, fmul_fast, frem_fast, fsub_fast};
+use std::intrinsics::{
+    fadd_algebraic, fadd_fast, fdiv_algebraic, fdiv_fast, fmul_algebraic, fmul_fast,
+    frem_algebraic, frem_fast, fsub_algebraic, fsub_fast,
+};
 
 // CHECK-LABEL: @add
 #[no_mangle]
@@ -13,30 +16,72 @@ pub fn add(x: f32, y: f32) -> f32 {
     x + y
 }
 
-// CHECK-LABEL: @addition
+// CHECK-LABEL: @test_fadd_algebraic
 #[no_mangle]
-pub fn addition(x: f32, y: f32) -> f32 {
-    // CHECK: fadd fast float
+pub fn test_fadd_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fadd reassoc nsz arcp contract float %x, %y
+    fadd_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fsub_algebraic
+#[no_mangle]
+pub fn test_fsub_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fsub reassoc nsz arcp contract float %x, %y
+    fsub_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fmul_algebraic
+#[no_mangle]
+pub fn test_fmul_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fmul reassoc nsz arcp contract float %x, %y
+    fmul_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fdiv_algebraic
+#[no_mangle]
+pub fn test_fdiv_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fdiv reassoc nsz arcp contract float %x, %y
+    fdiv_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_frem_algebraic
+#[no_mangle]
+pub fn test_frem_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: frem reassoc nsz arcp contract float %x, %y
+    frem_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fadd_fast
+#[no_mangle]
+pub fn test_fadd_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fadd fast float %x, %y
     unsafe { fadd_fast(x, y) }
 }
 
-// CHECK-LABEL: @subtraction
+// CHECK-LABEL: @test_fsub_fast
 #[no_mangle]
-pub fn subtraction(x: f32, y: f32) -> f32 {
-    // CHECK: fsub fast float
+pub fn test_fsub_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fsub fast float %x, %y
     unsafe { fsub_fast(x, y) }
 }
 
-// CHECK-LABEL: @multiplication
+// CHECK-LABEL: @test_fmul_fast
 #[no_mangle]
-pub fn multiplication(x: f32, y: f32) -> f32 {
-    // CHECK: fmul fast float
+pub fn test_fmul_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fmul fast float %x, %y
     unsafe { fmul_fast(x, y) }
 }
 
-// CHECK-LABEL: @division
+// CHECK-LABEL: @test_fdiv_fast
 #[no_mangle]
-pub fn division(x: f32, y: f32) -> f32 {
-    // CHECK: fdiv fast float
+pub fn test_fdiv_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fdiv fast float %x, %y
     unsafe { fdiv_fast(x, y) }
 }
+
+// CHECK-LABEL: @test_frem_fast
+#[no_mangle]
+pub fn test_frem_fast(x: f32, y: f32) -> f32 {
+    // CHECK: frem fast float %x, %y
+    unsafe { frem_fast(x, y) }
+}
diff --git a/tests/codegen/intrinsics/carrying_mul_add.rs b/tests/codegen/intrinsics/carrying_mul_add.rs
index b53585a8a6e..21fb49a3786 100644
--- a/tests/codegen/intrinsics/carrying_mul_add.rs
+++ b/tests/codegen/intrinsics/carrying_mul_add.rs
@@ -1,7 +1,6 @@
 //@ revisions: RAW OPT
 //@ compile-flags: -C opt-level=1
 //@[RAW] compile-flags: -C no-prepopulate-passes
-//@[OPT] min-llvm-version: 19
 
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs
index 4849b88c09c..560ebcccdd0 100644
--- a/tests/codegen/intrinsics/transmute.rs
+++ b/tests/codegen/intrinsics/transmute.rs
@@ -12,9 +12,6 @@ use std::intrinsics::{transmute, transmute_unchecked};
 use std::mem::MaybeUninit;
 use std::num::NonZero;
 
-// FIXME(LLVM18REMOVED): `trunc nuw` doesn't exist in LLVM 18, so once we no
-// longer support it the optional flag checks can be changed to required.
-
 pub enum ZstNever {}
 
 #[repr(align(2))]
@@ -157,7 +154,7 @@ pub unsafe fn check_from_newtype(x: Scalar64) -> u64 {
 pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool {
     // CHECK: %x = alloca [1 x i8], align 1
     // CHECK: %[[BYTE:.+]] = load i8, ptr %x, align 1
-    // CHECK: %[[BOOL:.+]] = trunc{{( nuw)?}} i8 %[[BYTE]] to i1
+    // CHECK: %[[BOOL:.+]] = trunc nuw i8 %[[BYTE]] to i1
     // CHECK: ret i1 %[[BOOL]]
     transmute(x)
 }
@@ -175,7 +172,7 @@ pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 {
 #[no_mangle]
 pub unsafe fn check_byte_to_bool(x: u8) -> bool {
     // CHECK-NOT: alloca
-    // CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1
+    // CHECK: %[[R:.+]] = trunc nuw i8 %x to i1
     // CHECK: ret i1 %[[R]]
     transmute(x)
 }
@@ -288,7 +285,7 @@ pub unsafe fn check_long_array_more_aligned(x: [u8; 100]) -> [u32; 25] {
 #[no_mangle]
 pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) {
     // CHECK-NOT: alloca
-    // CHECK: trunc{{( nuw)?}} i8 %x.0 to i1
+    // CHECK: trunc nuw i8 %x.0 to i1
     // CHECK: zext i1 %x.1 to i8
     transmute(x)
 }
@@ -342,7 +339,7 @@ pub unsafe fn check_heterogeneous_integer_pair(x: (i32, bool)) -> (bool, u32) {
     // CHECK: store i8 %[[WIDER]]
 
     // CHECK: %[[BYTE:.+]] = load i8
-    // CHECK: trunc{{( nuw)?}} i8 %[[BYTE:.+]] to i1
+    // CHECK: trunc nuw i8 %[[BYTE:.+]] to i1
     // CHECK: load i32
     transmute(x)
 }
diff --git a/tests/codegen/issues/issue-107681-unwrap_unchecked.rs b/tests/codegen/issues/issue-107681-unwrap_unchecked.rs
index fd7296de4c8..69aefc6b1fb 100644
--- a/tests/codegen/issues/issue-107681-unwrap_unchecked.rs
+++ b/tests/codegen/issues/issue-107681-unwrap_unchecked.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 19
 
 // Test for #107681.
 // Make sure we don't create `br` or `select` instructions.
diff --git a/tests/codegen/issues/issue-118306.rs b/tests/codegen/issues/issue-118306.rs
index f9f3e0c0529..f12dc7cdfe2 100644
--- a/tests/codegen/issues/issue-118306.rs
+++ b/tests/codegen/issues/issue-118306.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 19
 //@ only-x86_64
 
 // Test for #118306.
diff --git a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
index fbea4ee8979..853a1ff36b1 100644
--- a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
+++ b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 
@@ -37,6 +36,8 @@ pub unsafe fn update(s: *mut State) {
     // CHECK-NOT: store
     // CHECK-NOT: memcpy
     // CHECK-NOT: 75{{3|4}}
+
+    // CHECK: ret
     let State::A(v) = s.read() else { std::hint::unreachable_unchecked() };
     s.write(State::B(v));
 }
diff --git a/tests/codegen/issues/issue-126585.rs b/tests/codegen/issues/issue-126585.rs
index a468efd728d..466dab64cdc 100644
--- a/tests/codegen/issues/issue-126585.rs
+++ b/tests/codegen/issues/issue-126585.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=s
-//@ min-llvm-version: 19
 //@ only-x86_64
 
 // Test for #126585.
diff --git a/tests/codegen/range-attribute.rs b/tests/codegen/range-attribute.rs
index e23f5e6bb74..b81ff9ab3e2 100644
--- a/tests/codegen/range-attribute.rs
+++ b/tests/codegen/range-attribute.rs
@@ -6,7 +6,6 @@
 //@[bit32] only-32bit
 //@[bit64] only-64bit
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs b/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs
new file mode 100644
index 00000000000..9a2290901d6
--- /dev/null
+++ b/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs
@@ -0,0 +1,19 @@
+// Verifies that "kcfi-arity" module flag is added.
+//
+//@ add-core-stubs
+//@ revisions: x86_64
+//@ [x86_64] compile-flags: --target x86_64-unknown-none
+//@ [x86_64] needs-llvm-components: x86
+//@ compile-flags: -Ctarget-feature=-crt-static -Cpanic=abort -Zsanitizer=kcfi -Zsanitizer-kcfi-arity
+//@ min-llvm-version: 21.0.0
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+pub fn foo() {}
+
+// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi-arity", i32 1}
diff --git a/tests/codegen/slice-last-elements-optimization.rs b/tests/codegen/slice-last-elements-optimization.rs
new file mode 100644
index 00000000000..b90f91d7b17
--- /dev/null
+++ b/tests/codegen/slice-last-elements-optimization.rs
@@ -0,0 +1,37 @@
+//@ compile-flags: -Copt-level=3
+//@ only-x86_64
+//@ min-llvm-version: 20
+#![crate_type = "lib"]
+
+// This test verifies that LLVM 20 properly optimizes the bounds check
+// when accessing the last few elements of a slice with proper conditions.
+// Previously, this would generate an unreachable branch to
+// slice_start_index_len_fail even when the bounds check was provably safe.
+
+// CHECK-LABEL: @last_four_initial(
+#[no_mangle]
+pub fn last_four_initial(s: &[u8]) -> &[u8] {
+    // Previously this would generate a branch to slice_start_index_len_fail
+    // that is unreachable. The LLVM 20 fix should eliminate this branch.
+    // CHECK-NOT: slice_start_index_len_fail
+    // CHECK-NOT: unreachable
+    let start = if s.len() <= 4 { 0 } else { s.len() - 4 };
+    &s[start..]
+}
+
+// CHECK-LABEL: @last_four_optimized(
+#[no_mangle]
+pub fn last_four_optimized(s: &[u8]) -> &[u8] {
+    // This version was already correctly optimized before the fix in LLVM 20.
+    // CHECK-NOT: slice_start_index_len_fail
+    // CHECK-NOT: unreachable
+    if s.len() <= 4 { &s[0..] } else { &s[s.len() - 4..] }
+}
+
+// Just to verify we're correctly checking for the right thing
+// CHECK-LABEL: @test_bounds_check_happens(
+#[no_mangle]
+pub fn test_bounds_check_happens(s: &[u8], i: usize) -> &[u8] {
+    // CHECK: slice_start_index_len_fail
+    &s[i..]
+}
diff --git a/tests/codegen/slice-split-at.rs b/tests/codegen/slice-split-at.rs
new file mode 100644
index 00000000000..07018cf9c91
--- /dev/null
+++ b/tests/codegen/slice-split-at.rs
@@ -0,0 +1,24 @@
+//@ compile-flags: -Copt-level=3
+#![crate_type = "lib"]
+
+// Check that no panic is generated in `split_at` when calculating the index for
+// the tail chunk using `checked_sub`.
+//
+// Tests written for refactored implementations of:
+// `<[T]>::{split_last_chunk, split_last_chunk_mut, last_chunk, last_chunk_mut}`
+
+// CHECK-LABEL: @split_at_last_chunk
+#[no_mangle]
+pub fn split_at_last_chunk(s: &[u8], chunk_size: usize) -> Option<(&[u8], &[u8])> {
+    // CHECK-NOT: panic
+    let Some(index) = s.len().checked_sub(chunk_size) else { return None };
+    Some(s.split_at(index))
+}
+
+// CHECK-LABEL: @split_at_mut_last_chunk
+#[no_mangle]
+pub fn split_at_mut_last_chunk(s: &mut [u8], chunk_size: usize) -> Option<(&mut [u8], &mut [u8])> {
+    // CHECK-NOT: panic
+    let Some(index) = s.len().checked_sub(chunk_size) else { return None };
+    Some(s.split_at_mut(index))
+}
diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs
index 8b1f3b14fc3..6be0e21e0ef 100644
--- a/tests/codegen/tied-features-strength.rs
+++ b/tests/codegen/tied-features-strength.rs
@@ -4,21 +4,17 @@
 //@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
 //@ needs-llvm-components: aarch64
 
-// The "+fpmr" feature is matched as optional as it is only an explicit
-// feature in LLVM 18. Once the min supported version is LLVM-19 the optional
-// regex matching for this feature can be removed.
-
 //@ [ENABLE_SVE] compile-flags: -C target-feature=+sve -Copt-level=0
-// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
+// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
 
 //@ [DISABLE_SVE] compile-flags: -C target-feature=-sve -Copt-level=0
-// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-sve,?)|(\+neon,?))*}}" }
+// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(-sve,?)|(\+neon,?))*}}" }
 
 //@ [DISABLE_NEON] compile-flags: -C target-feature=-neon -Copt-level=0
-// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
+// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(-fp-armv8,?)|(-neon,?))*}}" }
 
 //@ [ENABLE_NEON] compile-flags: -C target-feature=+neon -Copt-level=0
-// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
+// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fp-armv8,?)|(\+neon,?))*}}" }
 
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index 3a3453b22b4..9f68d742a75 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -1,10 +1,8 @@
 //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled --edition=2021
 //@ only-x86_64
-// FIXME: Remove the `min-llvm-version`.
 //@ revisions: NINETEEN TWENTY
 //@[NINETEEN] exact-llvm-major-version: 19
 //@[TWENTY] min-llvm-version: 20
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 #![feature(try_blocks)]
@@ -16,12 +14,17 @@ use std::ptr::NonNull;
 #[no_mangle]
 pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
-    // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
-    // TWENTY-NEXT: %[[PAYLOAD:.+]] = select i1 %[[IS_SOME]], i32 %1, i32 undef
-    // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
-    // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1
-    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %[[PAYLOAD]], 1
-    // CHECK-NEXT: ret { i32, i32 } [[REG2]]
+    // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1
+
+    // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %0, i32 0
+    // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 [[SELECT]], 0
+    // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 %1, 1
+
+    // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef
+    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
+    // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1
+
+    // CHECK-NEXT: ret { i32, i32 } [[REG3]]
     match x {
         Some(x) => Some(x),
         None => None,
@@ -90,12 +93,17 @@ pub fn control_flow_nop_traits_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32,
 #[no_mangle]
 pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> {
     // CHECK: start:
-    // TWENTY-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1
-    // TWENTY-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef
-    // CHECK-NEXT: [[REG1:%[0-9a-zA-Z_.]+]] = insertvalue { i64, i64 } poison, i64 %0, 0
-    // NINETEEN-NEXT: [[REG2:%[0-9a-zA-Z_.]+]] = insertvalue { i64, i64 } [[REG1]], i64 %1, 1
-    // TWENTY-NEXT: [[REG2:%[0-9a-zA-Z_.]+]] = insertvalue { i64, i64 } [[REG1]], i64 %[[SEL]], 1
-    // CHECK-NEXT: ret { i64, i64 } [[REG2]]
+    // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i64 %0 to i1
+
+    // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %0, i64 0
+    // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 [[SELECT]], 0
+    // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 %1, 1
+
+    // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef
+    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0
+    // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1
+
+    // CHECK-NEXT: ret { i64, i64 } [[REG3]]
     match x {
         Some(x) => Some(x),
         None => None,
@@ -164,8 +172,8 @@ pub fn control_flow_nop_traits_64(x: ControlFlow<i64, u64>) -> ControlFlow<i64,
 #[no_mangle]
 pub fn result_nop_match_128(x: Result<i128, u128>) -> Result<i128, u128> {
     // CHECK: start:
-    // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8
     // CHECK-NEXT: store i128
+    // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8
     // CHECK-NEXT: store i128
     // CHECK-NEXT: ret void
     match x {
@@ -189,8 +197,8 @@ pub fn result_nop_traits_128(x: Result<i128, u128>) -> Result<i128, u128> {
 #[no_mangle]
 pub fn control_flow_nop_match_128(x: ControlFlow<i128, u128>) -> ControlFlow<i128, u128> {
     // CHECK: start:
-    // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8
     // CHECK-NEXT: store i128
+    // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8
     // CHECK-NEXT: store i128
     // CHECK-NEXT: ret void
     match x {
diff --git a/tests/codegen/unchecked_shifts.rs b/tests/codegen/unchecked_shifts.rs
index 9fccaf2252e..3f533718a2d 100644
--- a/tests/codegen/unchecked_shifts.rs
+++ b/tests/codegen/unchecked_shifts.rs
@@ -1,7 +1,4 @@
-//@ revisions: LLVM18 LLVM19PLUS
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@[LLVM18] exact-llvm-major-version: 18
-//@[LLVM19PLUS] min-llvm-version: 19
 
 // This runs mir-opts to inline the standard library call, but doesn't run LLVM
 // optimizations so it doesn't need to worry about them adding more flags.
@@ -24,8 +21,7 @@ pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 {
 #[no_mangle]
 pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
     // CHECK: shl i16 %a, %[[TRUNC]]
     a.unchecked_shl(b)
 }
@@ -53,8 +49,7 @@ pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 {
 #[no_mangle]
 pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
     // CHECK: ashr i16 %a, %[[TRUNC]]
     a.unchecked_shr(b)
 }
@@ -90,8 +85,7 @@ pub unsafe fn unchecked_shl_i128_u8(a: i128, b: u8) -> i128 {
 #[no_mangle]
 pub unsafe fn unchecked_shl_u8_i128(a: u8, b: i128) -> u8 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
     // CHECK: shl i8 %a, %[[TRUNC]]
     std::intrinsics::unchecked_shl(a, b)
 }
@@ -100,8 +94,7 @@ pub unsafe fn unchecked_shl_u8_i128(a: u8, b: i128) -> u8 {
 #[no_mangle]
 pub unsafe fn unchecked_shr_i8_u128(a: i8, b: u128) -> i8 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
     // CHECK: ashr i8 %a, %[[TRUNC]]
     std::intrinsics::unchecked_shr(a, b)
 }
diff --git a/tests/codegen/vec_pop_push_noop.rs b/tests/codegen/vec_pop_push_noop.rs
index 2635660596a..3e375219fe0 100644
--- a/tests/codegen/vec_pop_push_noop.rs
+++ b/tests/codegen/vec_pop_push_noop.rs
@@ -1,6 +1,3 @@
-//@ revisions: llvm-pre-19 llvm-19
-//@ [llvm-19] min-llvm-version: 19
-//@ [llvm-pre-19] max-llvm-major-version: 18
 //@ compile-flags: -Copt-level=3
 
 #![crate_type = "lib"]
diff --git a/tests/coverage-run-rustdoc/doctest.coverage b/tests/coverage-run-rustdoc/doctest.coverage
index f007eb0cade..0fa94361c47 100644
--- a/tests/coverage-run-rustdoc/doctest.coverage
+++ b/tests/coverage-run-rustdoc/doctest.coverage
@@ -58,21 +58,21 @@ $DIR/doctest.rs:
    LL|       |//!
    LL|       |//! doctest with custom main:
    LL|       |//! ```
-   LL|      1|//! fn some_func() {
-   LL|      1|//!     println!("called some_func()");
-   LL|      1|//! }
-   LL|       |//!
-   LL|       |//! #[derive(Debug)]
-   LL|       |//! struct SomeError;
+   LL|       |//! fn some_func() {
+   LL|       |//!     println!("called some_func()");
+   LL|       |//! }
+   LL|      1|//!
+   LL|      1|//! #[derive(Debug)]
+   LL|      1|//! struct SomeError;
    LL|       |//!
    LL|       |//! extern crate doctest_crate;
    LL|       |//!
-   LL|      1|//! fn doctest_main() -> Result<(), SomeError> {
+   LL|       |//! fn doctest_main() -> Result<(), SomeError> {
    LL|      1|//!     some_func();
    LL|      1|//!     doctest_crate::fn_run_in_doctests(2);
    LL|      1|//!     Ok(())
    LL|      1|//! }
-   LL|       |//!
+   LL|      1|//!
    LL|       |//! // this `main` is not shown as covered, as it clashes with all the other
    LL|       |//! // `main` functions that were automatically generated for doctests
    LL|       |//! fn main() -> Result<(), SomeError> {
diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map
index 84fae4a595a..26536caeba5 100644
--- a/tests/coverage/abort.cov-map
+++ b/tests/coverage/abort.cov-map
@@ -34,14 +34,14 @@ Number of file 0 mappings: 13
 Highest counter ID seen: c4
 
 Function name: abort::might_abort
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 24, 02, 02, 0c, 03, 02]
+Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 3, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 36)
+- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15)
 - Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
     = (c0 - c1)
 Highest counter ID seen: c1
diff --git a/tests/coverage/assert-ne.cov-map b/tests/coverage/assert-ne.cov-map
index b432e63c168..27d4b0382de 100644
--- a/tests/coverage/assert-ne.cov-map
+++ b/tests/coverage/assert-ne.cov-map
@@ -1,12 +1,12 @@
 Function name: assert_ne::main
-Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 1c, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 02]
+Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 15, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 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(0), rhs = Counter(2)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28)
+- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 21)
 - Code(Counter(1)) at (prev + 4, 13) to (start + 0, 19)
 - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c0 - c1)
diff --git a/tests/coverage/assert-ne.coverage b/tests/coverage/assert-ne.coverage
index 236a8fd1385..fc43d4a8e06 100644
--- a/tests/coverage/assert-ne.coverage
+++ b/tests/coverage/assert-ne.coverage
@@ -7,7 +7,7 @@
    LL|       |
    LL|      1|fn main() {
    LL|      1|    assert_ne!(
-   LL|      1|        Foo(5), // Make sure this expression's span isn't lost.
+   LL|      1|        black_box(Foo(5)), // Make sure this expression's span isn't lost.
    LL|      1|        if black_box(false) {
    LL|      0|            Foo(0) //
    LL|       |        } else {
diff --git a/tests/coverage/assert-ne.rs b/tests/coverage/assert-ne.rs
index 8a8fe089804..9d9fcb71ba7 100644
--- a/tests/coverage/assert-ne.rs
+++ b/tests/coverage/assert-ne.rs
@@ -7,7 +7,7 @@ struct Foo(u32);
 
 fn main() {
     assert_ne!(
-        Foo(5), // Make sure this expression's span isn't lost.
+        black_box(Foo(5)), // Make sure this expression's span isn't lost.
         if black_box(false) {
             Foo(0) //
         } else {
diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map
index 526110ebbb7..3aef4274edc 100644
--- a/tests/coverage/assert_not.cov-map
+++ b/tests/coverage/assert_not.cov-map
@@ -1,13 +1,13 @@
 Function name: assert_not::main
-Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 12, 01, 02, 05, 00, 14, 01, 01, 05, 00, 14, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 11, 01, 02, 05, 00, 13, 01, 01, 05, 00, 13, 01, 01, 05, 00, 15, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 18)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 20)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 20)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 17)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 21)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map
index 5eb69e668ca..d9196f446f1 100644
--- a/tests/coverage/async_block.cov-map
+++ b/tests/coverage/async_block.cov-map
@@ -1,5 +1,5 @@
 Function name: async_block::main
-Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 07, 01, 00, 0b, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 00, 14, 01, 16, 02, 07, 0a, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 07, 01, 00, 0b, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 22, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -9,11 +9,11 @@ Number of file 0 mappings: 6
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
     = (c1 - c0)
 - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19)
-- Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 1, 22)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19)
     = (c1 - c0)
-- Code(Expression(0, Sub)) at (prev + 7, 10) to (start + 2, 6)
+- Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 34)
     = (c1 - c0)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: async_block::main::{closure#0}
diff --git a/tests/coverage/async_block.coverage b/tests/coverage/async_block.coverage
index 9e3294492cd..4e00024aebd 100644
--- a/tests/coverage/async_block.coverage
+++ b/tests/coverage/async_block.coverage
@@ -15,6 +15,6 @@
    LL|     12|            }
    LL|     16|        };
    LL|     16|        executor::block_on(future);
-   LL|     16|    }
+   LL|       |    }
    LL|      1|}
 
diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map
index 9144a938a9e..a4ef0ceeb6d 100644
--- a/tests/coverage/async_closure.cov-map
+++ b/tests/coverage/async_closure.cov-map
@@ -30,29 +30,31 @@ Number of file 0 mappings: 2
 Highest counter ID seen: c0
 
 Function name: async_closure::main::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36)
 Highest counter ID seen: c0
 
-Function name: async_closure::main::{closure#0}::{closure#0}::<i16>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24]
+Function name: async_closure::main::{closure#0}
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36)
 Highest counter ID seen: c0
 
-Function name: async_closure::main::{closure#0}::{closure#1}::<i32>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24]
+Function name: async_closure::main::{closure#0}::{closure#0}::<i16>
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage
index 7fbea265812..5aed131de2e 100644
--- a/tests/coverage/async_closure.coverage
+++ b/tests/coverage/async_closure.coverage
@@ -9,12 +9,14 @@
    LL|       |
    LL|      1|pub fn main() {
    LL|      2|    let async_closure = async || {};
-                                               ^1
   ------------------
   | async_closure::main::{closure#0}:
   |   LL|      1|    let async_closure = async || {};
   ------------------
-  | async_closure::main::{closure#0}::{closure#1}::<i32>:
+  | async_closure::main::{closure#0}:
+  |   LL|      1|    let async_closure = async || {};
+  ------------------
+  | async_closure::main::{closure#0}::{closure#0}::<i16>:
   |   LL|      1|    let async_closure = async || {};
   ------------------
    LL|      1|    executor::block_on(async_closure());
diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map
index ef6f5a9dc42..c55c5897d8b 100644
--- a/tests/coverage/attr/off-on-sandwich.cov-map
+++ b/tests/coverage/attr/off-on-sandwich.cov-map
@@ -1,30 +1,30 @@
 Function name: off_on_sandwich::dense_a::dense_b
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 05, 02, 12, 01, 07, 05, 00, 06]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 05, 02, 10, 01, 07, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 5) to (start + 2, 18)
+- Code(Counter(0)) at (prev + 16, 5) to (start + 2, 16)
 - Code(Counter(0)) at (prev + 7, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 22, 09, 02, 17, 01, 0b, 09, 00, 0a]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 22, 09, 02, 15, 01, 0b, 09, 00, 0a]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 34, 9) to (start + 2, 23)
+- Code(Counter(0)) at (prev + 34, 9) to (start + 2, 21)
 - Code(Counter(0)) at (prev + 11, 9) to (start + 0, 10)
 Highest counter ID seen: c0
 
 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 25, 0d, 02, 1b, 01, 07, 0d, 00, 0e]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 25, 0d, 02, 19, 01, 07, 0d, 00, 0e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 37, 13) to (start + 2, 27)
+- Code(Counter(0)) at (prev + 37, 13) to (start + 2, 25)
 - Code(Counter(0)) at (prev + 7, 13) to (start + 0, 14)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map
index baac0073fcb..f08a70a899d 100644
--- a/tests/coverage/bad_counter_ids.cov-map
+++ b/tests/coverage/bad_counter_ids.cov-map
@@ -1,10 +1,10 @@
 Function name: bad_counter_ids::eq_bad
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 01, 02, 1f, 00, 03, 01, 00, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 01, 02, 0f, 00, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 31)
+- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 15)
 - Code(Zero) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
@@ -20,12 +20,12 @@ Number of file 0 mappings: 3
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::eq_good
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 1f, 01, 03, 01, 00, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 0f, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 2, 31)
+- Code(Counter(0)) at (prev + 16, 1) to (start + 2, 15)
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
@@ -41,12 +41,12 @@ Number of file 0 mappings: 3
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::ne_bad
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 1f, 00, 03, 01, 00, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 0f, 00, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 46, 1) to (start + 2, 31)
+- Code(Counter(0)) at (prev + 46, 1) to (start + 2, 15)
 - Code(Zero) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
@@ -62,12 +62,12 @@ Number of file 0 mappings: 3
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::ne_good
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 1f, 01, 03, 01, 00, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 0f, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 31)
+- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 15)
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map
index 55f45daa9c9..46533df00f7 100644
--- a/tests/coverage/branch/guard.cov-map
+++ b/tests/coverage/branch/guard.cov-map
@@ -1,5 +1,5 @@
 Function name: guard::branch_match_guard
-Raw bytes (89): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 0d, 01, 0c, 01, 01, 10, 02, 03, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02]
+Raw bytes (89): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 0d, 01, 0c, 01, 01, 0e, 02, 03, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -12,7 +12,7 @@ Number of expressions: 8
 - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4)
 - expression 7 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
 - Code(Expression(0, Sub)) at (prev + 3, 11) to (start + 0, 12)
     = (c1 - c3)
 - Code(Expression(1, Sub)) at (prev + 1, 20) to (start + 2, 10)
diff --git a/tests/coverage/branch/if-let.cov-map b/tests/coverage/branch/if-let.cov-map
index db45df2a5cd..7f6b174615a 100644
--- a/tests/coverage/branch/if-let.cov-map
+++ b/tests/coverage/branch/if-let.cov-map
@@ -1,11 +1,11 @@
 Function name: if_let::if_let
-Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 10, 20, 02, 05, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
 - Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 12) to (start + 0, 19)
     true  = (c0 - c1)
     false = c1
diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map
index a6b865318c6..1d40f032aa8 100644
--- a/tests/coverage/branch/if.cov-map
+++ b/tests/coverage/branch/if.cov-map
@@ -1,5 +1,5 @@
 Function name: if::branch_and
-Raw bytes (54): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 2b, 01, 01, 10, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (54): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 2b, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -7,7 +7,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 43, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 43, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -23,7 +23,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::branch_not
-Raw bytes (116): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 12, 01, 0c, 01, 01, 10, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (116): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 12, 01, 0c, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 7
@@ -35,12 +35,12 @@ Number of expressions: 7
 - expression 5 operands: lhs = Counter(0), rhs = Counter(4)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(4)
 Number of file 0 mappings: 18
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16)
 - Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 8) to (start + 0, 10)
@@ -68,7 +68,7 @@ Number of file 0 mappings: 18
 Highest counter ID seen: c4
 
 Function name: if::branch_not_as
-Raw bytes (90): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0e, 01, 1d, 01, 01, 10, 01, 03, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (90): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0e, 01, 1d, 01, 01, 0e, 01, 03, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
@@ -78,7 +78,7 @@ Number of expressions: 5
 - expression 3 operands: lhs = Counter(0), rhs = Counter(3)
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 8) to (start + 0, 20)
 - Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 0, 8) to (start + 0, 20)
     true  = (c0 - c1)
@@ -104,7 +104,7 @@ Number of file 0 mappings: 14
 Highest counter ID seen: c3
 
 Function name: if::branch_or
-Raw bytes (60): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 08, 01, 35, 01, 01, 10, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (60): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 08, 01, 35, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 6
@@ -115,7 +115,7 @@ Number of expressions: 6
 - expression 4 operands: lhs = Counter(0), rhs = Expression(5, Add)
 - expression 5 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 53, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 53, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map
index 622f30e2b56..5d4fc57eb8f 100644
--- a/tests/coverage/branch/lazy-boolean.cov-map
+++ b/tests/coverage/branch/lazy-boolean.cov-map
@@ -1,11 +1,11 @@
 Function name: lazy_boolean::branch_and
-Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 13, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 13, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -16,13 +16,13 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: lazy_boolean::branch_or
-Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 1b, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 1b, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 27, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 27, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -34,7 +34,7 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: lazy_boolean::chain
-Raw bytes (141): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 13, 01, 24, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 11, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 01, 02]
+Raw bytes (141): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 13, 01, 24, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 15
@@ -54,7 +54,7 @@ Number of expressions: 15
 - expression 13 operands: lhs = Expression(14, Add), rhs = Counter(6)
 - expression 14 operands: lhs = Counter(4), rhs = Counter(5)
 Number of file 0 mappings: 19
-- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 18)
@@ -69,7 +69,7 @@ Number of file 0 mappings: 19
     true  = c3
     false = (c2 - c3)
 - Code(Counter(3)) at (prev + 0, 40) to (start + 0, 45)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
 - Branch { true: Counter(4), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 18)
@@ -91,7 +91,7 @@ Number of file 0 mappings: 19
 Highest counter ID seen: c6
 
 Function name: lazy_boolean::nested_mixed
-Raw bytes (137): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 13, 01, 31, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 11, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 01, 02]
+Raw bytes (137): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 13, 01, 31, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 13
@@ -109,7 +109,7 @@ Number of expressions: 13
 - expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add)
 - expression 12 operands: lhs = Counter(5), rhs = Counter(6)
 Number of file 0 mappings: 19
-- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19)
@@ -127,7 +127,7 @@ Number of file 0 mappings: 19
     false = ((c1 + c2) - c3)
 - Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 51)
     = ((c1 + c2) - c3)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
 - Branch { true: Counter(4), false: Expression(8, Sub) } at (prev + 0, 14) to (start + 0, 19)
diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map
index 215d71599e4..78507a32638 100644
--- a/tests/coverage/branch/let-else.cov-map
+++ b/tests/coverage/branch/let-else.cov-map
@@ -1,11 +1,11 @@
 Function name: let_else::let_else
-Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 10, 20, 02, 05, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 01, 0f, 02, 04, 05, 00, 0a, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
 - Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 9) to (start + 0, 16)
     true  = (c0 - c1)
     false = c1
@@ -13,7 +13,7 @@ Number of file 0 mappings: 7
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 0, 19) to (start + 0, 24)
 - Code(Counter(1)) at (prev + 1, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 11)
+- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map
index d5b4d04d401..ef71d12c8af 100644
--- a/tests/coverage/branch/match-arms.cov-map
+++ b/tests/coverage/branch/match-arms.cov-map
@@ -1,5 +1,5 @@
 Function name: match_arms::guards
-Raw bytes (88): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 0c, 01, 30, 01, 01, 10, 21, 03, 0b, 00, 10, 05, 01, 11, 00, 29, 20, 05, 02, 00, 17, 00, 1b, 09, 01, 11, 00, 29, 20, 09, 06, 00, 17, 00, 1b, 0d, 01, 11, 00, 29, 20, 0d, 0a, 00, 17, 00, 1b, 11, 01, 11, 00, 29, 20, 11, 0e, 00, 17, 00, 1b, 12, 01, 0e, 00, 18, 01, 03, 05, 01, 02]
+Raw bytes (88): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 0c, 01, 30, 01, 01, 0e, 21, 03, 0b, 00, 10, 05, 01, 11, 00, 28, 20, 05, 02, 00, 17, 00, 1b, 09, 01, 11, 00, 28, 20, 09, 06, 00, 17, 00, 1b, 0d, 01, 11, 00, 28, 20, 0d, 0a, 00, 17, 00, 1b, 11, 01, 11, 00, 28, 20, 11, 0e, 00, 17, 00, 1b, 12, 01, 0e, 00, 15, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -12,31 +12,31 @@ Number of expressions: 8
 - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3)
 - expression 7 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 12
-- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 14)
 - Code(Counter(8)) at (prev + 3, 11) to (start + 0, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 41)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 40)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c1
     false = (c5 - c1)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 41)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 40)
 - Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c2
     false = (c6 - c2)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 41)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 40)
 - Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c3
     false = (c7 - c3)
-- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 41)
+- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 40)
 - Branch { true: Counter(4), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c4
     false = (c8 - c4)
-- Code(Expression(4, Sub)) at (prev + 1, 14) to (start + 0, 24)
+- Code(Expression(4, Sub)) at (prev + 1, 14) to (start + 0, 21)
     = (c0 - (((c1 + c2) + c3) + c4))
 - Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
 Highest counter ID seen: c8
 
 Function name: match_arms::match_arms
-Raw bytes (45): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 07, 01, 18, 01, 01, 10, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 21, 09, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 02, 01, 11, 00, 21, 01, 03, 05, 01, 02]
+Raw bytes (45): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 07, 01, 18, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 20, 09, 01, 11, 00, 20, 0d, 01, 11, 00, 20, 02, 01, 11, 00, 20, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -44,18 +44,18 @@ Number of expressions: 3
 - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 33)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
-- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 32)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 32)
+- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 32)
     = (c0 - ((c1 + c2) + c3))
 - Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
 Highest counter ID seen: c3
 
 Function name: match_arms::or_patterns
-Raw bytes (57): 0x[01, 01, 04, 05, 09, 01, 0b, 03, 0d, 01, 03, 09, 01, 25, 01, 01, 10, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2e, 01, 03, 05, 01, 02]
+Raw bytes (57): 0x[01, 01, 04, 05, 09, 01, 0b, 03, 0d, 01, 03, 09, 01, 25, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2d, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -64,16 +64,16 @@ Number of expressions: 4
 - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
 - expression 3 operands: lhs = Counter(0), rhs = Expression(0, Add)
 Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16)
 - Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
 - Code(Counter(2)) at (prev + 0, 30) to (start + 0, 31)
-- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 46)
+- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 45)
     = (c1 + c2)
 - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
 - Code(Expression(1, Sub)) at (prev + 0, 30) to (start + 0, 31)
     = (c0 - ((c1 + c2) + c3))
-- Code(Expression(3, Sub)) at (prev + 0, 36) to (start + 0, 46)
+- Code(Expression(3, Sub)) at (prev + 0, 36) to (start + 0, 45)
     = (c0 - (c1 + c2))
 - Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
 Highest counter ID seen: c3
diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map
index 31322f127af..1b0c6d12e3d 100644
--- a/tests/coverage/branch/match-trivial.cov-map
+++ b/tests/coverage/branch/match-trivial.cov-map
@@ -1,19 +1,19 @@
 Function name: match_trivial::_uninhabited (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 10]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 0e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 22, 1) to (start + 1, 16)
+- Code(Zero) at (prev + 22, 1) to (start + 1, 14)
 Highest counter ID seen: (none)
 
 Function name: match_trivial::trivial
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 10, 01, 03, 0b, 05, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 0e, 01, 03, 0b, 05, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 11) to (start + 5, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map
index 5ce92c72b51..67746af051b 100644
--- a/tests/coverage/branch/while.cov-map
+++ b/tests/coverage/branch/while.cov-map
@@ -1,11 +1,11 @@
 Function name: while::while_cond
-Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 0c, 01, 01, 10, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 0c, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
 - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 16)
@@ -17,13 +17,13 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: while::while_cond_not
-Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 15, 01, 01, 10, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 15, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 21, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 21, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 1, 11) to (start + 0, 20)
 - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 20)
@@ -35,7 +35,7 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: while::while_op_and
-Raw bytes (58): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 08, 01, 1e, 01, 01, 10, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
+Raw bytes (58): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 08, 01, 1e, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
@@ -45,7 +45,7 @@ Number of expressions: 5
 - expression 3 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 4 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
 - Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
 - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
@@ -61,7 +61,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: while::while_op_or
-Raw bytes (56): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 08, 01, 29, 01, 01, 10, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
+Raw bytes (56): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 08, 01, 29, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -70,7 +70,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 14)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
 - Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
 - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map
index fa20c8cf6d7..2d784ba09b6 100644
--- a/tests/coverage/closure.cov-map
+++ b/tests/coverage/closure.cov-map
@@ -1,15 +1,15 @@
 Function name: closure::main
-Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0f, 0d, 01, 16, 0e, 06, 0a, 01, 10, 05, 13, 0d, 01, 1a, 0e, 06, 0a, 01, 10, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 05, 00, 06, 01, 01, 05, 03, 02]
+Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0d, 1b, 01, 1a, 05, 02, 0a, 01, 0c, 05, 11, 1b, 01, 1e, 05, 02, 0a, 01, 0c, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 05, 00, 06, 01, 01, 05, 03, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 24
-- Code(Counter(0)) at (prev + 9, 1) to (start + 15, 13)
-- Code(Counter(0)) at (prev + 22, 14) to (start + 6, 10)
-- Code(Counter(0)) at (prev + 16, 5) to (start + 19, 13)
-- Code(Counter(0)) at (prev + 26, 14) to (start + 6, 10)
-- Code(Counter(0)) at (prev + 16, 5) to (start + 12, 22)
+- Code(Counter(0)) at (prev + 9, 1) to (start + 13, 27)
+- Code(Counter(0)) at (prev + 26, 5) to (start + 2, 10)
+- Code(Counter(0)) at (prev + 12, 5) to (start + 17, 27)
+- Code(Counter(0)) at (prev + 30, 5) to (start + 2, 10)
+- Code(Counter(0)) at (prev + 12, 5) to (start + 12, 22)
 - Code(Counter(0)) at (prev + 22, 5) to (start + 13, 24)
 - Code(Counter(0)) at (prev + 25, 9) to (start + 1, 30)
 - Code(Counter(0)) at (prev + 4, 9) to (start + 0, 41)
diff --git a/tests/coverage/closure.coverage b/tests/coverage/closure.coverage
index 3eac52eb723..2deeb9806c4 100644
--- a/tests/coverage/closure.coverage
+++ b/tests/coverage/closure.coverage
@@ -20,18 +20,18 @@
    LL|      1|        some_string
    LL|      1|            .
    LL|      1|            unwrap_or_else
-   LL|      1|        (
-   LL|      1|            ||
+   LL|       |        (
+   LL|       |            ||
    LL|      0|            {
    LL|      0|                let mut countdown = 0;
    LL|      0|                if is_false {
    LL|      0|                    countdown = 10;
    LL|      0|                }
    LL|      0|                "alt string 1".to_owned()
-   LL|      1|            }
-   LL|      1|        )
-   LL|      1|    );
-   LL|      1|
+   LL|      0|            }
+   LL|       |        )
+   LL|       |    );
+   LL|       |
    LL|      1|    some_string = Some(String::from("the string content"));
    LL|      1|    let
    LL|      1|        a
@@ -62,8 +62,8 @@
    LL|      1|        some_string
    LL|      1|            .
    LL|      1|            unwrap_or_else
-   LL|      1|        (
-   LL|      1|            ||
+   LL|       |        (
+   LL|       |            ||
    LL|      1|            {
    LL|      1|                let mut countdown = 0;
    LL|      1|                if is_false {
@@ -71,9 +71,9 @@
    LL|      1|                }
    LL|      1|                "alt string 3".to_owned()
    LL|      1|            }
-   LL|      1|        )
-   LL|      1|    );
-   LL|      1|
+   LL|       |        )
+   LL|       |    );
+   LL|       |
    LL|      1|    some_string = None;
    LL|      1|    let
    LL|      1|        a
diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map
index 653848dd6ff..9dd99c8fab3 100644
--- a/tests/coverage/closure_macro.cov-map
+++ b/tests/coverage/closure_macro.cov-map
@@ -8,16 +8,16 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: closure_macro::main
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 33)
+- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 32)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 84)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52)
 - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
     = (c0 - c1)
diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map
index 1bd1460a147..2548754d754 100644
--- a/tests/coverage/closure_macro_async.cov-map
+++ b/tests/coverage/closure_macro_async.cov-map
@@ -17,16 +17,16 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: closure_macro_async::test::{closure#0}
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 25, 2b, 01, 21, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 25, 2b, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 37, 43) to (start + 1, 33)
+- Code(Counter(0)) at (prev + 37, 43) to (start + 1, 32)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 84)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52)
 - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
     = (c0 - c1)
diff --git a/tests/coverage/condition/conditions.cov-map b/tests/coverage/condition/conditions.cov-map
index 417637f2d2e..c34075a0bcf 100644
--- a/tests/coverage/condition/conditions.cov-map
+++ b/tests/coverage/condition/conditions.cov-map
@@ -109,15 +109,17 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: conditions::func_call
-Raw bytes (37): 0x[01, 01, 02, 01, 05, 05, 09, 05, 01, 25, 01, 01, 0a, 20, 05, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
+Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 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 = Counter(2)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 10)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 9) to (start + 0, 10)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 9) to (start + 0, 10)
     true  = c1
     false = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 15)
diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map
index c6f2d415056..fee32376d83 100644
--- a/tests/coverage/coroutine.cov-map
+++ b/tests/coverage/coroutine.cov-map
@@ -13,7 +13,7 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: coroutine::main
-Raw bytes (53): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2e, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 35, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 35, 09, 02, 01, 00, 02]
+Raw bytes (53): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
@@ -21,14 +21,14 @@ Number of expressions: 2
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 19, 1) to (start + 2, 22)
-- Code(Counter(0)) at (prev + 8, 11) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 8, 11) to (start + 0, 45)
 - Code(Counter(1)) at (prev + 1, 43) to (start + 0, 45)
-- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 53)
+- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
 - Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
 - Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
-- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 53)
+- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c1 - c2)
 - Code(Counter(2)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c3
diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map
index 3deacbc8e12..6e2d243e8dd 100644
--- a/tests/coverage/holes.cov-map
+++ b/tests/coverage/holes.cov-map
@@ -8,24 +8,24 @@ Number of file 0 mappings: 1
 Highest counter ID seen: (none)
 
 Function name: holes::main
-Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 12, 01, 05, 05, 00, 12, 01, 07, 09, 00, 11, 01, 09, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 04, 05, 00, 12, 01, 04, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 0c, 0d, 01, 0f, 0e, 05, 02]
+Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 11, 01, 05, 05, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 11, 01, 04, 05, 00, 11, 01, 07, 05, 00, 11, 01, 06, 05, 00, 11, 01, 04, 05, 00, 11, 01, 04, 05, 00, 11, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 06, 27, 01, 13, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 18)
-- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 17)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 17)
 - Code(Counter(0)) at (prev + 7, 9) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 18)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
-- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 18)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 18)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
 - Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15)
 - Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15)
-- Code(Counter(0)) at (prev + 10, 5) to (start + 12, 13)
-- Code(Counter(0)) at (prev + 15, 14) to (start + 5, 2)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 6, 39)
+- Code(Counter(0)) at (prev + 19, 5) to (start + 1, 2)
 Highest counter ID seen: c0
 
 Function name: holes::main::_unused_fn (unused)
diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage
index 1b45c12156a..a6a02f1b9d0 100644
--- a/tests/coverage/holes.coverage
+++ b/tests/coverage/holes.coverage
@@ -84,18 +84,18 @@
    LL|      1|    // `nested_filter::OnlyBodies` or equivalent.
    LL|      1|    #[rustfmt::skip]
    LL|      1|    let _const_block_inside_anon_const =
-   LL|      1|        [
-   LL|      1|            0
-   LL|      1|            ;
-   LL|      1|            7
-   LL|      1|            +
-   LL|      1|            const
+   LL|       |        [
+   LL|       |            0
+   LL|       |            ;
+   LL|       |            7
+   LL|       |            +
+   LL|       |            const
    LL|       |            {
    LL|       |                3
-   LL|      1|            }
-   LL|      1|        ]
-   LL|      1|        ;
-   LL|      1|
+   LL|       |            }
+   LL|       |        ]
+   LL|       |        ;
+   LL|       |
    LL|      1|    black_box(());
    LL|      1|}
 
diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map
index 49cdc514fed..65cefe76c29 100644
--- a/tests/coverage/inline-dead.cov-map
+++ b/tests/coverage/inline-dead.cov-map
@@ -8,14 +8,14 @@ Number of file 0 mappings: 1
 Highest counter ID seen: (none)
 
 Function name: inline_dead::live::<false>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 01, 01, 09, 05, 02, 09, 00, 0f, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 01, 01, 09, 05, 02, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 13)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map
index a569ad53cbc..7264391baaf 100644
--- a/tests/coverage/inline.cov-map
+++ b/tests/coverage/inline.cov-map
@@ -15,12 +15,12 @@ Number of file 0 mappings: 5
 Highest counter ID seen: c1
 
 Function name: inline::error
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 01, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 01, 0b]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 20)
+- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 11)
 Highest counter ID seen: c0
 
 Function name: inline::length::<char>
diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map
index c188cca1b51..f1023109008 100644
--- a/tests/coverage/issue-83601.cov-map
+++ b/tests/coverage/issue-83601.cov-map
@@ -1,12 +1,12 @@
 Function name: issue_83601::main
-Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 1c, 05, 03, 09, 01, 1c, 02, 02, 05, 03, 02]
+Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 0f, 05, 03, 09, 01, 0f, 02, 02, 05, 03, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 28)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 28)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 15)
+- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 15)
 - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2)
     = (c1 - c2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map
index c8f75cddcb5..47e2922a805 100644
--- a/tests/coverage/issue-84561.cov-map
+++ b/tests/coverage/issue-84561.cov-map
@@ -1,11 +1,11 @@
 Function name: <issue_84561::Foo as core::fmt::Debug>::fmt
-Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, 8a, 01, 05, 01, 25, 05, 01, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, 8a, 01, 05, 01, 24, 05, 01, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 138, 5) to (start + 1, 37)
+- Code(Counter(0)) at (prev + 138, 5) to (start + 1, 36)
 - Code(Counter(1)) at (prev + 1, 37) to (start + 0, 38)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
     = (c0 - c1)
@@ -59,109 +59,80 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: issue_84561::test3
-Raw bytes (315): 0x[01, 01, 1b, 1d, 21, 25, 29, 21, 25, 2d, 31, 21, 17, 25, 2d, 41, 45, 49, 4d, 51, 55, 33, 51, 49, 4d, 33, 37, 49, 4d, 51, 59, 55, 59, 55, 59, 47, 5d, 55, 59, 61, 65, 71, 75, 69, 6d, 69, 6d, 69, 6d, 63, 79, 71, 75, 79, 7d, 7d, 81, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 09, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 11, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 19, 02, 05, 00, 1f, 1d, 01, 05, 00, 0f, 02, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 29, 00, 33, 00, 41, 06, 00, 4b, 00, 5a, 0a, 01, 05, 00, 0f, 2d, 05, 09, 03, 10, 31, 05, 0d, 00, 1b, 0e, 02, 0d, 00, 1c, 12, 04, 09, 05, 06, 35, 06, 05, 03, 06, 39, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 41, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 1a, 05, 09, 03, 0a, 33, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 22, 03, 0d, 00, 1d, 26, 03, 09, 00, 13, 2e, 03, 0d, 00, 1d, 47, 03, 05, 00, 0f, 47, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 42, 02, 0d, 00, 13, 61, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 4a, 02, 0d, 00, 13, 63, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 71, 04, 0d, 00, 13, 5a, 02, 0d, 00, 17, 5a, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 5a, 02, 15, 00, 1b, 75, 04, 0d, 00, 13, 5e, 03, 09, 00, 19, 79, 02, 05, 00, 0f, 66, 03, 09, 00, 22, 7d, 02, 05, 00, 0f, 6a, 03, 09, 00, 2c, 81, 01, 02, 01, 00, 02]
+Raw bytes (279): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 33, 01, 08, 01, 03, 0f, 05, 04, 09, 01, 0f, 09, 02, 05, 04, 0f, 09, 05, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 01, 0f, 0d, 02, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 02, 0f, 0d, 06, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 01, 0f, 0d, 05, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 02, 13, 21, 03, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 27
-- expression 0 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 1 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 2 operands: lhs = Counter(8), rhs = Counter(9)
-- expression 3 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 4 operands: lhs = Counter(8), rhs = Expression(5, Add)
-- expression 5 operands: lhs = Counter(9), rhs = Counter(11)
-- expression 6 operands: lhs = Counter(16), rhs = Counter(17)
-- expression 7 operands: lhs = Counter(18), rhs = Counter(19)
-- expression 8 operands: lhs = Counter(20), rhs = Counter(21)
-- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(20)
-- expression 10 operands: lhs = Counter(18), rhs = Counter(19)
-- expression 11 operands: lhs = Expression(12, Add), rhs = Expression(13, Add)
-- expression 12 operands: lhs = Counter(18), rhs = Counter(19)
-- expression 13 operands: lhs = Counter(20), rhs = Counter(22)
-- expression 14 operands: lhs = Counter(21), rhs = Counter(22)
-- expression 15 operands: lhs = Counter(21), rhs = Counter(22)
-- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(23)
-- expression 17 operands: lhs = Counter(21), rhs = Counter(22)
-- expression 18 operands: lhs = Counter(24), rhs = Counter(25)
-- expression 19 operands: lhs = Counter(28), rhs = Counter(29)
-- expression 20 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 21 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 22 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(30)
-- expression 24 operands: lhs = Counter(28), rhs = Counter(29)
-- expression 25 operands: lhs = Counter(30), rhs = Counter(31)
-- expression 26 operands: lhs = Counter(31), rhs = Counter(32)
+Number of expressions: 10
+- expression 0 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 1 operands: lhs = Counter(3), rhs = Counter(5)
+- expression 2 operands: lhs = Counter(3), rhs = Counter(6)
+- expression 3 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 4 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 5 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 6 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 7 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(12)
+- expression 9 operands: lhs = Counter(10), rhs = Counter(11)
 Number of file 0 mappings: 51
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28)
-- Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28)
-- Code(Counter(2)) at (prev + 2, 5) to (start + 4, 31)
-- Code(Counter(3)) at (prev + 5, 5) to (start + 0, 31)
-- Code(Counter(4)) at (prev + 1, 5) to (start + 0, 31)
-- Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28)
-- Code(Counter(6)) at (prev + 2, 5) to (start + 0, 31)
-- Code(Counter(7)) at (prev + 1, 5) to (start + 0, 15)
-- Code(Expression(0, Sub)) at (prev + 0, 32) to (start + 0, 48)
+- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 15)
+- Code(Counter(1)) at (prev + 4, 9) to (start + 1, 15)
+- Code(Counter(2)) at (prev + 2, 5) to (start + 4, 15)
+- Code(Counter(2)) at (prev + 5, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15)
+- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 48)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 3, 15)
+- Code(Zero) at (prev + 3, 32) to (start + 0, 48)
+- Code(Zero) at (prev + 0, 51) to (start + 0, 65)
+- Code(Zero) at (prev + 0, 75) to (start + 0, 90)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 5, 9) to (start + 3, 16)
+- Code(Zero) at (prev + 5, 13) to (start + 0, 27)
+- Code(Zero) at (prev + 2, 13) to (start + 0, 28)
+- Code(Counter(3)) at (prev + 4, 9) to (start + 2, 15)
+- Code(Counter(3)) at (prev + 6, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 9) to (start + 1, 15)
+- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15)
+- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 19)
+- Code(Expression(0, Sub)) at (prev + 5, 9) to (start + 0, 19)
+    = (c3 - c4)
+- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15)
+- Code(Counter(5)) at (prev + 1, 9) to (start + 0, 19)
+- Code(Zero) at (prev + 3, 13) to (start + 0, 29)
+- Code(Expression(1, Sub)) at (prev + 3, 9) to (start + 0, 19)
+    = (c3 - c5)
+- Code(Zero) at (prev + 3, 13) to (start + 0, 29)
+- Code(Counter(3)) at (prev + 3, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 19)
+- Code(Counter(6)) at (prev + 1, 13) to (start + 0, 19)
+- Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 19)
+    = (c3 - c6)
+- Code(Counter(7)) at (prev + 4, 5) to (start + 2, 19)
+- Code(Counter(8)) at (prev + 3, 13) to (start + 0, 19)
+- Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c7 - c8)
-- Code(Counter(8)) at (prev + 1, 5) to (start + 3, 15)
-- Code(Counter(9)) at (prev + 3, 32) to (start + 0, 48)
-- Code(Counter(10)) at (prev + 0, 51) to (start + 0, 65)
-- Code(Expression(1, Sub)) at (prev + 0, 75) to (start + 0, 90)
+- Code(Expression(9, Add)) at (prev + 3, 5) to (start + 0, 15)
+    = (c10 + c11)
+- Code(Counter(9)) at (prev + 1, 12) to (start + 0, 19)
+- Code(Counter(10)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Counter(10)) at (prev + 4, 13) to (start + 0, 19)
+- Code(Expression(7, Sub)) at (prev + 2, 13) to (start + 0, 23)
+    = (c9 - c10)
+- Code(Expression(7, Sub)) at (prev + 1, 20) to (start + 0, 27)
     = (c9 - c10)
-- Code(Expression(2, Sub)) at (prev + 1, 5) to (start + 0, 15)
-    = (c8 - c9)
-- Code(Counter(11)) at (prev + 5, 9) to (start + 3, 16)
-- Code(Counter(12)) at (prev + 5, 13) to (start + 0, 27)
-- Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 28)
-    = (c11 - c12)
-- Code(Expression(4, Sub)) at (prev + 4, 9) to (start + 5, 6)
-    = (c8 - (c9 + c11))
-- Code(Counter(13)) at (prev + 6, 5) to (start + 3, 6)
-- Code(Counter(14)) at (prev + 4, 5) to (start + 3, 6)
-- Code(Counter(15)) at (prev + 4, 9) to (start + 4, 6)
-- Code(Counter(16)) at (prev + 5, 8) to (start + 0, 15)
-- Code(Counter(17)) at (prev + 1, 9) to (start + 3, 10)
-- Code(Expression(6, Sub)) at (prev + 5, 9) to (start + 3, 10)
-    = (c16 - c17)
-- Code(Expression(12, Add)) at (prev + 5, 8) to (start + 0, 15)
-    = (c18 + c19)
-- Code(Counter(20)) at (prev + 1, 9) to (start + 0, 19)
-- Code(Expression(8, Sub)) at (prev + 3, 13) to (start + 0, 29)
-    = (c20 - c21)
-- Code(Expression(9, Sub)) at (prev + 3, 9) to (start + 0, 19)
-    = ((c18 + c19) - c20)
-- Code(Expression(11, Sub)) at (prev + 3, 13) to (start + 0, 29)
-    = ((c18 + c19) - (c20 + c22))
-- Code(Expression(17, Add)) at (prev + 3, 5) to (start + 0, 15)
-    = (c21 + c22)
-- Code(Expression(17, Add)) at (prev + 1, 12) to (start + 0, 19)
-    = (c21 + c22)
-- Code(Counter(23)) at (prev + 1, 13) to (start + 0, 19)
-- Code(Expression(16, Sub)) at (prev + 2, 13) to (start + 0, 19)
-    = ((c21 + c22) - c23)
-- Code(Counter(24)) at (prev + 4, 5) to (start + 2, 19)
-- Code(Counter(25)) at (prev + 3, 13) to (start + 0, 19)
-- Code(Expression(18, Sub)) at (prev + 2, 13) to (start + 0, 19)
-    = (c24 - c25)
-- Code(Expression(24, Add)) at (prev + 3, 5) to (start + 0, 15)
-    = (c28 + c29)
-- Code(Counter(26)) at (prev + 1, 12) to (start + 0, 19)
-- Code(Counter(27)) at (prev + 1, 13) to (start + 3, 14)
-- Code(Counter(28)) at (prev + 4, 13) to (start + 0, 19)
-- Code(Expression(22, Sub)) at (prev + 2, 13) to (start + 0, 23)
-    = (c26 - c27)
-- Code(Expression(22, Sub)) at (prev + 1, 20) to (start + 0, 27)
-    = (c26 - c27)
 - Code(Zero) at (prev + 1, 21) to (start + 0, 27)
-- Code(Expression(22, Sub)) at (prev + 2, 21) to (start + 0, 27)
-    = (c26 - c27)
-- Code(Counter(29)) at (prev + 4, 13) to (start + 0, 19)
-- Code(Expression(23, Sub)) at (prev + 3, 9) to (start + 0, 25)
-    = ((c28 + c29) - c30)
-- Code(Counter(30)) at (prev + 2, 5) to (start + 0, 15)
-- Code(Expression(25, Sub)) at (prev + 3, 9) to (start + 0, 34)
-    = (c30 - c31)
-- Code(Counter(31)) at (prev + 2, 5) to (start + 0, 15)
-- Code(Expression(26, Sub)) at (prev + 3, 9) to (start + 0, 44)
-    = (c31 - c32)
-- Code(Counter(32)) at (prev + 2, 1) to (start + 0, 2)
-Highest counter ID seen: c32
+- Code(Expression(7, Sub)) at (prev + 2, 21) to (start + 0, 27)
+    = (c9 - c10)
+- Code(Counter(11)) at (prev + 4, 13) to (start + 0, 19)
+- Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 25)
+    = ((c10 + c11) - c12)
+- Code(Counter(12)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Counter(12)) at (prev + 3, 9) to (start + 0, 34)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 3, 9) to (start + 0, 44)
+- Code(Zero) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c12
 
diff --git a/tests/coverage/issue-84561.coverage b/tests/coverage/issue-84561.coverage
index 2a642e2427b..a55f42a696e 100644
--- a/tests/coverage/issue-84561.coverage
+++ b/tests/coverage/issue-84561.coverage
@@ -47,32 +47,32 @@
    LL|      1|    let is_true = std::env::args().len() == 1;
    LL|      1|
    LL|      1|    assert_eq!(
-   LL|      1|        Foo(1),
-   LL|      1|        Foo(1)
-   LL|      1|    );
+   LL|       |        Foo(1),
+   LL|       |        Foo(1)
+   LL|       |    );
    LL|      1|    assert_ne!(
-   LL|      1|        Foo(0),
-   LL|      1|        Foo(1)
-   LL|      1|    );
+   LL|       |        Foo(0),
+   LL|       |        Foo(1)
+   LL|       |    );
    LL|      1|    assert_eq!(
-   LL|      1|        Foo(2),
-   LL|      1|        Foo(2)
-   LL|      1|    );
+   LL|       |        Foo(2),
+   LL|       |        Foo(2)
+   LL|       |    );
    LL|      1|    let bar = Foo(1);
    LL|      1|    assert_ne!(
-   LL|      1|        bar,
-   LL|      1|        Foo(3)
-   LL|      1|    );
+   LL|       |        bar,
+   LL|       |        Foo(3)
+   LL|       |    );
    LL|      1|    if is_true {
    LL|      1|        assert_ne!(
-   LL|      1|            Foo(0),
-   LL|      1|            Foo(4)
-   LL|      1|        );
+   LL|       |            Foo(0),
+   LL|       |            Foo(4)
+   LL|       |        );
    LL|       |    } else {
    LL|      0|        assert_eq!(
-   LL|      0|            Foo(3),
-   LL|      0|            Foo(3)
-   LL|      0|        );
+   LL|       |            Foo(3),
+   LL|       |            Foo(3)
+   LL|       |        );
    LL|       |    }
    LL|      1|    if is_true {
    LL|      1|        assert_ne!(
@@ -106,9 +106,9 @@
    LL|      1|    assert_ne!(
    LL|      1|        if is_true {
    LL|      1|            assert_eq!(
-   LL|      1|                Foo(3),
-   LL|      1|                Foo(3)
-   LL|      1|            );
+   LL|       |                Foo(3),
+   LL|       |                Foo(3)
+   LL|       |            );
    LL|      1|            Foo(0)
    LL|       |        } else {
    LL|      0|            assert_ne!(
diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map
index f13e82da151..fccc4d64395 100644
--- a/tests/coverage/loop-break.cov-map
+++ b/tests/coverage/loop-break.cov-map
@@ -1,12 +1,12 @@
 Function name: loop_break::main
-Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0b, 05, 02, 0c, 00, 27, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0b, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 11)
-- Code(Counter(1)) at (prev + 2, 12) to (start + 0, 39)
+- Code(Counter(1)) at (prev + 2, 12) to (start + 0, 33)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
     = (c1 - c0)
diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map
index 2cb0f948b3e..2157cd6ee3f 100644
--- a/tests/coverage/loops_branches.cov-map
+++ b/tests/coverage/loops_branches.cov-map
@@ -1,5 +1,5 @@
 Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 14, 01, 09, 05, 01, 10, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1e, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 22, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 14, 01, 09, 05, 01, 10, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -13,7 +13,7 @@ Number of file 0 mappings: 20
 - Code(Zero) at (prev + 1, 23) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 28) to (start + 0, 30)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29)
 - Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Zero) at (prev + 1, 16) to (start + 1, 10)
 - Code(Counter(3)) at (prev + 3, 13) to (start + 0, 14)
@@ -23,7 +23,7 @@ Number of file 0 mappings: 20
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
 - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
 - Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
     = ((c0 + c3) - (c1 + c2))
 - Code(Zero) at (prev + 1, 20) to (start + 1, 14)
@@ -33,7 +33,7 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c3
 
 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1e, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 22, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -48,7 +48,7 @@ Number of file 0 mappings: 20
 - Code(Zero) at (prev + 1, 23) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 28) to (start + 0, 30)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29)
 - Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14)
 - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 23)
@@ -58,7 +58,7 @@ Number of file 0 mappings: 20
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
 - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
 - Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
     = ((c0 + c2) - (c1 + c3))
 - Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15)
diff --git a/tests/coverage/macro_name_span.cov-map b/tests/coverage/macro_name_span.cov-map
index 58620452b2b..bd033faa551 100644
--- a/tests/coverage/macro_name_span.cov-map
+++ b/tests/coverage/macro_name_span.cov-map
@@ -1,10 +1,10 @@
 Function name: macro_name_span::affected_function
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 40]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 3e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 64)
+- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 62)
 Highest counter ID seen: c0
 
 Function name: macro_name_span::main
diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map
index 8ff5d6360f6..befe8866a59 100644
--- a/tests/coverage/mcdc/condition-limit.cov-map
+++ b/tests/coverage/mcdc/condition-limit.cov-map
@@ -1,5 +1,5 @@
 Function name: condition_limit::accept_7_conditions
-Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 07, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 06, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -12,7 +12,7 @@ Number of expressions: 8
 - expression 6 operands: lhs = Counter(6), rhs = Counter(7)
 - expression 7 operands: lhs = Counter(0), rhs = Counter(7)
 Number of file 0 mappings: 18
-- Code(Counter(0)) at (prev + 7, 1) to (start + 2, 9)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 9)
 - MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 2, 8) to (start + 0, 39)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 7, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
diff --git a/tests/coverage/mcdc/condition-limit.coverage b/tests/coverage/mcdc/condition-limit.coverage
index d11b8a17710..04ccd6497c3 100644
--- a/tests/coverage/mcdc/condition-limit.coverage
+++ b/tests/coverage/mcdc/condition-limit.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 19
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
    LL|       |
diff --git a/tests/coverage/mcdc/condition-limit.rs b/tests/coverage/mcdc/condition-limit.rs
index 2e8f1619379..867636cdaed 100644
--- a/tests/coverage/mcdc/condition-limit.rs
+++ b/tests/coverage/mcdc/condition-limit.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 19
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
 
diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map
index 771351f649f..1b038f48429 100644
--- a/tests/coverage/mcdc/if.cov-map
+++ b/tests/coverage/mcdc/if.cov-map
@@ -1,5 +1,5 @@
 Function name: if::mcdc_check_a
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -7,7 +7,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -23,7 +23,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_b
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 17, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 16, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -31,7 +31,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 23, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 22, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -47,7 +47,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_both
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -55,7 +55,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 31, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -71,7 +71,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_neither
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 07, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 06, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -79,7 +79,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -95,7 +95,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_not_tree_decision
-Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 31, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 30, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 7
@@ -107,7 +107,7 @@ Number of expressions: 7
 - expression 5 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(3)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 49, 1) to (start + 3, 10)
+- Code(Counter(0)) at (prev + 48, 1) to (start + 3, 10)
 - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 3 } at (prev + 0, 9) to (start + 0, 10)
     true  = c1
@@ -129,7 +129,7 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c3
 
 Function name: if::mcdc_check_tree_decision
-Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 27, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 26, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -142,7 +142,7 @@ Number of expressions: 8
 - expression 6 operands: lhs = Counter(0), rhs = Expression(7, Add)
 - expression 7 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 39, 1) to (start + 3, 9)
+- Code(Counter(0)) at (prev + 38, 1) to (start + 3, 9)
 - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -164,7 +164,7 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c3
 
 Function name: if::mcdc_nested_if
-Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3b, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3a, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 11
@@ -180,7 +180,7 @@ Number of expressions: 11
 - expression 9 operands: lhs = Counter(0), rhs = Expression(10, Add)
 - expression 10 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 59, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 58, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage
index b000c7d5d2f..51917d06045 100644
--- a/tests/coverage/mcdc/if.coverage
+++ b/tests/coverage/mcdc/if.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 19
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
    LL|       |
diff --git a/tests/coverage/mcdc/if.rs b/tests/coverage/mcdc/if.rs
index a2abb2edf11..c4675f5d167 100644
--- a/tests/coverage/mcdc/if.rs
+++ b/tests/coverage/mcdc/if.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 19
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
 
diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map
index 6a112b66e88..7d78e572a3b 100644
--- a/tests/coverage/mcdc/inlined_expressions.cov-map
+++ b/tests/coverage/mcdc/inlined_expressions.cov-map
@@ -1,12 +1,12 @@
 Function name: inlined_expressions::inlined_instance
-Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 08, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 07, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 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 = Counter(2)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 6)
+- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 6)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6)
     true  = c1
diff --git a/tests/coverage/mcdc/inlined_expressions.coverage b/tests/coverage/mcdc/inlined_expressions.coverage
index 57c655a2054..cfe398995e4 100644
--- a/tests/coverage/mcdc/inlined_expressions.coverage
+++ b/tests/coverage/mcdc/inlined_expressions.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 19
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
    LL|       |
diff --git a/tests/coverage/mcdc/inlined_expressions.rs b/tests/coverage/mcdc/inlined_expressions.rs
index 651e2fe8438..15d4260f6e2 100644
--- a/tests/coverage/mcdc/inlined_expressions.rs
+++ b/tests/coverage/mcdc/inlined_expressions.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 19
 //@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
 
diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map
index a231ac7b4c9..83d0739aaf5 100644
--- a/tests/coverage/mcdc/nested_if.cov-map
+++ b/tests/coverage/mcdc/nested_if.cov-map
@@ -1,5 +1,5 @@
 Function name: nested_if::doubly_nested_if_in_condition
-Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 14, 01, 0f, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 14, 01, 0e, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 15
@@ -19,7 +19,7 @@ Number of expressions: 15
 - expression 13 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 14 operands: lhs = Counter(0), rhs = Counter(4)
 Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -59,7 +59,7 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c6
 
 Function name: nested_if::nested_if_in_condition
-Raw bytes (118): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0e, 01, 07, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (118): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0e, 01, 06, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 10
@@ -74,7 +74,7 @@ Number of expressions: 10
 - expression 8 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 9 operands: lhs = Counter(0), rhs = Counter(4)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -103,7 +103,7 @@ Number of file 0 mappings: 14
 Highest counter ID seen: c4
 
 Function name: nested_if::nested_in_then_block_in_condition
-Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 14, 01, 22, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 14, 01, 21, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 15
@@ -123,7 +123,7 @@ Number of expressions: 15
 - expression 13 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 14 operands: lhs = Counter(0), rhs = Counter(6)
 Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 34, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -163,7 +163,7 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c6
 
 Function name: nested_if::nested_single_condition_decision
-Raw bytes (83): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0b, 01, 17, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (83): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0b, 01, 16, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
@@ -173,7 +173,7 @@ Number of expressions: 5
 - expression 3 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
 Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 23, 1) to (start + 4, 9)
+- Code(Counter(0)) at (prev + 22, 1) to (start + 4, 9)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage
index ca0cb54d581..c3ac30d22bf 100644
--- a/tests/coverage/mcdc/nested_if.coverage
+++ b/tests/coverage/mcdc/nested_if.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 19
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
    LL|       |
diff --git a/tests/coverage/mcdc/nested_if.rs b/tests/coverage/mcdc/nested_if.rs
index 83f188ea47e..db02aece33c 100644
--- a/tests/coverage/mcdc/nested_if.rs
+++ b/tests/coverage/mcdc/nested_if.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 19
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
 
diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map
index c282d53c5ac..48a103b2c7d 100644
--- a/tests/coverage/mcdc/non_control_flow.cov-map
+++ b/tests/coverage/mcdc/non_control_flow.cov-map
@@ -1,5 +1,5 @@
 Function name: non_control_flow::assign_3
-Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 16, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 15, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -8,7 +8,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 40)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
@@ -28,7 +28,7 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c3
 
 Function name: non_control_flow::assign_3_bis
-Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1b, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1a, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
@@ -38,7 +38,7 @@ Number of expressions: 5
 - expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
 - expression 4 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 44)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
@@ -58,14 +58,14 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c3
 
 Function name: non_control_flow::assign_and
-Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0c, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0b, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 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 = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 33)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
@@ -80,7 +80,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: non_control_flow::assign_or
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 11, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 10, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -88,7 +88,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 32)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
@@ -104,24 +104,26 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: non_control_flow::foo
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 02, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 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 + 37, 1) to (start + 2, 2)
+- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 2)
 Highest counter ID seen: c0
 
 Function name: non_control_flow::func_call
-Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 29, 01, 01, 0a, 28, 03, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
+Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 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 = Counter(2)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 10)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 9) to (start + 0, 15)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 9) to (start + 0, 15)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 9) to (start + 0, 10)
     true  = c1
     false = (c0 - c1)
@@ -133,7 +135,7 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c2
 
 Function name: non_control_flow::right_comb_tree
-Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 20, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02]
+Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 1f, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
@@ -143,7 +145,7 @@ Number of expressions: 5
 - expression 3 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 4 operands: lhs = Counter(4), rhs = Counter(5)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 32, 1) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 65)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 6, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42)
diff --git a/tests/coverage/mcdc/non_control_flow.coverage b/tests/coverage/mcdc/non_control_flow.coverage
index cead419fbdf..419d40bb6f9 100644
--- a/tests/coverage/mcdc/non_control_flow.coverage
+++ b/tests/coverage/mcdc/non_control_flow.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 19
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
    LL|       |
diff --git a/tests/coverage/mcdc/non_control_flow.rs b/tests/coverage/mcdc/non_control_flow.rs
index 6cfce6fae93..863bb8a5756 100644
--- a/tests/coverage/mcdc/non_control_flow.rs
+++ b/tests/coverage/mcdc/non_control_flow.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 19
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
 
diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map
index 04171fdb79b..244b0099544 100644
--- a/tests/coverage/no_cov_crate.cov-map
+++ b/tests/coverage/no_cov_crate.cov-map
@@ -35,22 +35,22 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: no_cov_crate::nested_fns::outer
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 33, 05, 02, 23, 01, 0c, 05, 00, 06]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 33, 05, 02, 22, 01, 0c, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 51, 5) to (start + 2, 35)
+- Code(Counter(0)) at (prev + 51, 5) to (start + 2, 34)
 - Code(Counter(0)) at (prev + 12, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: no_cov_crate::nested_fns::outer_both_covered
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 41, 05, 02, 17, 01, 0b, 05, 00, 06]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 41, 05, 02, 16, 01, 0b, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 65, 5) to (start + 2, 23)
+- Code(Counter(0)) at (prev + 65, 5) to (start + 2, 22)
 - Code(Counter(0)) at (prev + 11, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map
index 4628a24689e..18b13919fe5 100644
--- a/tests/coverage/panic_unwind.cov-map
+++ b/tests/coverage/panic_unwind.cov-map
@@ -26,14 +26,14 @@ Number of file 0 mappings: 9
 Highest counter ID seen: c3
 
 Function name: panic_unwind::might_panic
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 19, 02, 02, 0c, 03, 02]
+Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 4, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 25)
+- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15)
 - Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
     = (c0 - c1)
 Highest counter ID seen: c1
diff --git a/tests/coverage/sort_groups.cov-map b/tests/coverage/sort_groups.cov-map
index 69e13422296..898d68171c5 100644
--- a/tests/coverage/sort_groups.cov-map
+++ b/tests/coverage/sort_groups.cov-map
@@ -55,13 +55,13 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: sort_groups::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 06, 01, 04, 23, 05, 04, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 02, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 06, 01, 04, 1c, 05, 04, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 6, 1) to (start + 4, 35)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 4, 28)
 - Code(Counter(1)) at (prev + 4, 36) to (start + 2, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map
index 35b2c36a575..e45f3de1081 100644
--- a/tests/coverage/try_error_result.cov-map
+++ b/tests/coverage/try_error_result.cov-map
@@ -41,13 +41,13 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: try_error_result::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 71, 01, 02, 0c, 05, 03, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 71, 01, 02, 0a, 05, 03, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 113, 1) to (start + 2, 12)
+- Code(Counter(0)) at (prev + 113, 1) to (start + 2, 10)
 - Code(Counter(1)) at (prev + 3, 5) to (start + 0, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 11)
     = (c0 - c1)
@@ -55,7 +55,7 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: try_error_result::test1
-Raw bytes (67): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 02, 06, 0d, 00, 29, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 02, 06, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -67,13 +67,13 @@ Number of file 0 mappings: 11
 - Code(Counter(0)) at (prev + 13, 1) to (start + 2, 23)
 - Code(Counter(1)) at (prev + 7, 9) to (start + 0, 14)
 - Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
-- Code(Expression(0, Sub)) at (prev + 6, 13) to (start + 0, 41)
+- Code(Expression(0, Sub)) at (prev + 6, 13) to (start + 0, 17)
     = ((c0 + c2) - c1)
 - Code(Expression(0, Sub)) at (prev + 0, 41) to (start + 0, 42)
     = ((c0 + c2) - c1)
-- Code(Zero) at (prev + 1, 13) to (start + 0, 42)
+- Code(Zero) at (prev + 1, 13) to (start + 0, 17)
 - Code(Zero) at (prev + 0, 42) to (start + 0, 43)
-- Code(Expression(2, Sub)) at (prev + 4, 13) to (start + 0, 42)
+- Code(Expression(2, Sub)) at (prev + 4, 13) to (start + 0, 17)
     = (c1 - c0)
 - Code(Zero) at (prev + 0, 42) to (start + 0, 43)
 - Code(Expression(3, Sub)) at (prev + 3, 5) to (start + 0, 11)
@@ -82,7 +82,7 @@ Number of file 0 mappings: 11
 Highest counter ID seen: c2
 
 Function name: try_error_result::test2
-Raw bytes (336): 0x[01, 01, 36, 0d, 11, 0d, 3f, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 0d, 3f, 11, 15, 0d, 3b, 3f, 19, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 41, 53, 21, 25, 41, 21, 41, 53, 21, 25, 09, 73, 77, 2d, 0d, 29, 09, 0d, 09, 77, 0d, 29, 09, 73, 77, 2d, 0d, 29, 45, 8b, 01, 31, 35, 45, 31, 45, 8b, 01, 31, 35, 49, 9f, 01, 39, 3d, 49, 39, 49, 9f, 01, 39, 3d, 05, 09, ab, 01, 09, af, 01, 3d, b3, 01, 39, b7, 01, 35, bb, 01, 31, bf, 01, 2d, c3, 01, 29, c7, 01, 25, cb, 01, 21, cf, 01, 1d, d3, 01, 19, d7, 01, 15, 05, 11, 28, 01, 3d, 01, 03, 17, 05, 08, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 35, 15, 04, 11, 00, 12, 1e, 02, 11, 04, 12, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 41, 19, 00, 41, 00, 42, 26, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 20, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 41, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 60, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 20, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 42, 29, 00, 42, 00, 43, 66, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 20, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 20, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 36, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 20, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02]
+Raw bytes (336): 0x[01, 01, 36, 0d, 11, 0d, 3f, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 0d, 3f, 11, 15, 0d, 3b, 3f, 19, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 41, 53, 21, 25, 41, 21, 41, 53, 21, 25, 09, 73, 77, 2d, 0d, 29, 09, 0d, 09, 77, 0d, 29, 09, 73, 77, 2d, 0d, 29, 45, 8b, 01, 31, 35, 45, 31, 45, 8b, 01, 31, 35, 49, 9f, 01, 39, 3d, 49, 39, 49, 9f, 01, 39, 3d, 05, 09, ab, 01, 09, af, 01, 3d, b3, 01, 39, b7, 01, 35, bb, 01, 31, bf, 01, 2d, c3, 01, 29, c7, 01, 25, cb, 01, 21, cf, 01, 1d, d3, 01, 19, d7, 01, 15, 05, 11, 28, 01, 3d, 01, 03, 17, 05, 08, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 1c, 15, 04, 11, 00, 12, 1e, 02, 11, 03, 27, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 29, 19, 00, 41, 00, 42, 26, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 17, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 29, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 47, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 17, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 29, 29, 00, 42, 00, 43, 66, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 17, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 1d, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 17, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 1d, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 17, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 54
@@ -144,59 +144,59 @@ Number of file 0 mappings: 40
 - Code(Counter(0)) at (prev + 61, 1) to (start + 3, 23)
 - Code(Counter(1)) at (prev + 8, 9) to (start + 0, 14)
 - Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
-- Code(Counter(3)) at (prev + 6, 13) to (start + 0, 47)
+- Code(Counter(3)) at (prev + 6, 13) to (start + 0, 31)
 - Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 3, 53)
+- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 3, 28)
     = (c3 - c4)
 - Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18)
-- Code(Expression(7, Sub)) at (prev + 2, 17) to (start + 4, 18)
+- Code(Expression(7, Sub)) at (prev + 2, 17) to (start + 3, 39)
     = (c3 - (c4 + c5))
 - Code(Expression(12, Sub)) at (prev + 5, 17) to (start + 0, 20)
     = (c3 - (((c4 + c5) + c6) + c7))
-- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 65)
+- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 41)
     = (c3 - (c4 + c5))
 - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(9, Sub)) at (prev + 0, 67) to (start + 0, 95)
+- Code(Expression(9, Sub)) at (prev + 0, 67) to (start + 0, 71)
     = (c3 - ((c4 + c5) + c6))
 - Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96)
-- Code(Expression(12, Sub)) at (prev + 1, 13) to (start + 0, 32)
+- Code(Expression(12, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c3 - (((c4 + c5) + c6) + c7))
 - Code(Expression(19, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = (c16 - (c8 + c9))
-- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 65)
+- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 41)
 - Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 96)
+- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 71)
     = (c16 - c8)
 - Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97)
-- Code(Expression(19, Sub)) at (prev + 1, 13) to (start + 0, 32)
+- Code(Expression(19, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c16 - (c8 + c9))
 - Code(Expression(27, Sub)) at (prev + 4, 17) to (start + 0, 20)
     = (c2 - ((c3 + c10) + c11))
-- Code(Expression(24, Sub)) at (prev + 0, 23) to (start + 0, 66)
+- Code(Expression(24, Sub)) at (prev + 0, 23) to (start + 0, 41)
     = (c2 - c3)
 - Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67)
-- Code(Expression(25, Sub)) at (prev + 0, 68) to (start + 0, 97)
+- Code(Expression(25, Sub)) at (prev + 0, 68) to (start + 0, 72)
     = (c2 - (c3 + c10))
 - Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98)
-- Code(Expression(27, Sub)) at (prev + 1, 13) to (start + 0, 32)
+- Code(Expression(27, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c2 - ((c3 + c10) + c11))
 - Code(Expression(33, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = (c17 - (c12 + c13))
-- Code(Counter(17)) at (prev + 0, 23) to (start + 1, 54)
+- Code(Counter(17)) at (prev + 0, 23) to (start + 1, 29)
 - Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55)
-- Code(Expression(32, Sub)) at (prev + 1, 18) to (start + 0, 47)
+- Code(Expression(32, Sub)) at (prev + 1, 18) to (start + 0, 22)
     = (c17 - c12)
 - Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 32)
+- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c17 - (c12 + c13))
 - Code(Expression(38, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = (c18 - (c14 + c15))
-- Code(Counter(18)) at (prev + 0, 23) to (start + 1, 54)
+- Code(Counter(18)) at (prev + 0, 23) to (start + 1, 29)
 - Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18)
-- Code(Expression(37, Sub)) at (prev + 1, 18) to (start + 0, 47)
+- Code(Expression(37, Sub)) at (prev + 1, 18) to (start + 0, 22)
     = (c18 - c14)
 - Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 32)
+- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 23)
     = (c18 - (c14 + c15))
 - Code(Expression(40, Sub)) at (prev + 3, 5) to (start + 0, 11)
     = (c1 - c2)
diff --git a/tests/coverage/try_error_result.coverage b/tests/coverage/try_error_result.coverage
index 7100248f7df..7a89c0452ac 100644
--- a/tests/coverage/try_error_result.coverage
+++ b/tests/coverage/try_error_result.coverage
@@ -86,7 +86,7 @@
    LL|      1|                .
    LL|      1|                expect_err(
    LL|      1|                    "call should fail"
-   LL|      1|                );
+   LL|       |                );
    LL|      1|            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
                               ^0                                                ^0                          ^0
    LL|      0|            assert_eq!(val, 57);
diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map
index 7b9dc0b9bc8..29d40a05513 100644
--- a/tests/coverage/unicode.cov-map
+++ b/tests/coverage/unicode.cov-map
@@ -1,5 +1,5 @@
 Function name: unicode::main
-Raw bytes (53): 0x[01, 01, 02, 05, 01, 01, 0d, 09, 01, 0e, 01, 00, 0b, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 25, 09, 00, 29, 00, 46, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02]
+Raw bytes (53): 0x[01, 01, 02, 05, 01, 01, 0d, 09, 01, 0e, 01, 00, 0b, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
@@ -12,8 +12,8 @@ Number of file 0 mappings: 9
 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 27)
 - Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 40)
     = (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 37)
-- Code(Counter(2)) at (prev + 0, 41) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 35)
+- Code(Counter(2)) at (prev + 0, 41) to (start + 0, 68)
 - Code(Counter(3)) at (prev + 0, 71) to (start + 2, 6)
 - Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c3)
diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage
index 84c5f05a8c4..44349954550 100644
--- a/tests/coverage/unicode.coverage
+++ b/tests/coverage/unicode.coverage
@@ -15,7 +15,7 @@
    LL|     33|    for _İ in 'А'..='Я' { /* Я */ }
                       ^32                ^32
    LL|       |
-   LL|      1|    if 申し訳ございません() && 申し訳ございません() {
+   LL|      1|    if 申し訳ございません() && 申し訳ございません() {
                                                       ^0
    LL|      0|        println!("true");
    LL|      1|    }
diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map
index 97961bc7414..0bc18bfcbd3 100644
--- a/tests/coverage/unreachable.cov-map
+++ b/tests/coverage/unreachable.cov-map
@@ -1,27 +1,27 @@
 Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 27, 00, 47]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 27, 00, 45]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 14, 39) to (start + 0, 71)
+- Code(Zero) at (prev + 14, 39) to (start + 0, 69)
 Highest counter ID seen: (none)
 
 Function name: unreachable::unreachable_function (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 01, 01, 25]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 01, 01, 23]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 16, 1) to (start + 1, 37)
+- Code(Zero) at (prev + 16, 1) to (start + 1, 35)
 Highest counter ID seen: (none)
 
 Function name: unreachable::unreachable_intrinsic (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 2c]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 2a]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 1) to (start + 1, 44)
+- Code(Zero) at (prev + 21, 1) to (start + 1, 42)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map
index d296f9bd778..bf0916e5503 100644
--- a/tests/coverage/yield.cov-map
+++ b/tests/coverage/yield.cov-map
@@ -1,5 +1,5 @@
 Function name: yield::main
-Raw bytes (94): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 34, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 34, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 2e, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 34, 11, 02, 0b, 00, 2e, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 34, 12, 02, 01, 00, 02]
+Raw bytes (94): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 2e, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 2e, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
@@ -12,22 +12,22 @@ Number of file 0 mappings: 16
 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 22)
 - Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46)
 - Code(Counter(1)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
 - Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
 - Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
-- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c1 - c2)
 - Code(Counter(2)) at (prev + 3, 9) to (start + 0, 22)
 - Code(Counter(2)) at (prev + 8, 11) to (start + 0, 46)
 - Code(Counter(4)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(2, Sub)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(2, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c2 - c4)
 - Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46)
 - Code(Expression(4, Sub)) at (prev + 1, 39) to (start + 0, 41)
     = (c4 - c5)
-- Code(Counter(5)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Counter(5)) at (prev + 1, 14) to (start + 0, 20)
 - Code(Expression(4, Sub)) at (prev + 2, 1) to (start + 0, 2)
     = (c4 - c5)
 Highest counter ID seen: c5
diff --git a/tests/crashes/112201.rs b/tests/crashes/112201.rs
deleted file mode 100644
index 5d363403b8a..00000000000
--- a/tests/crashes/112201.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//@ known-bug: #112201
-
-pub fn compose(
-    f1: impl FnOnce(f64) -> f64 + Clone,
-    f2: impl FnOnce(f64) -> f64 + Clone,
-) -> impl FnOnce(f64) -> f64 + Clone {
-    move |x| f1(f2(x))
-}
-
-fn repeat_helper(
-    f: impl FnOnce(f64) -> f64 + Clone,
-    res: impl FnOnce(f64) -> f64 + Clone,
-    times: usize,
-) -> impl FnOnce(f64) -> f64 + Clone {
-    return res;
-    repeat_helper(f.clone(), compose(f, res), times - 1)
-}
-
-fn main() {}
diff --git a/tests/crashes/134334.rs b/tests/crashes/134334.rs
deleted file mode 100644
index d99df7bdc1e..00000000000
--- a/tests/crashes/134334.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #134334
-//@ only-x86_64
-
-#[repr(simd)]
-struct A();
-
-fn main() {
-    std::arch::asm!("{}", in(xmm_reg) A());
-}
diff --git a/tests/crashes/134335.rs b/tests/crashes/134335.rs
deleted file mode 100644
index bee6686ff3f..00000000000
--- a/tests/crashes/134335.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #134335
-//@compile-flags: -Zunstable-options --edition=2024 --crate-type=lib
-pub async fn async_closure(x: &mut i32) {
-    let c = async move || {
-        *x += 1;
-    };
-    call_once(c).await;
-}
-
-fn call_once<T>(f: impl FnOnce() -> T) -> T {
-    f()
-}
diff --git a/tests/crashes/137751.rs b/tests/crashes/137751.rs
deleted file mode 100644
index 85ae3acd53d..00000000000
--- a/tests/crashes/137751.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ known-bug: #137751
-//@ compile-flags: --edition=2021 -Znext-solver=globally
-async fn test() {
-    Box::pin(test()).await;
-}
-fn main() {}
diff --git a/tests/crashes/137874.rs b/tests/crashes/137874.rs
deleted file mode 100644
index 44718809024..00000000000
--- a/tests/crashes/137874.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #137874
-fn a() {
-    match b { deref !(0c) };
-}
diff --git a/tests/incremental/delayed_span_bug.rs b/tests/incremental/delayed_span_bug.rs
index 958e9dd07e2..1534aca5ddd 100644
--- a/tests/incremental/delayed_span_bug.rs
+++ b/tests/incremental/delayed_span_bug.rs
@@ -1,8 +1,8 @@
 //@ revisions: cfail1 cfail2
 //@ should-ice
-//@ error-pattern: delayed bug triggered by #[rustc_error(delayed_bug_from_inside_query)]
+//@ error-pattern: delayed bug triggered by #[rustc_delayed_bug_from_inside_query]
 
 #![feature(rustc_attrs)]
 
-#[rustc_error(delayed_bug_from_inside_query)]
+#[rustc_delayed_bug_from_inside_query]
 fn main() {}
diff --git a/tests/incremental/user-written-closure-synthetic-closure-conflict.rs b/tests/incremental/user-written-closure-synthetic-closure-conflict.rs
new file mode 100644
index 00000000000..618604d06b1
--- /dev/null
+++ b/tests/incremental/user-written-closure-synthetic-closure-conflict.rs
@@ -0,0 +1,15 @@
+//@ revisions: rpass1 rpass2
+//@ edition: 2024
+
+#![allow(unused)]
+
+fn main() {
+    #[cfg(rpass1)]
+    async || {};
+
+    #[cfg(rpass2)]
+    || {
+        || ();
+        || ();
+    };
+}
diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir
index bd0baddb1f8..9070c95bca4 100644
--- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir
+++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir
@@ -1,6 +1,6 @@
-// MIR for `foo::{closure#0}::{closure#1}` after built
+// MIR for `foo::{closure#0}::{synthetic#0}` after built
 
-fn foo::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> ()
+fn foo::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.rs b/tests/mir-opt/async_closure_fake_read_for_by_move.rs
index 3c5aec94bbf..e78671f5e9d 100644
--- a/tests/mir-opt/async_closure_fake_read_for_by_move.rs
+++ b/tests/mir-opt/async_closure_fake_read_for_by_move.rs
@@ -7,7 +7,7 @@ enum Foo {
 }
 
 // EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir
-// EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir
+// EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir
 fn foo(f: &Foo) {
     let x = async move || match f {
         Foo::Bar if true => {}
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir
index a9e08d2e8f6..c5f538e5ecd 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir
@@ -1,6 +1,6 @@
-// MIR for `main::{closure#0}::{closure#0}::{closure#1}` after built
+// MIR for `main::{closure#0}::{closure#0}::{synthetic#0}` after built
 
-fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir
index 4452ae7812e..e295f9b3cf1 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir
@@ -1,6 +1,6 @@
-// MIR for `main::{closure#0}::{closure#1}::{closure#1}` after built
+// MIR for `main::{closure#0}::{closure#1}::{synthetic#0}` after built
 
-fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#1}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs
index cd2e83e939a..93cc7834a64 100644
--- a/tests/mir-opt/async_closure_shims.rs
+++ b/tests/mir-opt/async_closure_shims.rs
@@ -42,11 +42,11 @@ async fn call_normal_mut<F: Future<Output = ()>>(f: &mut impl FnMut(i32) -> F) {
 
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir
-// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
+// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir
-// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
+// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir
 pub fn main() {
     block_on(async {
         let b = 2i32;
diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff
index 886f9a68dd9..417406de39b 100644
--- a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff
@@ -8,8 +8,9 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = const <bool as NeedsDrop>::NEEDS;
+-         _1 = const <bool as NeedsDrop>::NEEDS;
 -         switchInt(move _1) -> [0: bb2, otherwise: bb1];
++         _1 = const false;
 +         switchInt(const false) -> [0: bb2, otherwise: bb1];
       }
   
diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff
index cc53b213397..63ba2c6865f 100644
--- a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff
@@ -8,8 +8,9 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = const <bool as NeedsDrop>::NEEDS;
+-         _1 = const <bool as NeedsDrop>::NEEDS;
 -         switchInt(move _1) -> [0: bb2, otherwise: bb1];
++         _1 = const false;
 +         switchInt(const false) -> [0: bb2, otherwise: bb1];
       }
   
diff --git a/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff b/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff
index 23928337bf7..8df262b351f 100644
--- a/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff
+++ b/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff
@@ -14,19 +14,23 @@
   
       bb0: {
           StorageLive(_1);
-          StorageLive(_2);
+-         StorageLive(_2);
 -         StorageLive(_3);
 +         nop;
++         nop;
           _3 = const {ALLOC0: &u8};
-          _2 = copy (*_3);
+-         _2 = copy (*_3);
++         _2 = const 2_u8;
           StorageLive(_4);
           StorageLive(_5);
           _5 = const {ALLOC0: &u8};
 -         _4 = copy (*_5);
-+         _4 = copy (*_3);
-          _1 = Add(move _2, move _4);
+-         _1 = Add(move _2, move _4);
++         _4 = const 2_u8;
++         _1 = const 4_u8;
           StorageDead(_4);
-          StorageDead(_2);
+-         StorageDead(_2);
++         nop;
           StorageDead(_5);
 -         StorageDead(_3);
 +         nop;
diff --git a/tests/mir-opt/const_prop/read_immutable_static.rs b/tests/mir-opt/const_prop/read_immutable_static.rs
index 98ba76fb765..05fec2f3303 100644
--- a/tests/mir-opt/const_prop/read_immutable_static.rs
+++ b/tests/mir-opt/const_prop/read_immutable_static.rs
@@ -6,7 +6,6 @@ static FOO: u8 = 2;
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: debug x => [[x:_.*]];
-    // Disabled due to <https://github.com/rust-lang/rust/issues/130853>
-    // COM: CHECK: [[x]] = const 4_u8;
+    // CHECK: [[x]] = const 4_u8;
     let x = FOO + FOO;
 }
diff --git a/tests/mir-opt/const_prop/ref_deref.main.GVN.diff b/tests/mir-opt/const_prop/ref_deref.main.GVN.diff
index 4477b4b005b..b9e269266b0 100644
--- a/tests/mir-opt/const_prop/ref_deref.main.GVN.diff
+++ b/tests/mir-opt/const_prop/ref_deref.main.GVN.diff
@@ -16,7 +16,8 @@
           StorageLive(_2);
           _4 = const main::promoted[0];
           _2 = &(*_4);
-          _1 = copy (*_2);
+-         _1 = copy (*_2);
++         _1 = const 4_i32;
           StorageDead(_2);
           _0 = const ();
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff b/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff
index bbfd70bea16..dcc13c9251c 100644
--- a/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff
+++ b/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff
@@ -16,7 +16,8 @@
           StorageLive(_2);
           _4 = const main::promoted[0];
           _2 = &((*_4).1: i32);
-          _1 = copy (*_2);
+-         _1 = copy (*_2);
++         _1 = const 5_i32;
           StorageDead(_2);
           _0 = const ();
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/ref_deref_project.rs b/tests/mir-opt/const_prop/ref_deref_project.rs
index 31108e1a57f..5a48a887f93 100644
--- a/tests/mir-opt/const_prop/ref_deref_project.rs
+++ b/tests/mir-opt/const_prop/ref_deref_project.rs
@@ -5,7 +5,6 @@
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: debug a => [[a:_.*]];
-    // Disabled due to <https://github.com/rust-lang/rust/issues/130853>
-    // COM: CHECK: [[a]] = const 5_i32;
+    // CHECK: [[a]] = const 5_i32;
     let a = *(&(4, 5).1);
 }
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
index 0798b303929..d6e81debccd 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
@@ -40,7 +40,7 @@
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
++         _1 = const 2_u32;
           StorageDead(_6);
           StorageDead(_4);
           StorageDead(_2);
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
index c0b3d4d3219..6713e531892 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
@@ -40,7 +40,7 @@
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
++         _1 = const 2_u32;
           StorageDead(_6);
           StorageDead(_4);
           StorageDead(_2);
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
index 0798b303929..d6e81debccd 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
@@ -40,7 +40,7 @@
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
++         _1 = const 2_u32;
           StorageDead(_6);
           StorageDead(_4);
           StorageDead(_2);
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
index c0b3d4d3219..6713e531892 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
@@ -40,7 +40,7 @@
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
++         _1 = const 2_u32;
           StorageDead(_6);
           StorageDead(_4);
           StorageDead(_2);
diff --git a/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs
index 498e09fbb65..ebd3c9e792d 100644
--- a/tests/mir-opt/const_prop/slice_len.rs
+++ b/tests/mir-opt/const_prop/slice_len.rs
@@ -8,8 +8,7 @@ fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: debug a => [[a:_.*]];
     // CHECK: [[slice:_.*]] = copy {{.*}} as &[u32] (PointerCoercion(Unsize, AsCast));
-    // Disabled due to <https://github.com/rust-lang/rust/issues/130853>
-    // COM: CHECK: assert(const true,
-    // COM: CHECK: [[a]] = const 2_u32;
+    // CHECK: assert(const true,
+    // CHECK: [[a]] = const 2_u32;
     let a = (&[1u32, 2, 3] as &[u32])[1];
 }
diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
index febb6bfb0a4..2ac9769a0e7 100644
--- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
@@ -10,8 +10,9 @@
           StorageLive(_1);
           StorageLive(_2);
 -         _2 = ();
+-         _1 = Union32 { value: move _2 };
 +         _2 = const ();
-          _1 = Union32 { value: move _2 };
++         _1 = Union32 { value: const () };
           StorageDead(_2);
           _0 = move _1 as u32 (Transmute);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
index febb6bfb0a4..2ac9769a0e7 100644
--- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
@@ -10,8 +10,9 @@
           StorageLive(_1);
           StorageLive(_2);
 -         _2 = ();
+-         _1 = Union32 { value: move _2 };
 +         _2 = const ();
-          _1 = Union32 { value: move _2 };
++         _1 = Union32 { value: const () };
           StorageDead(_2);
           _0 = move _1 as u32 (Transmute);
           StorageDead(_1);
diff --git a/tests/mir-opt/coroutine_drop_cleanup.rs b/tests/mir-opt/coroutine_drop_cleanup.rs
index 33fdd2dd0d9..4ae97273cd9 100644
--- a/tests/mir-opt/coroutine_drop_cleanup.rs
+++ b/tests/mir-opt/coroutine_drop_cleanup.rs
@@ -8,7 +8,7 @@
 
 // EMIT_MIR coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.mir
 fn main() {
-    let gen = #[coroutine]
+    let gen_ = #[coroutine]
     || {
         let _s = String::new();
         yield;
diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
index 8e1cdb7182b..542b70bcee9 100644
--- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
@@ -27,10 +27,10 @@
       }
   
 +     coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 15:21 (#0);
-+     coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:33 (#0);
-+     coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:33 (#0);
-+     coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:33 (#0);
-+     coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:33 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:32 (#0);
++     coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:32 (#0);
++     coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:32 (#0);
++     coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:32 (#0);
 +     coverage Code { bcb: bcb2 } => $DIR/branch_match_arms.rs:21:2: 21:2 (#0);
 + 
       bb0: {
diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index 1a71cb8dea7..30de92f3b86 100644
--- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
@@ -8,7 +8,7 @@
       let mut _3: !;
   
 +     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:11 (#0);
-+     coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:15:12: 15:17 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:15:12: 15:15 (#0);
 +     coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:16:13: 16:18 (#0);
 +     coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:17:10: 17:10 (#0);
 +     coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:19:2: 19:2 (#0);
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
index 557320f0179..ef418798faa 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
@@ -5,11 +5,10 @@
       let mut _0: ();
       let _1: main::Un;
       let mut _2: u32;
-      let mut _3: u32;
       scope 1 {
           debug un => _1;
           scope 3 (inlined std::mem::drop::<u32>) {
-              debug _x => _3;
+              debug _x => _2;
           }
       }
       scope 2 (inlined val) {
@@ -17,13 +16,10 @@
   
       bb0: {
           StorageLive(_1);
-          StorageLive(_2);
-          nop;
           _1 = Un { us: const 1_u32 };
+          StorageLive(_2);
+          _2 = copy (_1.0: u32);
           StorageDead(_2);
-          StorageLive(_3);
-          _3 = copy (_1.0: u32);
-          StorageDead(_3);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
index 557320f0179..ef418798faa 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
@@ -5,11 +5,10 @@
       let mut _0: ();
       let _1: main::Un;
       let mut _2: u32;
-      let mut _3: u32;
       scope 1 {
           debug un => _1;
           scope 3 (inlined std::mem::drop::<u32>) {
-              debug _x => _3;
+              debug _x => _2;
           }
       }
       scope 2 (inlined val) {
@@ -17,13 +16,10 @@
   
       bb0: {
           StorageLive(_1);
-          StorageLive(_2);
-          nop;
           _1 = Un { us: const 1_u32 };
+          StorageLive(_2);
+          _2 = copy (_1.0: u32);
           StorageDead(_2);
-          StorageLive(_3);
-          _3 = copy (_1.0: u32);
-          StorageDead(_3);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff b/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff
index acbea13642c..b0702696e18 100644
--- a/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff
@@ -18,7 +18,8 @@
       }
   
       bb2: {
-          _0 = opaque::<T>(copy (*_3)) -> [return: bb3, unwind unreachable];
+-         _0 = opaque::<T>(copy (*_3)) -> [return: bb3, unwind unreachable];
++         _0 = opaque::<T>(copy _1) -> [return: bb3, unwind unreachable];
       }
   
       bb3: {
diff --git a/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff b/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff
index ba080bfdb07..fe05d4deeed 100644
--- a/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff
@@ -18,7 +18,8 @@
       }
   
       bb2: {
-          _0 = opaque::<T>(copy (*_3)) -> [return: bb3, unwind continue];
+-         _0 = opaque::<T>(copy (*_3)) -> [return: bb3, unwind continue];
++         _0 = opaque::<T>(copy _1) -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff
index 7f99b83d937..3cce35d34e9 100644
--- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff
@@ -8,10 +8,10 @@
       let mut _3: fn(u8) -> u8;
       let _5: ();
       let mut _6: fn(u8) -> u8;
-      let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21};
+      let mut _9: {closure@$DIR/gvn.rs:620:19: 620:21};
       let _10: ();
       let mut _11: fn();
-      let mut _13: {closure@$DIR/gvn.rs:615:19: 615:21};
+      let mut _13: {closure@$DIR/gvn.rs:620:19: 620:21};
       let _14: ();
       let mut _15: fn();
       scope 1 {
@@ -19,7 +19,7 @@
           let _4: fn(u8) -> u8;
           scope 2 {
               debug g => _4;
-              let _7: {closure@$DIR/gvn.rs:615:19: 615:21};
+              let _7: {closure@$DIR/gvn.rs:620:19: 620:21};
               scope 3 {
                   debug closure => _7;
                   let _8: fn();
@@ -62,16 +62,16 @@
           StorageDead(_6);
           StorageDead(_5);
 -         StorageLive(_7);
--         _7 = {closure@$DIR/gvn.rs:615:19: 615:21};
+-         _7 = {closure@$DIR/gvn.rs:620:19: 620:21};
 -         StorageLive(_8);
 +         nop;
-+         _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
++         _7 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21};
 +         nop;
           StorageLive(_9);
 -         _9 = copy _7;
 -         _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
-+         _9 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
-+         _8 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
++         _9 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21};
++         _8 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
           StorageDead(_9);
           StorageLive(_10);
           StorageLive(_11);
@@ -88,8 +88,8 @@
           StorageLive(_13);
 -         _13 = copy _7;
 -         _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
-+         _13 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
-+         _12 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
++         _13 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21};
++         _12 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
           StorageDead(_13);
           StorageLive(_14);
           StorageLive(_15);
diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff
index 06dd0502f30..d85aca040fe 100644
--- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff
@@ -8,10 +8,10 @@
       let mut _3: fn(u8) -> u8;
       let _5: ();
       let mut _6: fn(u8) -> u8;
-      let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21};
+      let mut _9: {closure@$DIR/gvn.rs:620:19: 620:21};
       let _10: ();
       let mut _11: fn();
-      let mut _13: {closure@$DIR/gvn.rs:615:19: 615:21};
+      let mut _13: {closure@$DIR/gvn.rs:620:19: 620:21};
       let _14: ();
       let mut _15: fn();
       scope 1 {
@@ -19,7 +19,7 @@
           let _4: fn(u8) -> u8;
           scope 2 {
               debug g => _4;
-              let _7: {closure@$DIR/gvn.rs:615:19: 615:21};
+              let _7: {closure@$DIR/gvn.rs:620:19: 620:21};
               scope 3 {
                   debug closure => _7;
                   let _8: fn();
@@ -62,16 +62,16 @@
           StorageDead(_6);
           StorageDead(_5);
 -         StorageLive(_7);
--         _7 = {closure@$DIR/gvn.rs:615:19: 615:21};
+-         _7 = {closure@$DIR/gvn.rs:620:19: 620:21};
 -         StorageLive(_8);
 +         nop;
-+         _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
++         _7 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21};
 +         nop;
           StorageLive(_9);
 -         _9 = copy _7;
 -         _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
-+         _9 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
-+         _8 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
++         _9 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21};
++         _8 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
           StorageDead(_9);
           StorageLive(_10);
           StorageLive(_11);
@@ -88,8 +88,8 @@
           StorageLive(_13);
 -         _13 = copy _7;
 -         _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
-+         _13 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
-+         _12 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
++         _13 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21};
++         _12 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
           StorageDead(_13);
           StorageLive(_14);
           StorageLive(_15);
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index c895a579259..6ef320c90de 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -100,17 +100,18 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
     opaque((x * y) - y);
 
     // We cannot substitute through an immutable reference.
-    // (Disabled due to <https://github.com/rust-lang/rust/issues/130853>)
     // CHECK: [[ref:_.*]] = &_3;
     // CHECK: [[deref:_.*]] = copy (*[[ref]]);
-    // COM: CHECK: [[addref:_.*]] = Add(copy [[deref]], copy _1);
-    // COM: CHECK: opaque::<u64>(copy [[addref]])
-    // COM: CHECK: opaque::<u64>(copy [[addref]])
+    // CHECK: [[addref:_.*]] = Add(move [[deref]], copy _1);
+    // CHECK: opaque::<u64>(move [[addref]])
+    // CHECK: [[deref2:_.*]] = copy (*[[ref]]);
+    // CHECK: [[addref2:_.*]] = Add(move [[deref2]], copy _1);
+    // CHECK: opaque::<u64>(move [[addref2]])
     let a = &z;
     opaque(*a + x);
     opaque(*a + x);
 
-    // And certainly not through a mutable reference or a pointer.
+    // But not through a mutable reference or a pointer.
     // CHECK: [[mut:_.*]] = &mut _3;
     // CHECK: [[addmut:_.*]] = Add(
     // CHECK: opaque::<u64>(move [[addmut]])
@@ -142,9 +143,11 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
     // Important: `e` is not `a`!
     // CHECK: [[ref2:_.*]] = &_3;
     // CHECK: [[deref2:_.*]] = copy (*[[ref2]]);
-    // COM: CHECK: [[addref2:_.*]] = Add(copy [[deref2]], copy _1);
-    // COM: CHECK: opaque::<u64>(copy [[addref2]])
-    // COM: CHECK: opaque::<u64>(copy [[addref2]])
+    // CHECK: [[addref2:_.*]] = Add(move [[deref2]], copy _1);
+    // CHECK: opaque::<u64>(move [[addref2]])
+    // CHECK: [[deref3:_.*]] = copy (*[[ref2]]);
+    // CHECK: [[addref3:_.*]] = Add(move [[deref3]], copy _1);
+    // CHECK: opaque::<u64>(move [[addref3]])
     let e = &z;
     opaque(*e + x);
     opaque(*e + x);
@@ -499,8 +502,9 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S<u32>) {
     // Do not reuse dereferences of `&Freeze`.
     // CHECK: [[ref:_.*]] = &(*_1);
     // CHECK: [[st7:_.*]] = copy (*[[ref]]);
-    // COM: CHECK: opaque::<u32>(copy [[st7]])
-    // COM: CHECK: opaque::<u32>(copy [[st7]])
+    // CHECK: opaque::<u32>(move [[st7]])
+    // CHECK: [[st8:_.*]] = copy (*[[ref]]);
+    // CHECK: opaque::<u32>(move [[st8]])
     let z = &*t;
     opaque(*z);
     opaque(*z);
@@ -519,8 +523,9 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S<u32>) {
 
     // `*s` is not Copy, but `(*s).0` is, but we still cannot reuse.
     // CHECK: [[st10:_.*]] = copy ((*_3).0: u32);
-    // COM: CHECK: opaque::<u32>(copy [[st10]])
-    // COM: CHECK: opaque::<u32>(copy [[st10]])
+    // CHECK: opaque::<u32>(move [[st10]])
+    // CHECK: [[st11:_.*]] = copy ((*_3).0: u32);
+    // CHECK: opaque::<u32>(move [[st11]])
     opaque(s.0);
     opaque(s.0);
 }
@@ -737,7 +742,7 @@ fn borrowed<T: Copy + Freeze>(x: T) {
     // CHECK: bb1: {
     // CHECK-NEXT: _0 = opaque::<T>(copy _1)
     // CHECK: bb2: {
-    // COM: CHECK-NEXT: _0 = opaque::<T>(copy _1)
+    // CHECK-NEXT: _0 = opaque::<T>(copy _1)
     mir! {
         {
             let a = x;
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
index 43efcbdfb1e..e8e99b44e72 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
@@ -111,8 +111,9 @@
           StorageLive(_7);
           StorageLive(_8);
 -         StorageLive(_9);
+-         StorageLive(_10);
++         nop;
 +         nop;
-          StorageLive(_10);
           StorageLive(_11);
           _11 = &(*_1);
           _10 = core::str::<impl str>::as_ptr(move _11) -> [return: bb3, unwind unreachable];
@@ -122,8 +123,9 @@
           StorageDead(_11);
           _9 = &_10;
 -         StorageLive(_12);
+-         StorageLive(_13);
++         nop;
 +         nop;
-          StorageLive(_13);
           StorageLive(_14);
 -         _14 = &(*_4);
 +         _14 = &(*_1);
@@ -148,11 +150,12 @@
           StorageLive(_17);
           StorageLive(_18);
 -         _18 = copy (*_15);
-+         _18 = copy (*_9);
++         _18 = copy _10;
           StorageLive(_19);
 -         _19 = copy (*_16);
-+         _19 = copy (*_12);
-          _17 = Eq(move _18, move _19);
+-         _17 = Eq(move _18, move _19);
++         _19 = copy _13;
++         _17 = Eq(copy _10, copy _13);
           switchInt(move _17) -> [0: bb6, otherwise: bb5];
       }
   
@@ -163,8 +166,10 @@
           StorageDead(_17);
           StorageDead(_16);
           StorageDead(_15);
-          StorageDead(_13);
-          StorageDead(_10);
+-         StorageDead(_13);
+-         StorageDead(_10);
++         nop;
++         nop;
           StorageDead(_8);
           StorageDead(_7);
 -         StorageLive(_29);
@@ -213,8 +218,9 @@
           StorageLive(_33);
           StorageLive(_34);
 -         StorageLive(_35);
+-         StorageLive(_36);
++         nop;
 +         nop;
-          StorageLive(_36);
           StorageLive(_37);
           _37 = &(*_1);
           _36 = core::str::<impl str>::as_ptr(move _37) -> [return: bb8, unwind unreachable];
@@ -224,8 +230,9 @@
           StorageDead(_37);
           _35 = &_36;
 -         StorageLive(_38);
+-         StorageLive(_39);
++         nop;
 +         nop;
-          StorageLive(_39);
           StorageLive(_40);
           _40 = &(*_29);
           _39 = core::slice::<impl [u8]>::as_ptr(move _40) -> [return: bb9, unwind unreachable];
@@ -249,11 +256,12 @@
           StorageLive(_43);
           StorageLive(_44);
 -         _44 = copy (*_41);
-+         _44 = copy (*_35);
++         _44 = copy _36;
           StorageLive(_45);
 -         _45 = copy (*_42);
-+         _45 = copy (*_38);
-          _43 = Eq(move _44, move _45);
+-         _43 = Eq(move _44, move _45);
++         _45 = copy _39;
++         _43 = Eq(copy _36, copy _39);
           switchInt(move _43) -> [0: bb11, otherwise: bb10];
       }
   
@@ -264,8 +272,10 @@
           StorageDead(_43);
           StorageDead(_42);
           StorageDead(_41);
-          StorageDead(_39);
-          StorageDead(_36);
+-         StorageDead(_39);
+-         StorageDead(_36);
++         nop;
++         nop;
           StorageDead(_34);
           StorageDead(_33);
           _0 = const ();
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
index 8572f538c0f..4296d4d4a59 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
@@ -111,8 +111,9 @@
           StorageLive(_7);
           StorageLive(_8);
 -         StorageLive(_9);
+-         StorageLive(_10);
++         nop;
 +         nop;
-          StorageLive(_10);
           StorageLive(_11);
           _11 = &(*_1);
           _10 = core::str::<impl str>::as_ptr(move _11) -> [return: bb3, unwind continue];
@@ -122,8 +123,9 @@
           StorageDead(_11);
           _9 = &_10;
 -         StorageLive(_12);
+-         StorageLive(_13);
++         nop;
 +         nop;
-          StorageLive(_13);
           StorageLive(_14);
 -         _14 = &(*_4);
 +         _14 = &(*_1);
@@ -148,11 +150,12 @@
           StorageLive(_17);
           StorageLive(_18);
 -         _18 = copy (*_15);
-+         _18 = copy (*_9);
++         _18 = copy _10;
           StorageLive(_19);
 -         _19 = copy (*_16);
-+         _19 = copy (*_12);
-          _17 = Eq(move _18, move _19);
+-         _17 = Eq(move _18, move _19);
++         _19 = copy _13;
++         _17 = Eq(copy _10, copy _13);
           switchInt(move _17) -> [0: bb6, otherwise: bb5];
       }
   
@@ -163,8 +166,10 @@
           StorageDead(_17);
           StorageDead(_16);
           StorageDead(_15);
-          StorageDead(_13);
-          StorageDead(_10);
+-         StorageDead(_13);
+-         StorageDead(_10);
++         nop;
++         nop;
           StorageDead(_8);
           StorageDead(_7);
 -         StorageLive(_29);
@@ -213,8 +218,9 @@
           StorageLive(_33);
           StorageLive(_34);
 -         StorageLive(_35);
+-         StorageLive(_36);
++         nop;
 +         nop;
-          StorageLive(_36);
           StorageLive(_37);
           _37 = &(*_1);
           _36 = core::str::<impl str>::as_ptr(move _37) -> [return: bb8, unwind continue];
@@ -224,8 +230,9 @@
           StorageDead(_37);
           _35 = &_36;
 -         StorageLive(_38);
+-         StorageLive(_39);
++         nop;
 +         nop;
-          StorageLive(_39);
           StorageLive(_40);
           _40 = &(*_29);
           _39 = core::slice::<impl [u8]>::as_ptr(move _40) -> [return: bb9, unwind continue];
@@ -249,11 +256,12 @@
           StorageLive(_43);
           StorageLive(_44);
 -         _44 = copy (*_41);
-+         _44 = copy (*_35);
++         _44 = copy _36;
           StorageLive(_45);
 -         _45 = copy (*_42);
-+         _45 = copy (*_38);
-          _43 = Eq(move _44, move _45);
+-         _43 = Eq(move _44, move _45);
++         _45 = copy _39;
++         _43 = Eq(copy _36, copy _39);
           switchInt(move _43) -> [0: bb11, otherwise: bb10];
       }
   
@@ -264,8 +272,10 @@
           StorageDead(_43);
           StorageDead(_42);
           StorageDead(_41);
-          StorageDead(_39);
-          StorageDead(_36);
+-         StorageDead(_39);
+-         StorageDead(_36);
++         nop;
++         nop;
           StorageDead(_34);
           StorageDead(_33);
           _0 = const ();
diff --git a/tests/mir-opt/gvn_clone.rs b/tests/mir-opt/gvn_clone.rs
index c16b665fbd3..08938c0e1b4 100644
--- a/tests/mir-opt/gvn_clone.rs
+++ b/tests/mir-opt/gvn_clone.rs
@@ -1,5 +1,3 @@
-//@ compile-flags: -Zunsound-mir-opts
-// FIXME: see <https://github.com/rust-lang/rust/issues/132353>
 //@ test-mir-pass: GVN
 //@ compile-flags: -Zmir-enable-passes=+InstSimplify-before-inline
 
diff --git a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
index 2a672e82970..0f23415ec53 100644
--- a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
+++ b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
@@ -1,7 +1,7 @@
-- // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` before GVN
-+ // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` after GVN
+- // MIR for `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` before GVN
++ // MIR for `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` after GVN
   
-  fn <impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone(_1: &AllCopy) -> AllCopy {
+  fn <impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone(_1: &AllCopy) -> AllCopy {
       debug self => _1;
       let mut _0: AllCopy;
       let mut _2: i32;
diff --git a/tests/mir-opt/gvn_copy_aggregate.rs b/tests/mir-opt/gvn_copy_aggregate.rs
index 7c181d1ad37..c9473025a15 100644
--- a/tests/mir-opt/gvn_copy_aggregate.rs
+++ b/tests/mir-opt/gvn_copy_aggregate.rs
@@ -1,5 +1,3 @@
-//@ compile-flags: -Zunsound-mir-opts
-// FIXME: see <https://github.com/rust-lang/rust/issues/132353.
 //@ test-mir-pass: GVN
 //@ compile-flags: -Cpanic=abort
 
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
index 881b629803a..a3e4796d088 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
@@ -17,15 +17,16 @@
           StorageLive(_3);
           _5 = const f::promoted[0];
           _3 = &(*_5);
-          _2 = copy ((*_3).1: E);
--         StorageLive(_1);
-+         nop;
-          _1 = copy ((_2 as A).1: u32);
+-         _2 = copy ((*_3).1: E);
++         _2 = const Scalar(0x00000000): E;
+          StorageLive(_1);
+-         _1 = copy ((_2 as A).1: u32);
++         _1 = const 0_u32;
           StorageDead(_3);
           StorageDead(_2);
-          _0 = copy _1;
--         StorageDead(_1);
-+         nop;
+-         _0 = copy _1;
++         _0 = const 0_u32;
+          StorageDead(_1);
           return;
       }
   }
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
index 881b629803a..a3e4796d088 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
@@ -17,15 +17,16 @@
           StorageLive(_3);
           _5 = const f::promoted[0];
           _3 = &(*_5);
-          _2 = copy ((*_3).1: E);
--         StorageLive(_1);
-+         nop;
-          _1 = copy ((_2 as A).1: u32);
+-         _2 = copy ((*_3).1: E);
++         _2 = const Scalar(0x00000000): E;
+          StorageLive(_1);
+-         _1 = copy ((_2 as A).1: u32);
++         _1 = const 0_u32;
           StorageDead(_3);
           StorageDead(_2);
-          _0 = copy _1;
--         StorageDead(_1);
-+         nop;
+-         _0 = copy _1;
++         _0 = const 0_u32;
+          StorageDead(_1);
           return;
       }
   }
diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.rs b/tests/mir-opt/pre-codegen/clone_as_copy.rs
index ae4661e93fd..f5ff1854d38 100644
--- a/tests/mir-opt/pre-codegen/clone_as_copy.rs
+++ b/tests/mir-opt/pre-codegen/clone_as_copy.rs
@@ -1,5 +1,3 @@
-//@ compile-flags: -Zunsound-mir-opts
-// FIXME: see <https://github.com/rust-lang/rust/issues/132353>
 //@ compile-flags: -Cdebuginfo=full
 
 // Check if we have transformed the nested clone to the copy in the complete pipeline.
diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.rs b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs
index 4f70ec36bc9..738cd981ae6 100644
--- a/tests/mir-opt/pre-codegen/deref_nested_borrows.rs
+++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs
@@ -1,4 +1,3 @@
-//! Regression test for <https://github.com/rust-lang/rust/issues/130853>
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 fn src(x: &&u8) -> bool {
diff --git a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir
index 62a9cd9131f..9020cf1ef37 100644
--- a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir
@@ -3,13 +3,9 @@
 fn <impl at $DIR/no_inlined_clone.rs:9:10: 9:15>::clone(_1: &Foo) -> Foo {
     debug self => _1;
     let mut _0: Foo;
-    let mut _2: i32;
 
     bb0: {
-        StorageLive(_2);
-        _2 = copy ((*_1).0: i32);
-        _0 = Foo { a: move _2 };
-        StorageDead(_2);
+        _0 = copy (*_1);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir
index 5a269717f82..cbdd194afd3 100644
--- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir
@@ -4,70 +4,65 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
     let mut _0: bool;
     let mut _3: &(usize, usize, usize, usize);
     let _4: &usize;
-    let mut _5: &(usize, usize, usize, usize);
+    let _5: &usize;
     let _6: &usize;
-    let mut _7: &(usize, usize, usize, usize);
-    let _8: &usize;
-    let mut _9: &(usize, usize, usize, usize);
-    let _10: &usize;
-    let mut _11: &&usize;
-    let _12: &usize;
-    let mut _13: &&usize;
-    let mut _16: bool;
-    let mut _17: &&usize;
-    let _18: &usize;
-    let mut _19: &&usize;
-    let mut _22: bool;
-    let mut _23: &&usize;
-    let _24: &usize;
-    let mut _25: &&usize;
-    let mut _28: bool;
-    let mut _29: &&usize;
-    let _30: &usize;
-    let mut _31: &&usize;
+    let _7: &usize;
+    let mut _8: &&usize;
+    let _9: &usize;
+    let mut _10: &&usize;
+    let mut _13: bool;
+    let mut _14: &&usize;
+    let _15: &usize;
+    let mut _16: &&usize;
+    let mut _19: bool;
+    let mut _20: &&usize;
+    let _21: &usize;
+    let mut _22: &&usize;
+    let mut _23: bool;
+    let mut _24: &&usize;
+    let _25: &usize;
+    let mut _26: &&usize;
     scope 1 {
         debug a => _4;
-        debug b => _6;
-        debug c => _8;
-        debug d => _10;
+        debug b => _5;
+        debug c => _6;
+        debug d => _7;
         scope 2 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _11;
-            debug other => _13;
+            debug self => _8;
+            debug other => _10;
             scope 3 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
                 debug self => _4;
-                debug other => _8;
-                let mut _14: usize;
-                let mut _15: usize;
+                debug other => _6;
+                let mut _11: usize;
+                let mut _12: usize;
             }
         }
         scope 4 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _17;
-            debug other => _19;
+            debug self => _14;
+            debug other => _16;
             scope 5 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _10;
-                debug other => _6;
-                let mut _20: usize;
-                let mut _21: usize;
+                debug self => _7;
+                debug other => _5;
+                let mut _17: usize;
+                let mut _18: usize;
             }
         }
         scope 6 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _23;
-            debug other => _25;
+            debug self => _20;
+            debug other => _22;
             scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _8;
+                debug self => _6;
                 debug other => _4;
-                let mut _26: usize;
-                let mut _27: usize;
             }
         }
         scope 8 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _29;
-            debug other => _31;
+            debug self => _24;
+            debug other => _26;
             scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _6;
-                debug other => _10;
-                let mut _32: usize;
-                let mut _33: usize;
+                debug self => _5;
+                debug other => _7;
+                let mut _27: usize;
+                let mut _28: usize;
             }
         }
     }
@@ -75,129 +70,116 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
     bb0: {
         _3 = copy (*_2);
         _4 = &((*_3).0: usize);
-        _5 = copy (*_2);
-        _6 = &((*_5).1: usize);
-        _7 = copy (*_2);
-        _8 = &((*_7).2: usize);
-        _9 = copy (*_2);
-        _10 = &((*_9).3: usize);
-        StorageLive(_16);
-        StorageLive(_11);
-        _11 = &_4;
+        _5 = &((*_3).1: usize);
+        _6 = &((*_3).2: usize);
+        _7 = &((*_3).3: usize);
         StorageLive(_13);
-        StorageLive(_12);
-        _12 = copy _8;
-        _13 = &_12;
-        StorageLive(_14);
-        _14 = copy ((*_3).0: usize);
-        StorageLive(_15);
-        _15 = copy ((*_7).2: usize);
-        _16 = Le(move _14, move _15);
-        StorageDead(_15);
-        StorageDead(_14);
-        switchInt(move _16) -> [0: bb1, otherwise: bb2];
+        StorageLive(_8);
+        _8 = &_4;
+        StorageLive(_10);
+        StorageLive(_9);
+        _9 = copy _6;
+        _10 = &_9;
+        _11 = copy ((*_3).0: usize);
+        _12 = copy ((*_3).2: usize);
+        _13 = Le(copy _11, copy _12);
+        switchInt(move _13) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageDead(_12);
-        StorageDead(_13);
-        StorageDead(_11);
+        StorageDead(_9);
+        StorageDead(_10);
+        StorageDead(_8);
         goto -> bb4;
     }
 
     bb2: {
-        StorageDead(_12);
-        StorageDead(_13);
-        StorageDead(_11);
-        StorageLive(_22);
-        StorageLive(_17);
-        _17 = &_10;
+        StorageDead(_9);
+        StorageDead(_10);
+        StorageDead(_8);
         StorageLive(_19);
+        StorageLive(_14);
+        _14 = &_7;
+        StorageLive(_16);
+        StorageLive(_15);
+        _15 = copy _5;
+        _16 = &_15;
+        StorageLive(_17);
+        _17 = copy ((*_3).3: usize);
         StorageLive(_18);
-        _18 = copy _6;
-        _19 = &_18;
-        StorageLive(_20);
-        _20 = copy ((*_9).3: usize);
-        StorageLive(_21);
-        _21 = copy ((*_5).1: usize);
-        _22 = Le(move _20, move _21);
-        StorageDead(_21);
-        StorageDead(_20);
-        switchInt(move _22) -> [0: bb3, otherwise: bb8];
+        _18 = copy ((*_3).1: usize);
+        _19 = Le(move _17, move _18);
+        StorageDead(_18);
+        StorageDead(_17);
+        switchInt(move _19) -> [0: bb3, otherwise: bb8];
     }
 
     bb3: {
-        StorageDead(_18);
-        StorageDead(_19);
-        StorageDead(_17);
+        StorageDead(_15);
+        StorageDead(_16);
+        StorageDead(_14);
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_28);
         StorageLive(_23);
-        _23 = &_8;
-        StorageLive(_25);
-        StorageLive(_24);
-        _24 = copy _4;
-        _25 = &_24;
-        StorageLive(_26);
-        _26 = copy ((*_7).2: usize);
-        StorageLive(_27);
-        _27 = copy ((*_3).0: usize);
-        _28 = Le(move _26, move _27);
-        StorageDead(_27);
-        StorageDead(_26);
-        switchInt(move _28) -> [0: bb5, otherwise: bb6];
+        StorageLive(_20);
+        _20 = &_6;
+        StorageLive(_22);
+        StorageLive(_21);
+        _21 = copy _4;
+        _22 = &_21;
+        _23 = Le(copy _12, copy _11);
+        switchInt(move _23) -> [0: bb5, otherwise: bb6];
     }
 
     bb5: {
-        StorageDead(_24);
-        StorageDead(_25);
-        StorageDead(_23);
+        StorageDead(_21);
+        StorageDead(_22);
+        StorageDead(_20);
         _0 = const false;
         goto -> bb7;
     }
 
     bb6: {
-        StorageDead(_24);
+        StorageDead(_21);
+        StorageDead(_22);
+        StorageDead(_20);
+        StorageLive(_24);
+        _24 = &_5;
+        StorageLive(_26);
+        StorageLive(_25);
+        _25 = copy _7;
+        _26 = &_25;
+        StorageLive(_27);
+        _27 = copy ((*_3).1: usize);
+        StorageLive(_28);
+        _28 = copy ((*_3).3: usize);
+        _0 = Le(move _27, move _28);
+        StorageDead(_28);
+        StorageDead(_27);
         StorageDead(_25);
-        StorageDead(_23);
-        StorageLive(_29);
-        _29 = &_6;
-        StorageLive(_31);
-        StorageLive(_30);
-        _30 = copy _10;
-        _31 = &_30;
-        StorageLive(_32);
-        _32 = copy ((*_5).1: usize);
-        StorageLive(_33);
-        _33 = copy ((*_9).3: usize);
-        _0 = Le(move _32, move _33);
-        StorageDead(_33);
-        StorageDead(_32);
-        StorageDead(_30);
-        StorageDead(_31);
-        StorageDead(_29);
+        StorageDead(_26);
+        StorageDead(_24);
         goto -> bb7;
     }
 
     bb7: {
-        StorageDead(_28);
+        StorageDead(_23);
         goto -> bb9;
     }
 
     bb8: {
-        StorageDead(_18);
-        StorageDead(_19);
-        StorageDead(_17);
+        StorageDead(_15);
+        StorageDead(_16);
+        StorageDead(_14);
         _0 = const true;
         goto -> bb9;
     }
 
     bb9: {
-        StorageDead(_22);
-        StorageDead(_16);
+        StorageDead(_19);
+        StorageDead(_13);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir
index f93f7264dec..bc7a31d5219 100644
--- a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir
@@ -4,46 +4,40 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41},
     let mut _0: bool;
     let mut _3: &(usize, usize, usize, usize);
     let _4: usize;
-    let mut _5: &(usize, usize, usize, usize);
+    let _5: usize;
     let _6: usize;
-    let mut _7: &(usize, usize, usize, usize);
-    let _8: usize;
-    let mut _9: &(usize, usize, usize, usize);
-    let _10: usize;
-    let mut _11: bool;
-    let mut _12: bool;
-    let mut _13: bool;
+    let _7: usize;
+    let mut _8: bool;
+    let mut _9: bool;
+    let mut _10: bool;
     scope 1 {
         debug a => _4;
-        debug b => _6;
-        debug c => _8;
-        debug d => _10;
+        debug b => _5;
+        debug c => _6;
+        debug d => _7;
     }
 
     bb0: {
         _3 = copy (*_2);
         _4 = copy ((*_3).0: usize);
-        _5 = copy (*_2);
-        _6 = copy ((*_5).1: usize);
-        _7 = copy (*_2);
-        _8 = copy ((*_7).2: usize);
-        _9 = copy (*_2);
-        _10 = copy ((*_9).3: usize);
-        StorageLive(_11);
-        _11 = Le(copy _4, copy _8);
-        switchInt(move _11) -> [0: bb2, otherwise: bb1];
+        _5 = copy ((*_3).1: usize);
+        _6 = copy ((*_3).2: usize);
+        _7 = copy ((*_3).3: usize);
+        StorageLive(_8);
+        _8 = Le(copy _4, copy _6);
+        switchInt(move _8) -> [0: bb2, otherwise: bb1];
     }
 
     bb1: {
-        StorageLive(_12);
-        _12 = Le(copy _10, copy _6);
-        switchInt(move _12) -> [0: bb2, otherwise: bb6];
+        StorageLive(_9);
+        _9 = Le(copy _7, copy _5);
+        switchInt(move _9) -> [0: bb2, otherwise: bb6];
     }
 
     bb2: {
-        StorageLive(_13);
-        _13 = Le(copy _8, copy _4);
-        switchInt(move _13) -> [0: bb3, otherwise: bb4];
+        StorageLive(_10);
+        _10 = Le(copy _6, copy _4);
+        switchInt(move _10) -> [0: bb3, otherwise: bb4];
     }
 
     bb3: {
@@ -52,12 +46,12 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41},
     }
 
     bb4: {
-        _0 = Le(copy _6, copy _10);
+        _0 = Le(copy _5, copy _7);
         goto -> bb5;
     }
 
     bb5: {
-        StorageDead(_13);
+        StorageDead(_10);
         goto -> bb7;
     }
 
@@ -67,8 +61,8 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41},
     }
 
     bb7: {
-        StorageDead(_12);
-        StorageDead(_11);
+        StorageDead(_9);
+        StorageDead(_8);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index 7ef532d222d..c75edde711e 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -22,74 +22,74 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
             debug i => _33;
             debug x => _34;
         }
-        scope 19 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _27: std::option::Option<&T>;
             let mut _30: (usize, bool);
             let mut _31: (usize, &T);
-            scope 20 {
+            scope 19 {
                 let _29: usize;
-                scope 25 {
+                scope 24 {
                 }
             }
-            scope 21 {
-                scope 22 {
-                    scope 28 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
+            scope 20 {
+                scope 21 {
+                    scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
                     }
                 }
             }
-            scope 23 {
-                scope 24 {
+            scope 22 {
+                scope 23 {
                 }
             }
-            scope 26 (inlined <Option<&T> as Try>::branch) {
+            scope 25 (inlined <Option<&T> as Try>::branch) {
                 let _28: &T;
-                scope 27 {
+                scope 26 {
                 }
             }
-            scope 29 (inlined <std::slice::Iter<'_, T> as Iterator>::next) {
+            scope 28 (inlined <std::slice::Iter<'_, T> as Iterator>::next) {
                 let _14: std::ptr::NonNull<T>;
                 let _16: std::ptr::NonNull<T>;
                 let mut _19: bool;
                 let mut _22: std::ptr::NonNull<T>;
                 let mut _24: usize;
                 let _26: &T;
-                scope 30 {
+                scope 29 {
                     let _15: *const T;
-                    scope 31 {
+                    scope 30 {
                         let _23: usize;
-                        scope 32 {
-                            scope 35 (inlined core::num::<impl usize>::unchecked_sub) {
-                                scope 36 (inlined core::ub_checks::check_language_ub) {
-                                    scope 37 (inlined core::ub_checks::check_language_ub::runtime) {
+                        scope 31 {
+                            scope 34 (inlined core::num::<impl usize>::unchecked_sub) {
+                                scope 35 (inlined core::ub_checks::check_language_ub) {
+                                    scope 36 (inlined core::ub_checks::check_language_ub::runtime) {
                                     }
                                 }
                             }
-                            scope 38 (inlined without_provenance_mut::<T>) {
+                            scope 37 (inlined without_provenance_mut::<T>) {
                             }
                         }
-                        scope 33 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
-                            scope 34 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
+                        scope 32 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
+                            scope 33 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
                             }
                         }
-                        scope 39 (inlined <NonNull<T> as PartialEq>::eq) {
+                        scope 38 (inlined <NonNull<T> as PartialEq>::eq) {
                             let mut _17: *mut T;
                             let mut _18: *mut T;
-                            scope 40 (inlined NonNull::<T>::as_ptr) {
+                            scope 39 (inlined NonNull::<T>::as_ptr) {
                             }
-                            scope 41 (inlined NonNull::<T>::as_ptr) {
+                            scope 40 (inlined NonNull::<T>::as_ptr) {
                             }
                         }
-                        scope 42 (inlined NonNull::<T>::add) {
+                        scope 41 (inlined NonNull::<T>::add) {
                             let mut _20: *const T;
                             let mut _21: *const T;
-                            scope 43 (inlined NonNull::<T>::as_ptr) {
+                            scope 42 (inlined NonNull::<T>::as_ptr) {
                             }
                         }
-                        scope 44 (inlined NonNull::<T>::as_ref::<'_>) {
+                        scope 43 (inlined NonNull::<T>::as_ref::<'_>) {
                             let _25: *const T;
-                            scope 45 (inlined NonNull::<T>::as_ptr) {
+                            scope 44 (inlined NonNull::<T>::as_ptr) {
                             }
-                            scope 46 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
+                            scope 45 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
                             }
                         }
                     }
@@ -109,33 +109,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined std::ptr::without_provenance::<T>) {
-                        scope 13 (inlined without_provenance_mut::<T>) {
+                    scope 11 (inlined std::ptr::without_provenance::<T>) {
+                        scope 12 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 14 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
-                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    scope 9 (inlined NonNull::<[T]>::from_ref) {
-                        let mut _4: *const [T];
-                    }
+                scope 8 (inlined NonNull::<[T]>::from_ref) {
+                    let mut _4: *const [T];
                 }
-                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        scope 17 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index 33dbf04d028..bc72181b77c 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -34,33 +34,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined std::ptr::without_provenance::<T>) {
-                        scope 13 (inlined without_provenance_mut::<T>) {
+                    scope 11 (inlined std::ptr::without_provenance::<T>) {
+                        scope 12 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 14 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
-                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    scope 9 (inlined NonNull::<[T]>::from_ref) {
-                        let mut _4: *const [T];
-                    }
+                scope 8 (inlined NonNull::<[T]>::from_ref) {
+                    let mut _4: *const [T];
                 }
-                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        scope 17 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 62787f3447c..38c509d0b53 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -18,50 +18,50 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _27;
         }
-        scope 17 (inlined <std::slice::Iter<'_, T> as Iterator>::next) {
+        scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::next) {
             let _13: std::ptr::NonNull<T>;
             let _15: std::ptr::NonNull<T>;
             let mut _18: bool;
             let mut _21: std::ptr::NonNull<T>;
             let mut _23: usize;
             let _25: &T;
-            scope 18 {
+            scope 17 {
                 let _14: *const T;
-                scope 19 {
+                scope 18 {
                     let _22: usize;
-                    scope 20 {
-                        scope 23 (inlined core::num::<impl usize>::unchecked_sub) {
-                            scope 24 (inlined core::ub_checks::check_language_ub) {
-                                scope 25 (inlined core::ub_checks::check_language_ub::runtime) {
+                    scope 19 {
+                        scope 22 (inlined core::num::<impl usize>::unchecked_sub) {
+                            scope 23 (inlined core::ub_checks::check_language_ub) {
+                                scope 24 (inlined core::ub_checks::check_language_ub::runtime) {
                                 }
                             }
                         }
-                        scope 26 (inlined without_provenance_mut::<T>) {
+                        scope 25 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 21 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
-                        scope 22 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
+                    scope 20 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
+                        scope 21 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
                         }
                     }
-                    scope 27 (inlined <NonNull<T> as PartialEq>::eq) {
+                    scope 26 (inlined <NonNull<T> as PartialEq>::eq) {
                         let mut _16: *mut T;
                         let mut _17: *mut T;
-                        scope 28 (inlined NonNull::<T>::as_ptr) {
+                        scope 27 (inlined NonNull::<T>::as_ptr) {
                         }
-                        scope 29 (inlined NonNull::<T>::as_ptr) {
+                        scope 28 (inlined NonNull::<T>::as_ptr) {
                         }
                     }
-                    scope 30 (inlined NonNull::<T>::add) {
+                    scope 29 (inlined NonNull::<T>::add) {
                         let mut _19: *const T;
                         let mut _20: *const T;
-                        scope 31 (inlined NonNull::<T>::as_ptr) {
+                        scope 30 (inlined NonNull::<T>::as_ptr) {
                         }
                     }
-                    scope 32 (inlined NonNull::<T>::as_ref::<'_>) {
+                    scope 31 (inlined NonNull::<T>::as_ref::<'_>) {
                         let _24: *const T;
-                        scope 33 (inlined NonNull::<T>::as_ptr) {
+                        scope 32 (inlined NonNull::<T>::as_ptr) {
                         }
-                        scope 34 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
+                        scope 33 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
                         }
                     }
                 }
@@ -80,29 +80,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined std::ptr::without_provenance::<T>) {
-                        scope 13 (inlined without_provenance_mut::<T>) {
+                    scope 11 (inlined std::ptr::without_provenance::<T>) {
+                        scope 12 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 14 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
-                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    scope 9 (inlined NonNull::<[T]>::from_ref) {
-                        let mut _4: *const [T];
-                    }
+                scope 8 (inlined NonNull::<[T]>::from_ref) {
+                    let mut _4: *const [T];
                 }
-                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 16 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index e5478e27918..158cc284b1a 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -18,50 +18,50 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _27;
         }
-        scope 17 (inlined <std::slice::Iter<'_, T> as Iterator>::next) {
+        scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::next) {
             let _13: std::ptr::NonNull<T>;
             let _15: std::ptr::NonNull<T>;
             let mut _18: bool;
             let mut _21: std::ptr::NonNull<T>;
             let mut _23: usize;
             let _25: &T;
-            scope 18 {
+            scope 17 {
                 let _14: *const T;
-                scope 19 {
+                scope 18 {
                     let _22: usize;
-                    scope 20 {
-                        scope 23 (inlined core::num::<impl usize>::unchecked_sub) {
-                            scope 24 (inlined core::ub_checks::check_language_ub) {
-                                scope 25 (inlined core::ub_checks::check_language_ub::runtime) {
+                    scope 19 {
+                        scope 22 (inlined core::num::<impl usize>::unchecked_sub) {
+                            scope 23 (inlined core::ub_checks::check_language_ub) {
+                                scope 24 (inlined core::ub_checks::check_language_ub::runtime) {
                                 }
                             }
                         }
-                        scope 26 (inlined without_provenance_mut::<T>) {
+                        scope 25 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 21 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
-                        scope 22 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
+                    scope 20 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
+                        scope 21 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
                         }
                     }
-                    scope 27 (inlined <NonNull<T> as PartialEq>::eq) {
+                    scope 26 (inlined <NonNull<T> as PartialEq>::eq) {
                         let mut _16: *mut T;
                         let mut _17: *mut T;
-                        scope 28 (inlined NonNull::<T>::as_ptr) {
+                        scope 27 (inlined NonNull::<T>::as_ptr) {
                         }
-                        scope 29 (inlined NonNull::<T>::as_ptr) {
+                        scope 28 (inlined NonNull::<T>::as_ptr) {
                         }
                     }
-                    scope 30 (inlined NonNull::<T>::add) {
+                    scope 29 (inlined NonNull::<T>::add) {
                         let mut _19: *const T;
                         let mut _20: *const T;
-                        scope 31 (inlined NonNull::<T>::as_ptr) {
+                        scope 30 (inlined NonNull::<T>::as_ptr) {
                         }
                     }
-                    scope 32 (inlined NonNull::<T>::as_ref::<'_>) {
+                    scope 31 (inlined NonNull::<T>::as_ref::<'_>) {
                         let _24: *const T;
-                        scope 33 (inlined NonNull::<T>::as_ptr) {
+                        scope 32 (inlined NonNull::<T>::as_ptr) {
                         }
-                        scope 34 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
+                        scope 33 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
                         }
                     }
                 }
@@ -80,29 +80,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined std::ptr::without_provenance::<T>) {
-                        scope 13 (inlined without_provenance_mut::<T>) {
+                    scope 11 (inlined std::ptr::without_provenance::<T>) {
+                        scope 12 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 14 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
-                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    scope 9 (inlined NonNull::<[T]>::from_ref) {
-                        let mut _4: *const [T];
-                    }
+                scope 8 (inlined NonNull::<[T]>::from_ref) {
+                    let mut _4: *const [T];
                 }
-                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 16 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index 4b7ab4516d2..00366762108 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _17;
         }
-        scope 19 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
@@ -34,33 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined std::ptr::without_provenance::<T>) {
-                        scope 13 (inlined without_provenance_mut::<T>) {
+                    scope 11 (inlined std::ptr::without_provenance::<T>) {
+                        scope 12 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 14 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
-                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    scope 9 (inlined NonNull::<[T]>::from_ref) {
-                        let mut _4: *const [T];
-                    }
+                scope 8 (inlined NonNull::<[T]>::from_ref) {
+                    let mut _4: *const [T];
                 }
-                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        scope 17 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index b2c15247cd7..e1d710fb689 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _17;
         }
-        scope 19 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
@@ -34,33 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 12 (inlined std::ptr::without_provenance::<T>) {
-                        scope 13 (inlined without_provenance_mut::<T>) {
+                    scope 11 (inlined std::ptr::without_provenance::<T>) {
+                        scope 12 (inlined without_provenance_mut::<T>) {
                         }
                     }
-                    scope 14 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
-                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    scope 9 (inlined NonNull::<[T]>::from_ref) {
-                        let mut _4: *const [T];
-                    }
+                scope 8 (inlined NonNull::<[T]>::from_ref) {
+                    let mut _4: *const [T];
                 }
-                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        scope 17 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir
index ac485f485b1..889e80d26e1 100644
--- a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir
@@ -19,14 +19,14 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb1: {
-        _3 = move ((_1 as Ok).0: T);
-        _0 = Result::<T, E>::Ok(copy _3);
+        _3 = copy ((_1 as Ok).0: T);
+        _0 = copy _1;
         goto -> bb3;
     }
 
     bb2: {
-        _4 = move ((_1 as Err).0: E);
-        _0 = Result::<T, E>::Err(copy _4);
+        _4 = copy ((_1 as Err).0: E);
+        _0 = copy _1;
         goto -> bb3;
     }
 
diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff
index 22d4277ee45..54c11679f0c 100644
--- a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff
+++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff
@@ -6,62 +6,52 @@
       let mut _0: std::option::Option<i32>;
       let mut _2: &std::option::Option<i32>;
       let mut _3: &std::option::Option<i32>;
-      let _4: &&mut std::option::Option<i32>;
-      let mut _5: isize;
-      let mut _7: !;
-      let mut _8: std::option::Option<i32>;
-      let mut _9: i32;
-      let mut _10: !;
-      let mut _11: &mut std::option::Option<i32>;
+      let mut _4: isize;
+      let mut _6: !;
+      let mut _7: std::option::Option<i32>;
+      let mut _8: i32;
+      let mut _9: !;
       scope 1 {
-          debug col => _6;
-          let _6: i32;
+          debug col => _5;
+          let _5: i32;
       }
   
       bb0: {
--         StorageLive(_2);
-+         nop;
+          StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_4);
-          _4 = &_1;
--         _11 = deref_copy (*_4);
--         _3 = &(*_11);
-+         _11 = copy _1;
-+         _3 = &(*_1);
-          _2 = get(move _3) -> [return: bb1, unwind unreachable];
+          _3 = &(*_1);
+          _2 = get::<Option<i32>>(move _3) -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
           StorageDead(_3);
-          _5 = discriminant((*_2));
-          switchInt(move _5) -> [1: bb2, otherwise: bb3];
+          _4 = discriminant((*_2));
+          switchInt(move _4) -> [1: bb2, otherwise: bb3];
       }
   
       bb2: {
--         StorageLive(_6);
+-         StorageLive(_5);
 +         nop;
-          _6 = copy (((*_2) as Some).0: i32);
-          StorageLive(_8);
--         _8 = Option::<i32>::None;
--         (*_1) = move _8;
-+         _8 = const Option::<i32>::None;
+          _5 = copy (((*_2) as Some).0: i32);
+          StorageLive(_7);
+-         _7 = Option::<i32>::None;
+-         (*_1) = move _7;
++         _7 = const Option::<i32>::None;
 +         (*_1) = const Option::<i32>::None;
+          StorageDead(_7);
+          StorageLive(_8);
+          _8 = copy _5;
+-         _0 = Option::<i32>::Some(move _8);
++         _0 = Option::<i32>::Some(copy _5);
           StorageDead(_8);
-          StorageLive(_9);
-          _9 = copy _6;
--         _0 = Option::<i32>::Some(move _9);
-+         _0 = copy (*_2);
-          StorageDead(_9);
--         StorageDead(_6);
-+         nop;
-          StorageDead(_4);
--         StorageDead(_2);
+-         StorageDead(_5);
 +         nop;
+          StorageDead(_2);
           return;
       }
   
       bb3: {
-          StorageLive(_10);
+          StorageLive(_9);
           unreachable;
       }
 + }
diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs
index 47721b768be..33e31b56977 100644
--- a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs
+++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs
@@ -7,16 +7,23 @@
 //! This test demonstrates the behavior, and should be adjusted or removed when fixing and relanding
 //! the mir-opt.
 #![crate_type = "lib"]
-// skip-filecheck
-//@ compile-flags: -O -Zunsound-mir-opts
 //@ test-mir-pass: GVN
 #![allow(internal_features)]
-#![feature(rustc_attrs, core_intrinsics)]
+#![feature(core_intrinsics, custom_mir, rustc_attrs)]
+
+use std::intrinsics::mir::*;
 
 // EMIT_MIR simplify_aggregate_to_copy_miscompile.foo.GVN.diff
-#[no_mangle]
 fn foo(v: &mut Option<i32>) -> Option<i32> {
-    if let &Some(col) = get(&v) {
+    // CHECK-LABEL: fn foo(
+    // CHECK-SAME: [[v:_.*]]: &mut Option<i32>
+    // CHECK: [[v_alias_1:_.*]] = &(*_1)
+    // CHECK-NEXT: [[v_alias_2:_.*]] = get::<Option<i32>>(move [[v_alias_1]])
+    // CHECK: (*[[v]]) = const Option::<i32>::None;
+    // CHECK-NOT: _0 = copy (*[[v_alias_2]])
+    // CHECK: _0 = Option::<i32>::Some
+    // CHECK-NOT: _0 = copy (*[[v_alias_2]])
+    if let &Some(col) = get(v) {
         *v = None;
         return Some(col);
     } else {
@@ -24,9 +31,31 @@ fn foo(v: &mut Option<i32>) -> Option<i32> {
     }
 }
 
-#[no_mangle]
+pub enum Value {
+    V0(i32),
+    V1(i32),
+}
+
+// EMIT_MIR simplify_aggregate_to_copy_miscompile.set_discriminant.GVN.diff
+#[custom_mir(dialect = "runtime", phase = "initial")]
+fn set_discriminant(v: &mut Value) -> Value {
+    // CHECK-LABEL: fn set_discriminant(
+    mir! {
+        let v_: &Value;
+        {
+            Call(v_ = get(v), ReturnTo(ret), UnwindUnreachable())
+        }
+        ret = {
+            let col: i32 = Field(Variant(*v_, 0), 0);
+            SetDiscriminant(*v, 1);
+            RET = Value::V0(col);
+            Return()
+        }
+    }
+}
+
 #[inline(never)]
 #[rustc_nounwind]
-fn get(v: &Option<i32>) -> &Option<i32> {
+fn get<T>(v: &T) -> &T {
     v
 }
diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.set_discriminant.GVN.diff b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.set_discriminant.GVN.diff
new file mode 100644
index 00000000000..41f9763d024
--- /dev/null
+++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.set_discriminant.GVN.diff
@@ -0,0 +1,20 @@
+- // MIR for `set_discriminant` before GVN
++ // MIR for `set_discriminant` after GVN
+  
+  fn set_discriminant(_1: &mut Value) -> Value {
+      let mut _0: Value;
+      let mut _2: &Value;
+      let mut _3: i32;
+  
+      bb0: {
+          _2 = get::<Value>(copy _1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          _3 = copy (((*_2) as variant#0).0: i32);
+          discriminant((*_1)) = 1;
+          _0 = Value::V0(copy _3);
+          return;
+      }
+  }
+  
diff --git a/tests/pretty/autodiff_forward.pp b/tests/pretty/autodiff_forward.pp
index dc7a2712f42..4b2fb6166ff 100644
--- a/tests/pretty/autodiff_forward.pp
+++ b/tests/pretty/autodiff_forward.pp
@@ -25,27 +25,31 @@ pub fn f1(x: &[f64], y: f64) -> f64 {
 
     // We want to be sure that the same function can be differentiated in different ways
 
+
+    // Make sure, that we add the None for the default return.
+
+
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(Forward, Dual, Const, Dual,)]
+#[rustc_autodiff(Forward, 1, Dual, Const, Dual)]
 #[inline(never)]
-pub fn df1(x: &[f64], bx: &[f64], y: f64) -> (f64, f64) {
+pub fn df1(x: &[f64], bx_0: &[f64], y: f64) -> (f64, f64) {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f1(x, y));
-    ::core::hint::black_box((bx,));
-    ::core::hint::black_box((f1(x, y), f64::default()))
+    ::core::hint::black_box((bx_0,));
+    ::core::hint::black_box(<(f64, f64)>::default())
 }
 #[rustc_autodiff]
 #[inline(never)]
 pub fn f2(x: &[f64], y: f64) -> f64 {
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(Forward, Dual, Const, Const,)]
+#[rustc_autodiff(Forward, 1, Dual, Const, Const)]
 #[inline(never)]
-pub fn df2(x: &[f64], bx: &[f64], y: f64) -> f64 {
+pub fn df2(x: &[f64], bx_0: &[f64], y: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f2(x, y));
-    ::core::hint::black_box((bx,));
+    ::core::hint::black_box((bx_0,));
     ::core::hint::black_box(f2(x, y))
 }
 #[rustc_autodiff]
@@ -53,20 +57,20 @@ pub fn df2(x: &[f64], bx: &[f64], y: f64) -> f64 {
 pub fn f3(x: &[f64], y: f64) -> f64 {
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(Forward, Dual, Const, Const,)]
+#[rustc_autodiff(Forward, 1, Dual, Const, Const)]
 #[inline(never)]
-pub fn df3(x: &[f64], bx: &[f64], y: f64) -> f64 {
+pub fn df3(x: &[f64], bx_0: &[f64], y: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f3(x, y));
-    ::core::hint::black_box((bx,));
+    ::core::hint::black_box((bx_0,));
     ::core::hint::black_box(f3(x, y))
 }
 #[rustc_autodiff]
 #[inline(never)]
 pub fn f4() {}
-#[rustc_autodiff(Forward, None)]
+#[rustc_autodiff(Forward, 1, None)]
 #[inline(never)]
-pub fn df4() {
+pub fn df4() -> () {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f4());
     ::core::hint::black_box(());
@@ -76,28 +80,82 @@ pub fn df4() {
 pub fn f5(x: &[f64], y: f64) -> f64 {
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(Forward, Const, Dual, Const,)]
+#[rustc_autodiff(Forward, 1, Const, Dual, Const)]
 #[inline(never)]
-pub fn df5_y(x: &[f64], y: f64, by: f64) -> f64 {
+pub fn df5_y(x: &[f64], y: f64, by_0: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f5(x, y));
-    ::core::hint::black_box((by,));
+    ::core::hint::black_box((by_0,));
     ::core::hint::black_box(f5(x, y))
 }
-#[rustc_autodiff(Forward, Dual, Const, Const,)]
+#[rustc_autodiff(Forward, 1, Dual, Const, Const)]
 #[inline(never)]
-pub fn df5_x(x: &[f64], bx: &[f64], y: f64) -> f64 {
+pub fn df5_x(x: &[f64], bx_0: &[f64], y: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f5(x, y));
-    ::core::hint::black_box((bx,));
+    ::core::hint::black_box((bx_0,));
     ::core::hint::black_box(f5(x, y))
 }
-#[rustc_autodiff(Reverse, Duplicated, Const, Active,)]
+#[rustc_autodiff(Reverse, 1, Duplicated, Const, Active)]
 #[inline(never)]
-pub fn df5_rev(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 {
+pub fn df5_rev(x: &[f64], dx_0: &mut [f64], y: f64, dret: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f5(x, y));
-    ::core::hint::black_box((dx, dret));
+    ::core::hint::black_box((dx_0, dret));
     ::core::hint::black_box(f5(x, y))
 }
+struct DoesNotImplDefault;
+#[rustc_autodiff]
+#[inline(never)]
+pub fn f6() -> DoesNotImplDefault {
+    ::core::panicking::panic("not implemented")
+}
+#[rustc_autodiff(Forward, 1, Const)]
+#[inline(never)]
+pub fn df6() -> DoesNotImplDefault {
+    unsafe { asm!("NOP", options(pure, nomem)); };
+    ::core::hint::black_box(f6());
+    ::core::hint::black_box(());
+    ::core::hint::black_box(f6())
+}
+#[rustc_autodiff]
+#[inline(never)]
+pub fn f7(x: f32) -> () {}
+#[rustc_autodiff(Forward, 1, Const, None)]
+#[inline(never)]
+pub fn df7(x: f32) -> () {
+    unsafe { asm!("NOP", options(pure, nomem)); };
+    ::core::hint::black_box(f7(x));
+    ::core::hint::black_box(());
+}
+#[no_mangle]
+#[rustc_autodiff]
+#[inline(never)]
+fn f8(x: &f32) -> f32 { ::core::panicking::panic("not implemented") }
+#[rustc_autodiff(Forward, 4, Dual, Dual)]
+#[inline(never)]
+fn f8_3(x: &f32, bx_0: &f32, bx_1: &f32, bx_2: &f32, bx_3: &f32)
+    -> [f32; 5usize] {
+    unsafe { asm!("NOP", options(pure, nomem)); };
+    ::core::hint::black_box(f8(x));
+    ::core::hint::black_box((bx_0, bx_1, bx_2, bx_3));
+    ::core::hint::black_box(<[f32; 5usize]>::default())
+}
+#[rustc_autodiff(Forward, 4, Dual, DualOnly)]
+#[inline(never)]
+fn f8_2(x: &f32, bx_0: &f32, bx_1: &f32, bx_2: &f32, bx_3: &f32)
+    -> [f32; 4usize] {
+    unsafe { asm!("NOP", options(pure, nomem)); };
+    ::core::hint::black_box(f8(x));
+    ::core::hint::black_box((bx_0, bx_1, bx_2, bx_3));
+    ::core::hint::black_box(<[f32; 4usize]>::default())
+}
+#[rustc_autodiff(Forward, 1, Dual, DualOnly)]
+#[inline(never)]
+fn f8_1(x: &f32, bx_0: &f32) -> f32 {
+    unsafe { asm!("NOP", options(pure, nomem)); };
+    ::core::hint::black_box(f8(x));
+    ::core::hint::black_box((bx_0,));
+    ::core::hint::black_box(<f32>::default())
+}
 fn main() {}
diff --git a/tests/pretty/autodiff_forward.rs b/tests/pretty/autodiff_forward.rs
index bc558211632..a765738c2a8 100644
--- a/tests/pretty/autodiff_forward.rs
+++ b/tests/pretty/autodiff_forward.rs
@@ -36,4 +36,22 @@ pub fn f5(x: &[f64], y: f64) -> f64 {
     unimplemented!()
 }
 
+struct DoesNotImplDefault;
+#[autodiff(df6, Forward, Const)]
+pub fn f6() -> DoesNotImplDefault {
+    unimplemented!()
+}
+
+// Make sure, that we add the None for the default return.
+#[autodiff(df7, Forward, Const)]
+pub fn f7(x: f32) -> () {}
+
+#[autodiff(f8_1, Forward, Dual, DualOnly)]
+#[autodiff(f8_2, Forward, 4, Dual, DualOnly)]
+#[autodiff(f8_3, Forward, 4, Dual, Dual)]
+#[no_mangle]
+fn f8(x: &f32) -> f32 {
+    unimplemented!()
+}
+
 fn main() {}
diff --git a/tests/pretty/autodiff_reverse.pp b/tests/pretty/autodiff_reverse.pp
index b2cf0244af4..31920694a3a 100644
--- a/tests/pretty/autodiff_reverse.pp
+++ b/tests/pretty/autodiff_reverse.pp
@@ -28,18 +28,18 @@ pub fn f1(x: &[f64], y: f64) -> f64 {
 
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(Reverse, Duplicated, Const, Active,)]
+#[rustc_autodiff(Reverse, 1, Duplicated, Const, Active)]
 #[inline(never)]
-pub fn df1(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 {
+pub fn df1(x: &[f64], dx_0: &mut [f64], y: f64, dret: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f1(x, y));
-    ::core::hint::black_box((dx, dret));
+    ::core::hint::black_box((dx_0, dret));
     ::core::hint::black_box(f1(x, y))
 }
 #[rustc_autodiff]
 #[inline(never)]
 pub fn f2() {}
-#[rustc_autodiff(Reverse, None)]
+#[rustc_autodiff(Reverse, 1, None)]
 #[inline(never)]
 pub fn df2() {
     unsafe { asm!("NOP", options(pure, nomem)); };
@@ -51,12 +51,12 @@ pub fn df2() {
 pub fn f3(x: &[f64], y: f64) -> f64 {
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(Reverse, Duplicated, Const, Active,)]
+#[rustc_autodiff(Reverse, 1, Duplicated, Const, Active)]
 #[inline(never)]
-pub fn df3(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 {
+pub fn df3(x: &[f64], dx_0: &mut [f64], y: f64, dret: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f3(x, y));
-    ::core::hint::black_box((dx, dret));
+    ::core::hint::black_box((dx_0, dret));
     ::core::hint::black_box(f3(x, y))
 }
 enum Foo { Reverse, }
@@ -64,7 +64,7 @@ use Foo::Reverse;
 #[rustc_autodiff]
 #[inline(never)]
 pub fn f4(x: f32) { ::core::panicking::panic("not implemented") }
-#[rustc_autodiff(Reverse, Const, None)]
+#[rustc_autodiff(Reverse, 1, Const, None)]
 #[inline(never)]
 pub fn df4(x: f32) {
     unsafe { asm!("NOP", options(pure, nomem)); };
@@ -76,11 +76,11 @@ pub fn df4(x: f32) {
 pub fn f5(x: *const f32, y: &f32) {
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(Reverse, DuplicatedOnly, Duplicated, None)]
+#[rustc_autodiff(Reverse, 1, DuplicatedOnly, Duplicated, None)]
 #[inline(never)]
-pub unsafe fn df5(x: *const f32, dx: *mut f32, y: &f32, dy: &mut f32) {
+pub unsafe fn df5(x: *const f32, dx_0: *mut f32, y: &f32, dy_0: &mut f32) {
     unsafe { asm!("NOP", options(pure, nomem)); };
     ::core::hint::black_box(f5(x, y));
-    ::core::hint::black_box((dx, dy));
+    ::core::hint::black_box((dx_0, dy_0));
 }
 fn main() {}
diff --git a/tests/pretty/hir-lifetimes.pp b/tests/pretty/hir-lifetimes.pp
index e545b0c8f57..4d1ab9d383b 100644
--- a/tests/pretty/hir-lifetimes.pp
+++ b/tests/pretty/hir-lifetimes.pp
@@ -30,10 +30,10 @@ impl  Foo<'_> {
 
     // FIXME: impl Traits printed as just `/*impl Trait*/`, ugh
     fn iter1<'a>(&self)
-        -> /*impl Trait*/ { #[lang = "Range"]{ start: 0,  end: 1,} }
+        -> /*impl Trait*/ { #[lang = "Range"] { start: 0, end: 1 } }
 
     fn iter2(&self)
-        -> /*impl Trait*/ { #[lang = "Range"]{ start: 0,  end: 1,} }
+        -> /*impl Trait*/ { #[lang = "Range"] { start: 0, end: 1 } }
 }
 
 fn a(x: Foo<'_>) { }
@@ -82,7 +82,7 @@ struct St<'a> {
     x: &'a u32,
 }
 
-fn f() { { let _ = St{ x: &0,}; }; { let _ = St{ x: &0,}; }; }
+fn f() { { let _ = St { x: &0 }; }; { let _ = St { x: &0 }; }; }
 
 struct Name<'a>(&'a str);
 
diff --git a/tests/pretty/hir-struct-expr.pp b/tests/pretty/hir-struct-expr.pp
new file mode 100644
index 00000000000..f85d17542df
--- /dev/null
+++ b/tests/pretty/hir-struct-expr.pp
@@ -0,0 +1,28 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+//@ pretty-compare-only
+//@ pretty-mode:hir
+//@ pp-exact:hir-struct-expr.pp
+
+struct StructWithSomeFields {
+    field_1: i32,
+    field_2: i32,
+    field_3: i32,
+    field_4: i32,
+    field_5: i32,
+    field_6: i32,
+}
+
+fn main() {
+    let a =
+        StructWithSomeFields {
+            field_1: 1,
+            field_2: 2,
+            field_3: 3,
+            field_4: 4,
+            field_5: 5,
+            field_6: 6 };
+    let a = StructWithSomeFields { field_1: 1, field_2: 2, ..a };
+}
diff --git a/tests/pretty/hir-struct-expr.rs b/tests/pretty/hir-struct-expr.rs
new file mode 100644
index 00000000000..9580f5d557d
--- /dev/null
+++ b/tests/pretty/hir-struct-expr.rs
@@ -0,0 +1,24 @@
+//@ pretty-compare-only
+//@ pretty-mode:hir
+//@ pp-exact:hir-struct-expr.pp
+
+struct StructWithSomeFields {
+    field_1: i32,
+    field_2: i32,
+    field_3: i32,
+    field_4: i32,
+    field_5: i32,
+    field_6: i32,
+}
+
+fn main() {
+    let a = StructWithSomeFields {
+        field_1: 1,
+        field_2: 2,
+        field_3: 3,
+        field_4: 4,
+        field_5: 5,
+        field_6: 6,
+    };
+    let a = StructWithSomeFields { field_1: 1, field_2: 2, ..a };
+}
diff --git a/tests/pretty/stmt_expr_attributes.rs b/tests/pretty/stmt_expr_attributes.rs
index 01a503ce7ee..90d2b2f5e1e 100644
--- a/tests/pretty/stmt_expr_attributes.rs
+++ b/tests/pretty/stmt_expr_attributes.rs
@@ -1,6 +1,5 @@
 //@ pp-exact
 
-#![feature(inline_const_pat)]
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
 
@@ -206,9 +205,7 @@ fn _11() {
             let _ = ();
             ()
         };
-    let const {
-                    #![rustc_dummy]
-                } =
+    let _ =
         #[rustc_dummy] const {
                 #![rustc_dummy]
             };
diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
index 024ce975cd6..ba887b3d791 100644
--- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
+++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
@@ -3,10 +3,10 @@
 // Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current
 // `rustc` version and the `since` property in feature stability gating is properly respected.
 
-use run_make_support::{aux_build, rfs, rustc, source_root};
+use run_make_support::{rfs, rustc, source_root};
 
 fn main() {
-    aux_build().input("stable.rs").emit("metadata").run();
+    rustc().crate_type("lib").input("stable.rs").emit("metadata").run();
 
     let output =
         rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run();
diff --git a/tests/run-make/apple-slow-tls/rmake.rs b/tests/run-make/apple-slow-tls/rmake.rs
new file mode 100644
index 00000000000..231e0b1668e
--- /dev/null
+++ b/tests/run-make/apple-slow-tls/rmake.rs
@@ -0,0 +1,37 @@
+//! Test if compilation with has-thread-local=false works, and if the output
+//! has indeed no fast TLS variables.
+
+//@ only-apple
+
+use run_make_support::serde_json::{self, Value};
+use run_make_support::{cargo, llvm_nm, rfs, rustc};
+
+fn main() {
+    let output =
+        rustc().print("target-spec-json").args(["-Z", "unstable-options"]).run().stdout_utf8();
+
+    let mut target_json: Value = serde_json::from_str(&output).unwrap();
+    let has_thread_local = &mut target_json["has-thread-local"];
+    assert!(matches!(has_thread_local, Value::Bool(true)), "{:?}", has_thread_local);
+    *has_thread_local = Value::Bool(false);
+
+    let out_path = "t.json";
+    rfs::write(out_path, serde_json::to_string(&target_json).unwrap());
+
+    cargo()
+        .args([
+            "b",
+            "--manifest-path",
+            "tls_test/Cargo.toml",
+            "--target",
+            "t.json",
+            "-Zbuild-std=std,core,panic_abort",
+        ])
+        .run();
+
+    // If a binary has any fast TLS variables, it should also contain the symbols
+    // __tlv_bootstrap and __tlv_atexit. We don't want them.
+    let output = llvm_nm().arg("tls_test/target/t/debug/tls_test").run().stdout_utf8();
+    assert!(!output.contains("_tlv_bootstrap"));
+    assert!(!output.contains("_tlv_atexit"));
+}
diff --git a/tests/run-make/apple-slow-tls/tls_test/Cargo.toml b/tests/run-make/apple-slow-tls/tls_test/Cargo.toml
new file mode 100644
index 00000000000..c8e5a228eef
--- /dev/null
+++ b/tests/run-make/apple-slow-tls/tls_test/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "tls_test"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
diff --git a/tests/run-make/apple-slow-tls/tls_test/src/main.rs b/tests/run-make/apple-slow-tls/tls_test/src/main.rs
new file mode 100644
index 00000000000..d48d22bb3d1
--- /dev/null
+++ b/tests/run-make/apple-slow-tls/tls_test/src/main.rs
@@ -0,0 +1,10 @@
+use std::cell::RefCell;
+
+fn main() {
+    thread_local! {
+        static S: RefCell<String> = RefCell::default();
+    }
+
+    S.with(|x| *x.borrow_mut() = "pika pika".to_string());
+    S.with(|x| println!("{}", x.borrow()));
+}
diff --git a/tests/run-make/embed-metadata/dep1.rs b/tests/run-make/embed-metadata/dep1.rs
new file mode 100644
index 00000000000..be70c3933e0
--- /dev/null
+++ b/tests/run-make/embed-metadata/dep1.rs
@@ -0,0 +1 @@
+pub fn func_dep1() {}
diff --git a/tests/run-make/embed-metadata/foo.rs b/tests/run-make/embed-metadata/foo.rs
new file mode 100644
index 00000000000..0cc9cede860
--- /dev/null
+++ b/tests/run-make/embed-metadata/foo.rs
@@ -0,0 +1,5 @@
+extern crate dep1;
+
+fn main() {
+    dep1::func_dep1();
+}
diff --git a/tests/run-make/embed-metadata/rmake.rs b/tests/run-make/embed-metadata/rmake.rs
new file mode 100644
index 00000000000..acefb186484
--- /dev/null
+++ b/tests/run-make/embed-metadata/rmake.rs
@@ -0,0 +1,86 @@
+// Tests the -Zembed-metadata compiler flag.
+// Tracking issue: https://github.com/rust-lang/rust/issues/139165
+
+use run_make_support::rfs::{create_dir, remove_file, rename};
+use run_make_support::{Rustc, dynamic_lib_name, path, run_in_tmpdir, rust_lib_name, rustc};
+
+#[derive(Debug, Copy, Clone)]
+enum LibraryKind {
+    Rlib,
+    Dylib,
+}
+
+impl LibraryKind {
+    fn crate_type(&self) -> &str {
+        match self {
+            LibraryKind::Rlib => "rlib",
+            LibraryKind::Dylib => "dylib",
+        }
+    }
+
+    fn add_extern(&self, rustc: &mut Rustc, dep_name: &str, dep_path: &str) {
+        let dep_path = match self {
+            LibraryKind::Dylib => format!("{dep_path}/{}", dynamic_lib_name(dep_name)),
+            LibraryKind::Rlib => format!("{dep_path}/{}", rust_lib_name(dep_name)),
+        };
+        rustc.extern_(dep_name, dep_path);
+    }
+}
+
+fn main() {
+    // The compiler takes different paths based on if --extern is passed or not, so we test all
+    // combinations (`rlib`/`dylib` x `--extern`/`no --extern`).
+    for kind in [LibraryKind::Rlib, LibraryKind::Dylib] {
+        eprintln!("Testing library kind {kind:?}");
+        lookup_rmeta_in_lib_dir(kind);
+        lookup_rmeta_through_extern(kind);
+        lookup_rmeta_missing(kind);
+    }
+}
+
+// Lookup .rmeta file in the same directory as a rlib/dylib with stub metadata.
+fn lookup_rmeta_in_lib_dir(kind: LibraryKind) {
+    run_in_tmpdir(|| {
+        build_dep_rustc(kind).run();
+        rustc().input("foo.rs").run();
+    });
+}
+
+// Lookup .rmeta file when specifying the dependency using --extern.
+fn lookup_rmeta_through_extern(kind: LibraryKind) {
+    run_in_tmpdir(|| {
+        // Generate libdep1.rlib and libdep1.rmeta in deps
+        create_dir("deps");
+        build_dep_rustc(kind).out_dir("deps").run();
+
+        let mut rustc = rustc();
+        kind.add_extern(&mut rustc, "dep1", "deps");
+        rustc.extern_("dep1", path("deps").join("libdep1.rmeta"));
+        rustc.input("foo.rs").run();
+    });
+}
+
+// Check the error message when the .rmeta file is missing.
+fn lookup_rmeta_missing(kind: LibraryKind) {
+    run_in_tmpdir(|| {
+        create_dir("deps");
+        build_dep_rustc(kind).out_dir("deps").run();
+
+        let mut rustc = rustc();
+        kind.add_extern(&mut rustc, "dep1", "deps");
+        rustc.input("foo.rs").run_fail().assert_stderr_contains("only metadata stub found");
+    });
+}
+
+fn build_dep_rustc(kind: LibraryKind) -> Rustc {
+    let mut dep_rustc = rustc();
+    dep_rustc
+        .arg("-Zembed-metadata=no")
+        .crate_type(kind.crate_type())
+        .input("dep1.rs")
+        .emit("metadata,link");
+    if matches!(kind, LibraryKind::Dylib) {
+        dep_rustc.arg("-Cprefer-dynamic");
+    }
+    dep_rustc
+}
diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs
index 228cfb0864e..87d4faaa77a 100644
--- a/tests/run-make/issue-107495-archive-permissions/rmake.rs
+++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs
@@ -4,7 +4,7 @@ use std::path::Path;
 
 #[cfg(unix)]
 use run_make_support::libc;
-use run_make_support::{aux_build, rfs};
+use run_make_support::{rfs, rustc};
 
 fn main() {
     #[cfg(unix)]
@@ -12,7 +12,7 @@ fn main() {
         libc::umask(0o002);
     }
 
-    aux_build().arg("foo.rs").run();
+    rustc().crate_type("lib").arg("foo.rs").run();
     verify(Path::new("libfoo.rlib"));
 }
 
diff --git a/tests/run-make/print-crate-root-lint-levels/lib.rs b/tests/run-make/print-crate-root-lint-levels/lib.rs
new file mode 100644
index 00000000000..dc846f8fd95
--- /dev/null
+++ b/tests/run-make/print-crate-root-lint-levels/lib.rs
@@ -0,0 +1,5 @@
+#![allow(unexpected_cfgs)]
+#![expect(unused_mut)]
+
+#[deny(unknown_lints)]
+mod my_mod {}
diff --git a/tests/run-make/print-crate-root-lint-levels/rmake.rs b/tests/run-make/print-crate-root-lint-levels/rmake.rs
new file mode 100644
index 00000000000..e373c91102d
--- /dev/null
+++ b/tests/run-make/print-crate-root-lint-levels/rmake.rs
@@ -0,0 +1,118 @@
+//! This checks the output of `--print=crate-root-lint-levels`
+
+extern crate run_make_support;
+
+use std::collections::HashSet;
+use std::iter::FromIterator;
+
+use run_make_support::rustc;
+
+struct CrateRootLintLevels {
+    args: &'static [&'static str],
+    contains: Contains,
+}
+
+struct Contains {
+    contains: &'static [&'static str],
+    doesnt_contain: &'static [&'static str],
+}
+
+fn main() {
+    check(CrateRootLintLevels {
+        args: &[],
+        contains: Contains {
+            contains: &[
+                "unexpected_cfgs=allow",
+                "unused_mut=expect",
+                "warnings=warn",
+                "stable_features=warn",
+                "unknown_lints=warn",
+            ],
+            doesnt_contain: &["unexpected_cfgs=warn", "unused_mut=warn"],
+        },
+    });
+    check(CrateRootLintLevels {
+        args: &["-Wunexpected_cfgs"],
+        contains: Contains {
+            contains: &["unexpected_cfgs=allow", "warnings=warn"],
+            doesnt_contain: &["unexpected_cfgs=warn"],
+        },
+    });
+    check(CrateRootLintLevels {
+        args: &["-Dwarnings"],
+        contains: Contains {
+            contains: &[
+                "unexpected_cfgs=allow",
+                "warnings=deny",
+                "stable_features=deny",
+                "unknown_lints=deny",
+            ],
+            doesnt_contain: &["warnings=warn"],
+        },
+    });
+    check(CrateRootLintLevels {
+        args: &["-Dstable_features"],
+        contains: Contains {
+            contains: &["warnings=warn", "stable_features=deny", "unexpected_cfgs=allow"],
+            doesnt_contain: &["warnings=deny"],
+        },
+    });
+    check(CrateRootLintLevels {
+        args: &["-Dwarnings", "--force-warn=stable_features"],
+        contains: Contains {
+            contains: &["warnings=deny", "stable_features=force-warn", "unknown_lints=deny"],
+            doesnt_contain: &["warnings=warn"],
+        },
+    });
+    check(CrateRootLintLevels {
+        args: &["-Dwarnings", "--cap-lints=warn"],
+        contains: Contains {
+            contains: &[
+                "unexpected_cfgs=allow",
+                "warnings=warn",
+                "stable_features=warn",
+                "unknown_lints=warn",
+            ],
+            doesnt_contain: &["warnings=deny"],
+        },
+    });
+}
+
+#[track_caller]
+fn check(CrateRootLintLevels { args, contains }: CrateRootLintLevels) {
+    let output = rustc()
+        .input("lib.rs")
+        .arg("-Zunstable-options")
+        .print("crate-root-lint-levels")
+        .args(args)
+        .run();
+
+    let stdout = output.stdout_utf8();
+
+    let mut found = HashSet::<String>::new();
+
+    for l in stdout.lines() {
+        assert!(l == l.trim());
+        if let Some((left, right)) = l.split_once('=') {
+            assert!(!left.contains("\""));
+            assert!(!right.contains("\""));
+        } else {
+            assert!(l.contains('='));
+        }
+        assert!(found.insert(l.to_string()), "{}", &l);
+    }
+
+    let Contains { contains, doesnt_contain } = contains;
+
+    {
+        let should_found = HashSet::<String>::from_iter(contains.iter().map(|s| s.to_string()));
+        let diff: Vec<_> = should_found.difference(&found).collect();
+        assert!(diff.is_empty(), "should found: {:?}, didn't found {:?}", &should_found, &diff);
+    }
+    {
+        let should_not_find =
+            HashSet::<String>::from_iter(doesnt_contain.iter().map(|s| s.to_string()));
+        let diff: Vec<_> = should_not_find.intersection(&found).collect();
+        assert!(diff.is_empty(), "should not find {:?}, did found {:?}", &should_not_find, &diff);
+    }
+}
diff --git a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
index 263bb9b2e20..9a08991c4b8 100644
--- a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
+++ b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
@@ -4,24 +4,11 @@
 //@ ignore-nightly
 //@ only-x86_64-unknown-linux-gnu
 
-use std::process::Output;
-
-use run_make_support::regex::Regex;
+use run_make_support::linker::assert_rustc_doesnt_use_lld;
 use run_make_support::rustc;
 
 fn main() {
     // A regular compilation should not use rust-lld by default. We'll check that by asking the
     // linker to display its version number with a link-arg.
-    let output = rustc().arg("-Wlinker-messages").link_arg("-Wl,-v").input("main.rs").run();
-    assert!(
-        !find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should not be present in the output logs:\n{}",
-        output.stderr_utf8()
-    );
-}
-
-fn find_lld_version_in_logs(stderr: String) -> bool {
-    let lld_version_re =
-        Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
-    stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
+    assert_rustc_doesnt_use_lld(rustc().input("main.rs"));
 }
diff --git a/tests/run-make/rust-lld-by-default-nightly/rmake.rs b/tests/run-make/rust-lld-by-default-nightly/rmake.rs
index 7a0a08863dd..3ff1e2770e6 100644
--- a/tests/run-make/rust-lld-by-default-nightly/rmake.rs
+++ b/tests/run-make/rust-lld-by-default-nightly/rmake.rs
@@ -6,35 +6,14 @@
 //@ ignore-stable
 //@ only-x86_64-unknown-linux-gnu
 
-use run_make_support::regex::Regex;
+use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
 use run_make_support::rustc;
 
 fn main() {
     // A regular compilation should use rust-lld by default. We'll check that by asking the linker
     // to display its version number with a link-arg.
-    let output = rustc().arg("-Wlinker-messages").link_arg("-Wl,-v").input("main.rs").run();
-    assert!(
-        find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should be present in the output logs:\n{}",
-        output.stderr_utf8()
-    );
+    assert_rustc_uses_lld(rustc().input("main.rs"));
 
     // But it can still be disabled by turning the linker feature off.
-    let output = rustc()
-        .arg("-Wlinker-messages")
-        .link_arg("-Wl,-v")
-        .arg("-Zlinker-features=-lld")
-        .input("main.rs")
-        .run();
-    assert!(
-        !find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should not be present in the output logs:\n{}",
-        output.stderr_utf8()
-    );
-}
-
-fn find_lld_version_in_logs(stderr: String) -> bool {
-    let lld_version_re =
-        Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
-    stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
+    assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
 }
diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs
index 993a248ad00..e2b065a10b1 100644
--- a/tests/run-make/rust-lld-custom-target/rmake.rs
+++ b/tests/run-make/rust-lld-custom-target/rmake.rs
@@ -8,43 +8,22 @@
 //@ needs-rust-lld
 //@ only-x86_64-unknown-linux-gnu
 
-use run_make_support::regex::Regex;
+use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
 use run_make_support::rustc;
 
 fn main() {
     // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking
     // the linker to display its version number with a link-arg.
-    let output = rustc()
-        .crate_type("cdylib")
-        .arg("-Wlinker-messages")
-        .target("custom-target.json")
-        .link_arg("-Wl,-v")
-        .input("lib.rs")
-        .run();
-    assert!(
-        find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should be present in the output logs:\n{}",
-        output.stderr_utf8()
+    assert_rustc_uses_lld(
+        rustc().crate_type("cdylib").target("custom-target.json").input("lib.rs"),
     );
 
     // But it can also be disabled via linker features.
-    let output = rustc()
-        .crate_type("cdylib")
-        .arg("-Wlinker-messages")
-        .target("custom-target.json")
-        .arg("-Zlinker-features=-lld")
-        .link_arg("-Wl,-v")
-        .input("lib.rs")
-        .run();
-    assert!(
-        !find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should not be present in the output logs:\n{}",
-        output.stderr_utf8()
+    assert_rustc_doesnt_use_lld(
+        rustc()
+            .crate_type("cdylib")
+            .target("custom-target.json")
+            .arg("-Zlinker-features=-lld")
+            .input("lib.rs"),
     );
 }
-
-fn find_lld_version_in_logs(stderr: String) -> bool {
-    let lld_version_re =
-        Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
-    stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
-}
diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs
index 35f716c24c7..9470f5d0be1 100644
--- a/tests/run-make/rust-lld/rmake.rs
+++ b/tests/run-make/rust-lld/rmake.rs
@@ -4,64 +4,32 @@
 //@ needs-rust-lld
 //@ ignore-s390x lld does not yet support s390x as target
 
-use run_make_support::regex::Regex;
-use run_make_support::{is_msvc, rustc};
+use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
+use run_make_support::rustc;
 
 fn main() {
-    // lld-link is used if msvc, otherwise a gnu-compatible lld is used.
-    let linker_version_flag = if is_msvc() { "--version" } else { "-Wl,-v" };
-
     // Opt-in to lld and the self-contained linker, to link with rust-lld. We'll check that by
     // asking the linker to display its version number with a link-arg.
-    let output = rustc()
-        .arg("-Zlinker-features=+lld")
-        .arg("-Clink-self-contained=+linker")
-        .arg("-Zunstable-options")
-        .arg("-Wlinker-messages")
-        .link_arg(linker_version_flag)
-        .input("main.rs")
-        .run();
-    assert!(
-        find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should be present in the output logs:\n{}",
-        output.stderr_utf8()
+    assert_rustc_uses_lld(
+        rustc()
+            .arg("-Zlinker-features=+lld")
+            .arg("-Clink-self-contained=+linker")
+            .arg("-Zunstable-options")
+            .input("main.rs"),
     );
 
-    // It should not be used when we explicitly opt-out of lld.
-    let output = rustc()
-        .link_arg(linker_version_flag)
-        .arg("-Zlinker-features=-lld")
-        .arg("-Wlinker-messages")
-        .input("main.rs")
-        .run();
-    assert!(
-        !find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should not be present in the output logs:\n{}",
-        output.stderr_utf8()
-    );
+    // It should not be used when we explicitly opt out of lld.
+    assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
 
     // While we're here, also check that the last linker feature flag "wins" when passed multiple
     // times to rustc.
-    let output = rustc()
-        .link_arg(linker_version_flag)
-        .arg("-Clink-self-contained=+linker")
-        .arg("-Zunstable-options")
-        .arg("-Zlinker-features=-lld")
-        .arg("-Zlinker-features=+lld")
-        .arg("-Zlinker-features=-lld,+lld")
-        .arg("-Wlinker-messages")
-        .input("main.rs")
-        .run();
-    assert!(
-        find_lld_version_in_logs(output.stderr_utf8()),
-        "the LLD version string should be present in the output logs:\n{}",
-        output.stderr_utf8()
+    assert_rustc_uses_lld(
+        rustc()
+            .arg("-Clink-self-contained=+linker")
+            .arg("-Zunstable-options")
+            .arg("-Zlinker-features=-lld")
+            .arg("-Zlinker-features=+lld")
+            .arg("-Zlinker-features=-lld,+lld")
+            .input("main.rs"),
     );
 }
-
-fn find_lld_version_in_logs(stderr: String) -> bool {
-    // Strip the `-Wlinker-messages` wrappers prefixing the linker output.
-    let stderr = Regex::new(r"warning: linker std(out|err):").unwrap().replace_all(&stderr, "");
-    let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
-    stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
-}
diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout
index 98e56735082..f19ca1e9f90 100644
--- a/tests/run-make/rustc-help/help-v.stdout
+++ b/tests/run-make/rustc-help/help-v.stdout
@@ -29,7 +29,7 @@ Options:
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
-        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
+        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                         Compiler information to print on stdout
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout
index 040555f1d04..f7d35296603 100644
--- a/tests/run-make/rustc-help/help.stdout
+++ b/tests/run-make/rustc-help/help.stdout
@@ -29,7 +29,7 @@ Options:
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
-        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
+        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                         Compiler information to print on stdout
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
diff --git a/tests/run-make/rustdoc-error-lines/rmake.rs b/tests/run-make/rustdoc-error-lines/rmake.rs
index ea5ec2faed9..0d8c500ed1e 100644
--- a/tests/run-make/rustdoc-error-lines/rmake.rs
+++ b/tests/run-make/rustdoc-error-lines/rmake.rs
@@ -8,11 +8,11 @@ fn main() {
 
     let should_contain = &[
         "input.rs - foo (line 5)",
-        "input.rs:7:15",
+        "input.rs:8:15",
         "input.rs - bar (line 13)",
-        "input.rs:15:15",
+        "input.rs:16:15",
         "input.rs - bar (line 22)",
-        "input.rs:24:15",
+        "input.rs:25:15",
     ];
     for text in should_contain {
         assert!(output.contains(text), "output doesn't contains {:?}", text);
diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs
index f36a5784c89..9184e5f772f 100644
--- a/tests/run-make/target-specs/rmake.rs
+++ b/tests/run-make/target-specs/rmake.rs
@@ -14,7 +14,7 @@ fn main() {
         .input("foo.rs")
         .target("my-invalid-platform.json")
         .run_fail()
-        .assert_stderr_contains("Error loading target specification");
+        .assert_stderr_contains("error loading target specification");
     rustc()
         .input("foo.rs")
         .target("my-incomplete-platform.json")
diff --git a/tests/rustdoc-json/attrs/automatically_derived.rs b/tests/rustdoc-json/attrs/automatically_derived.rs
new file mode 100644
index 00000000000..4e1ab3d145e
--- /dev/null
+++ b/tests/rustdoc-json/attrs/automatically_derived.rs
@@ -0,0 +1,13 @@
+#[derive(Default)]
+pub struct Derive;
+
+pub struct Manual;
+
+impl Default for Manual {
+    fn default() -> Self {
+        Self
+    }
+}
+
+//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]"]'
+//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Manual" && @.inner.impl.trait.path == "Default")].attrs' '[]'
diff --git a/tests/rustdoc-ui/doctest/display-output.stdout b/tests/rustdoc-ui/doctest/display-output.stdout
index ad25d1ce541..45e107b2c70 100644
--- a/tests/rustdoc-ui/doctest/display-output.stdout
+++ b/tests/rustdoc-ui/doctest/display-output.stdout
@@ -6,7 +6,7 @@ successes:
 
 ---- $DIR/display-output.rs - foo (line 9) stdout ----
 warning: unused variable: `x`
-  --> $DIR/display-output.rs:11:5
+  --> $DIR/display-output.rs:12:5
    |
 LL | let x = 12;
    |     ^ help: if this is intentional, prefix it with an underscore: `_x`
@@ -19,13 +19,13 @@ LL | #![warn(unused)]
    = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
 
 warning: unused variable: `x`
-  --> $DIR/display-output.rs:13:8
+  --> $DIR/display-output.rs:14:8
    |
 LL | fn foo(x: &dyn std::fmt::Display) {}
    |        ^ help: if this is intentional, prefix it with an underscore: `_x`
 
 warning: function `foo` is never used
-  --> $DIR/display-output.rs:13:4
+  --> $DIR/display-output.rs:14:4
    |
 LL | fn foo(x: &dyn std::fmt::Display) {}
    |    ^^^
diff --git a/tests/rustdoc-ui/doctest/edition-2024-error-output.rs b/tests/rustdoc-ui/doctest/edition-2024-error-output.rs
new file mode 100644
index 00000000000..82a85debcd1
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/edition-2024-error-output.rs
@@ -0,0 +1,14 @@
+// This is a regression test for <https://github.com/rust-lang/rust/issues/137970>.
+// The output must look nice and not like a `Debug` display of a `String`.
+
+//@ edition: 2024
+//@ compile-flags: --test
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "panicked at .+rs:" -> "panicked at $$TMP:"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ rustc-env:RUST_BACKTRACE=0
+//@ failure-status: 101
+
+//! ```rust
+//! assert_eq!(2 + 2, 5);
+//! ```
diff --git a/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout
new file mode 100644
index 00000000000..8f056a5f703
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout
@@ -0,0 +1,20 @@
+
+running 1 test
+test $DIR/edition-2024-error-output.rs - (line 12) ... FAILED
+
+failures:
+
+---- $DIR/edition-2024-error-output.rs - (line 12) stdout ----
+
+thread 'main' panicked at $TMP:6:1:
+assertion `left == right` failed
+  left: 4
+ right: 5
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+
+
+failures:
+    $DIR/edition-2024-error-output.rs - (line 12)
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/extern-crate.rs b/tests/rustdoc-ui/doctest/extern-crate.rs
new file mode 100644
index 00000000000..0415d33bb72
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/extern-crate.rs
@@ -0,0 +1,23 @@
+//@ check-pass
+//@ compile-flags:--test --test-args=--test-threads=1
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+
+// This test ensures that crate imports are placed outside of the `main` function
+// so they work all the time (even in 2015 edition).
+
+/// ```rust
+/// #![feature(test)]
+///
+/// extern crate test;
+/// use test::Bencher;
+///
+/// #[bench]
+/// fn bench_xor_1000_ints(b: &mut Bencher) {
+///     b.iter(|| {
+///         (0..1000).fold(0, |old, new| old ^ new);
+///     });
+/// }
+/// ```
+///
+pub fn foo() {}
diff --git a/tests/rustdoc-ui/doctest/extern-crate.stdout b/tests/rustdoc-ui/doctest/extern-crate.stdout
new file mode 100644
index 00000000000..b103343afdd
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/extern-crate.stdout
@@ -0,0 +1,6 @@
+
+running 1 test
+test $DIR/extern-crate.rs - foo (line 9) ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/no-run-flag-error.rs b/tests/rustdoc-ui/doctest/no-run-flag-error.rs
index 896d7729b8d..3f9016b23db 100644
--- a/tests/rustdoc-ui/doctest/no-run-flag-error.rs
+++ b/tests/rustdoc-ui/doctest/no-run-flag-error.rs
@@ -1,6 +1,7 @@
 // test the behavior of the --no-run flag without the --test flag
 
 //@ compile-flags:-Z unstable-options --no-run --test-args=--test-threads=1
-//@ error-pattern: the `--test` flag must be passed
 
 pub fn f() {}
+
+//~? ERROR the `--test` flag must be passed to enable `--no-run`
diff --git a/tests/rustdoc-ui/extract-doctests.stdout b/tests/rustdoc-ui/extract-doctests.stdout
index fa8604cae94..b11531b844e 100644
--- a/tests/rustdoc-ui/extract-doctests.stdout
+++ b/tests/rustdoc-ui/extract-doctests.stdout
@@ -1 +1 @@
-{"format_version":1,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":"#![allow(unused)]\nfn main() {\nlet x = 12;\nlet y = 14;\n}","name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":"#![allow(unused)]\nfn main() {\nlet\n}","name":"$DIR/extract-doctests.rs - (line 13)"}]}
\ No newline at end of file
+{"format_version":1,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":"#![allow(unused)]\nfn main() {\nlet x = 12;\nlet y = 14;\n}","name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":null,"name":"$DIR/extract-doctests.rs - (line 13)"}]}
\ No newline at end of file
diff --git a/tests/rustdoc-ui/invalid-theme-name.rs b/tests/rustdoc-ui/invalid-theme-name.rs
index d632a08ebc8..7f1d191c89d 100644
--- a/tests/rustdoc-ui/invalid-theme-name.rs
+++ b/tests/rustdoc-ui/invalid-theme-name.rs
@@ -1,3 +1,4 @@
 //@ compile-flags:--theme {{src-base}}/invalid-theme-name.rs
-//@ error-pattern: invalid argument
 //@ error-pattern: must have a .css extension
+
+//~? ERROR invalid argument: "$DIR/invalid-theme-name.rs"
diff --git a/tests/rustdoc-ui/issues/issue-91713.rs b/tests/rustdoc-ui/issues/issue-91713.rs
index 9875b5d4ad6..68240726007 100644
--- a/tests/rustdoc-ui/issues/issue-91713.rs
+++ b/tests/rustdoc-ui/issues/issue-91713.rs
@@ -1,3 +1,4 @@
 //@ check-pass
 //@ compile-flags: --passes list
-//@ error-pattern: the `passes` flag no longer functions
+
+//~? WARN the `passes` flag no longer functions
diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs
index 6e631061e8a..5e7dc377f5d 100644
--- a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs
+++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs
@@ -1,6 +1,7 @@
-//@ error-pattern: no documentation found
 //@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
 #![deny(rustdoc::missing_crate_level_docs)]
 //^~ NOTE defined here
 
 pub fn foo() {}
+
+//~? ERROR no documentation found for this crate's top-level module
diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr
index 3a748335ea8..721d3662c93 100644
--- a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr
+++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr
@@ -3,7 +3,7 @@ error: no documentation found for this crate's top-level module
    = help: The following guide may be of use:
            https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
 note: the lint level is defined here
-  --> $DIR/no-crate-level-doc-lint.rs:3:9
+  --> $DIR/no-crate-level-doc-lint.rs:2:9
    |
 LL | #![deny(rustdoc::missing_crate_level_docs)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout
index a05b5169989..c0d2515998f 100644
--- a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout
+++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout
@@ -5,11 +5,11 @@ test remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) .
 failures:
 
 ---- remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) stdout ----
-error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `is`
+error: expected one of `!` or `::`, found `is`
   --> remapped_path/remap-path-prefix-invalid-doctest.rs:11:6
    |
 LL | this is not real code
-   |      ^^ expected one of 8 possible tokens
+   |      ^^ expected one of `!` or `::`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs
index 27781f47e0d..d18d26bf794 100644
--- a/tests/rustdoc-ui/track-diagnostics.rs
+++ b/tests/rustdoc-ui/track-diagnostics.rs
@@ -8,4 +8,4 @@
 struct A;
 struct B;
 
-pub const S: A = B;
+pub const S: A = B; //~ ERROR mismatched types
diff --git a/tests/rustdoc/playground.rs b/tests/rustdoc/playground.rs
index db2d1669df6..65dad2a5195 100644
--- a/tests/rustdoc/playground.rs
+++ b/tests/rustdoc/playground.rs
@@ -24,4 +24,4 @@
 
 //@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' ""
 //@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' ""
-//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&version=nightly&edition=2015"]' ""
+//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0A%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&version=nightly&edition=2015"]' ""
diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.rs b/tests/ui-fulldeps/missing-rustc-driver-error.rs
index 03ab5ce7b25..d582efada90 100644
--- a/tests/ui-fulldeps/missing-rustc-driver-error.rs
+++ b/tests/ui-fulldeps/missing-rustc-driver-error.rs
@@ -1,6 +1,6 @@
 // Test that we get the following hint when trying to use a compiler crate without rustc_driver.
 //@ error-pattern: try adding `extern crate rustc_driver;` at the top level of this crate
-//@ compile-flags: --emit link
+//@ compile-flags: --emit link --error-format=human
 //@ normalize-stderr: ".*crate .* required.*\n\n" -> ""
 //@ normalize-stderr: "aborting due to [0-9]+" -> "aborting due to NUMBER"
 
diff --git a/tests/ui-fulldeps/stable-mir/check_assoc_items.rs b/tests/ui-fulldeps/stable-mir/check_assoc_items.rs
new file mode 100644
index 00000000000..f6f895588f2
--- /dev/null
+++ b/tests/ui-fulldeps/stable-mir/check_assoc_items.rs
@@ -0,0 +1,145 @@
+//@ run-pass
+//! Test that users are able to retrieve all associated items from a definition.
+//! definition.
+
+//@ ignore-stage1
+//@ ignore-cross-compile
+//@ ignore-remote
+//@ edition: 2021
+
+#![feature(rustc_private)]
+#![feature(assert_matches)]
+
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_smir;
+extern crate rustc_driver;
+extern crate rustc_interface;
+extern crate stable_mir;
+
+use rustc_smir::rustc_internal;
+use std::io::Write;
+use std::collections::HashSet;
+use stable_mir::CrateDef;
+use stable_mir::*;
+use stable_mir::ty::*;
+use std::ops::ControlFlow;
+
+const CRATE_NAME: &str = "crate_assoc_items";
+
+/// This function uses the Stable MIR APIs to get information about the test crate.
+fn test_assoc_items() -> ControlFlow<()> {
+    let local_crate = stable_mir::local_crate();
+    check_items(
+        &local_crate.fn_defs(),
+        &[
+            "AStruct::new",
+            "<AStruct as ATrait>::assoc_fn_no_self",
+            "<AStruct as ATrait>::assoc_fn_has_self",
+            "ATrait::rpitit",
+            "ATrait::assoc_fn_has_self",
+            "ATrait::assoc_fn_no_self",
+            "<AStruct as ATrait>::rpitit",
+        ],
+    );
+
+    let local_impls = local_crate.trait_impls();
+    let local_traits = local_crate.trait_decls();
+
+    let trait_assoc_item_defs: Vec<AssocDef> = local_traits[0].associated_items()
+        .iter().map(|assoc_item| assoc_item.def_id).collect();
+    check_items(
+        &trait_assoc_item_defs,
+        &[
+            "ATrait::{synthetic#0}",
+            "ATrait::rpitit",
+            "ATrait::Assoc",
+            "ATrait::assoc_fn_no_self",
+            "ATrait::assoc_fn_has_self",
+        ]
+    );
+
+    let impl_assoc_item_defs: Vec<AssocDef> = local_impls[0].associated_items()
+        .iter().map(|assoc_item| assoc_item.def_id).collect();
+    check_items(
+        &impl_assoc_item_defs,
+        &[
+            "<AStruct as ATrait>::{synthetic#0}",
+            "<AStruct as ATrait>::rpitit",
+            "<AStruct as ATrait>::Assoc",
+            "<AStruct as ATrait>::assoc_fn_no_self",
+            "<AStruct as ATrait>::assoc_fn_has_self",
+        ]
+    );
+
+    ControlFlow::Continue(())
+}
+
+/// Check if the list of definitions matches the expected list.
+/// Note that order doesn't matter.
+fn check_items<T: CrateDef>(items: &[T], expected: &[&str]) {
+    let expected: HashSet<_> = expected.iter().map(|s| s.to_string()).collect();
+    let item_names: HashSet<_> = items.iter().map(|item| item.name()).collect();
+    assert_eq!(item_names, expected);
+}
+
+fn main() {
+    let path = "assoc_items.rs";
+    generate_input(&path).unwrap();
+    let args = vec![
+        "rustc".to_string(),
+        "--crate-type=lib".to_string(),
+        "--crate-name".to_string(),
+        CRATE_NAME.to_string(),
+        path.to_string(),
+    ];
+    run!(args, test_assoc_items).unwrap();
+}
+
+fn generate_input(path: &str) -> std::io::Result<()> {
+    let mut file = std::fs::File::create(path)?;
+    write!(
+        file,
+        r#"
+        #![allow(dead_code, unused_variables)]
+        struct AStruct;
+
+        impl AStruct {{
+            const ASSOC_CONST: &str = "Nina";
+
+            fn new() -> Self {{
+                AStruct{{}}
+            }}
+        }}
+
+        trait ATrait {{
+            type Assoc;
+
+            fn assoc_fn_no_self() {{
+            }}
+
+            fn assoc_fn_has_self(&self) {{
+            }}
+
+            fn rpitit(&self) -> impl std::fmt::Debug {{
+                "ciallo"
+            }}
+        }}
+
+        impl ATrait for AStruct {{
+            type Assoc = u32;
+
+            fn assoc_fn_no_self() {{
+            }}
+
+            fn assoc_fn_has_self(&self) {{
+            }}
+
+            fn rpitit(&self) -> impl std::fmt::Debug {{
+                "ciallo~"
+            }}
+        }}
+    "#
+    )?;
+    Ok(())
+}
diff --git a/tests/ui/abi/fixed_x18.rs b/tests/ui/abi/fixed_x18.rs
index f1ff3e1d534..d373468f68f 100644
--- a/tests/ui/abi/fixed_x18.rs
+++ b/tests/ui/abi/fixed_x18.rs
@@ -23,3 +23,5 @@
 
 #[lang = "sized"]
 trait Sized {}
+
+//~? ERROR the `-Zfixed-x18` flag is not supported on the `
diff --git a/tests/ui/abi/large-byval-align.rs b/tests/ui/abi/large-byval-align.rs
index ddd579f264e..c1de841178f 100644
--- a/tests/ui/abi/large-byval-align.rs
+++ b/tests/ui/abi/large-byval-align.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -Copt-level=0
 //@ only-x86_64
-//@ min-llvm-version: 19
 //@ build-pass
 
 #[repr(align(536870912))]
diff --git a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs
index d758c903087..74882fb5c55 100644
--- a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs
+++ b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: --target aarch64-unknown-none -Zsanitizer=shadow-call-stack
-//@ error-pattern: shadow-call-stack sanitizer is not supported for this target
 //@ dont-check-compiler-stderr
 //@ needs-llvm-components: aarch64
 
@@ -13,3 +12,5 @@ trait Sized {}
 
 #[no_mangle]
 pub fn foo() {}
+
+//~? ERROR shadow-call-stack sanitizer is not supported for this target
diff --git a/tests/ui/allocator/two-allocators2.rs b/tests/ui/allocator/two-allocators2.rs
index b3bb4598c77..6efb297054b 100644
--- a/tests/ui/allocator/two-allocators2.rs
+++ b/tests/ui/allocator/two-allocators2.rs
@@ -1,6 +1,5 @@
 //@ aux-build:system-allocator.rs
 //@ no-prefer-dynamic
-//@ error-pattern: the `#[global_allocator]` in
 
 extern crate system_allocator;
 
@@ -10,3 +9,5 @@ use std::alloc::System;
 static A: System = System;
 
 fn main() {}
+
+//~? ERROR the `#[global_allocator]` in this crate conflicts with global allocator in: system_allocator
diff --git a/tests/ui/allocator/two-allocators3.rs b/tests/ui/allocator/two-allocators3.rs
index 0cb3879666d..3aba96068de 100644
--- a/tests/ui/allocator/two-allocators3.rs
+++ b/tests/ui/allocator/two-allocators3.rs
@@ -1,10 +1,10 @@
 //@ aux-build:system-allocator.rs
 //@ aux-build:system-allocator2.rs
 //@ no-prefer-dynamic
-//@ error-pattern: the `#[global_allocator]` in
-
 
 extern crate system_allocator;
 extern crate system_allocator2;
 
 fn main() {}
+
+//~? ERROR the `#[global_allocator]` in system_allocator conflicts with global allocator in: system_allocator2
diff --git a/tests/ui/amdgpu-require-explicit-cpu.rs b/tests/ui/amdgpu-require-explicit-cpu.rs
index 46778a1094f..d40cb97977d 100644
--- a/tests/ui/amdgpu-require-explicit-cpu.rs
+++ b/tests/ui/amdgpu-require-explicit-cpu.rs
@@ -3,7 +3,6 @@
 //@ compile-flags: --crate-type=cdylib --target=amdgcn-amd-amdhsa
 //@ needs-llvm-components: amdgpu
 //@ needs-rust-lld
-//@[nocpu] error-pattern: target requires explicitly specifying a cpu
 //@[nocpu] build-fail
 //@[cpu] compile-flags: -Ctarget-cpu=gfx900
 //@[cpu] build-pass
@@ -15,3 +14,5 @@
 trait Sized {}
 
 pub fn foo() {}
+
+//[nocpu]~? ERROR target requires explicitly specifying a cpu with `-C target-cpu`
diff --git a/tests/ui/asm/aarch64/srcloc.old.stderr b/tests/ui/asm/aarch64/srcloc.old.stderr
deleted file mode 100644
index 2a15e48f025..00000000000
--- a/tests/ui/asm/aarch64/srcloc.old.stderr
+++ /dev/null
@@ -1,290 +0,0 @@
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:15:15
-   |
-LL |         asm!("invalid_instruction");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     invalid_instruction
-   |     ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:19:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:13
-   |
-LL |             invalid_instruction
-   |             ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:24:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:13
-   |
-LL |             invalid_instruction
-   |             ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:30:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:13
-   |
-LL |             invalid_instruction
-   |             ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:37:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:13
-   |
-LL |             invalid_instruction
-   |             ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:42:14
-   |
-LL |         asm!(concat!("invalid", "_", "instruction"));
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     invalid_instruction
-   |     ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:46:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     invalid_instruction
-   |     ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:52:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:1
-   |
-LL | invalid_instruction
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:59:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:66:13
-   |
-LL |             concat!("invalid", "_", "instruction"),
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:1
-   |
-LL | invalid_instruction
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:73:13
-   |
-LL |             concat!("invalid", "_", "instruction"),
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:1
-   |
-LL | invalid_instruction
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:80:14
-   |
-LL |             "invalid_instruction1",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     invalid_instruction1
-   |     ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:81:14
-   |
-LL |             "invalid_instruction2",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:1
-   |
-LL | invalid_instruction2
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:87:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     invalid_instruction1
-   |     ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:87:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:1
-   |
-LL | invalid_instruction2
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:96:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     invalid_instruction1
-   |     ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:96:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:1
-   |
-LL | invalid_instruction2
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:100:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction3
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:100:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:1
-   |
-LL | invalid_instruction4
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:111:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     invalid_instruction1
-   |     ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:111:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:1
-   |
-LL | invalid_instruction2
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:115:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:1
-   |
-LL | invalid_instruction3
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:115:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:5:1
-   |
-LL | invalid_instruction4
-   | ^
-
-error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:128:14
-   |
-LL |             "invalid_instruction"
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:1
-   |
-LL | invalid_instruction
-   | ^
-
-error: aborting due to 24 previous errors
-
diff --git a/tests/ui/asm/aarch64/srcloc.rs b/tests/ui/asm/aarch64/srcloc.rs
index 9b92dfef056..c635fa6ba70 100644
--- a/tests/ui/asm/aarch64/srcloc.rs
+++ b/tests/ui/asm/aarch64/srcloc.rs
@@ -1,10 +1,7 @@
-//@ revisions: old new
 //@ only-aarch64
 //@ build-fail
 //@ needs-asm-support
 //@ compile-flags: -Ccodegen-units=1
-//@[old] ignore-llvm-version: 19 - 99
-//@[new] min-llvm-version: 19
 
 use std::arch::asm;
 
diff --git a/tests/ui/asm/aarch64/srcloc.new.stderr b/tests/ui/asm/aarch64/srcloc.stderr
index b92a07e5fb1..b47f19bea61 100644
--- a/tests/ui/asm/aarch64/srcloc.new.stderr
+++ b/tests/ui/asm/aarch64/srcloc.stderr
@@ -1,5 +1,5 @@
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:15:15
+  --> $DIR/srcloc.rs:12:15
    |
 LL |         asm!("invalid_instruction");
    |               ^^^^^^^^^^^^^^^^^^^
@@ -11,7 +11,7 @@ LL |     invalid_instruction
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:19:13
+  --> $DIR/srcloc.rs:16:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:24:13
+  --> $DIR/srcloc.rs:21:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:30:13
+  --> $DIR/srcloc.rs:27:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:37:13
+  --> $DIR/srcloc.rs:34:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -59,7 +59,7 @@ LL |             invalid_instruction
    |             ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:42:14
+  --> $DIR/srcloc.rs:39:14
    |
 LL |         asm!(concat!("invalid", "_", "instruction"));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     invalid_instruction
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:46:14
+  --> $DIR/srcloc.rs:43:14
    |
 LL |             "invalid_instruction",
    |              ^^^^^^^^^^^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     invalid_instruction
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:52:14
+  --> $DIR/srcloc.rs:49:14
    |
 LL |             "invalid_instruction",
    |              ^^^^^^^^^^^^^^^^^^^
@@ -95,7 +95,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:59:14
+  --> $DIR/srcloc.rs:56:14
    |
 LL |             "invalid_instruction",
    |              ^^^^^^^^^^^^^^^^^^^
@@ -107,7 +107,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:66:13
+  --> $DIR/srcloc.rs:63:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -119,7 +119,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:73:13
+  --> $DIR/srcloc.rs:70:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL | invalid_instruction
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:80:14
+  --> $DIR/srcloc.rs:77:14
    |
 LL |             "invalid_instruction1",
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -143,7 +143,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:81:14
+  --> $DIR/srcloc.rs:78:14
    |
 LL |             "invalid_instruction2",
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -155,7 +155,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:87:13
+  --> $DIR/srcloc.rs:84:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -170,7 +170,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:87:13
+  --> $DIR/srcloc.rs:84:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -185,7 +185,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:96:13
+  --> $DIR/srcloc.rs:93:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -200,7 +200,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:96:13
+  --> $DIR/srcloc.rs:93:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -215,7 +215,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:100:13
+  --> $DIR/srcloc.rs:97:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -230,7 +230,7 @@ LL | invalid_instruction3
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:100:13
+  --> $DIR/srcloc.rs:97:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -245,7 +245,7 @@ LL | invalid_instruction4
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:111:13
+  --> $DIR/srcloc.rs:108:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -260,7 +260,7 @@ LL |     invalid_instruction1
    |     ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:111:13
+  --> $DIR/srcloc.rs:108:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -275,7 +275,7 @@ LL | invalid_instruction2
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:115:13
+  --> $DIR/srcloc.rs:112:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -290,7 +290,7 @@ LL | invalid_instruction3
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:115:13
+  --> $DIR/srcloc.rs:112:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -305,7 +305,7 @@ LL | invalid_instruction4
    | ^
 
 error: unrecognized instruction mnemonic
-  --> $DIR/srcloc.rs:128:14
+  --> $DIR/srcloc.rs:125:14
    |
 LL |             "invalid_instruction"
    |              ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/inline-syntax.arm.stderr b/tests/ui/asm/inline-syntax.arm.stderr
index 4003a10f374..5b4eb3cc140 100644
--- a/tests/ui/asm/inline-syntax.arm.stderr
+++ b/tests/ui/asm/inline-syntax.arm.stderr
@@ -15,7 +15,7 @@ LL | .intel_syntax noprefix
    | ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:26:15
+  --> $DIR/inline-syntax.rs:21:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     .intel_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:30:15
+  --> $DIR/inline-syntax.rs:24:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,7 +39,7 @@ LL |     .intel_syntax aaa noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:34:15
+  --> $DIR/inline-syntax.rs:27:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^
@@ -51,7 +51,7 @@ LL |     .att_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:38:15
+  --> $DIR/inline-syntax.rs:30:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |     .att_syntax bbb noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:42:15
+  --> $DIR/inline-syntax.rs:33:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -75,7 +75,7 @@ LL |     .intel_syntax noprefix; nop
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:49:13
+  --> $DIR/inline-syntax.rs:39:13
    |
 LL |             .intel_syntax noprefix
    |             ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/inline-syntax.arm_llvm_18.stderr b/tests/ui/asm/inline-syntax.arm_llvm_18.stderr
deleted file mode 100644
index a03861c78a3..00000000000
--- a/tests/ui/asm/inline-syntax.arm_llvm_18.stderr
+++ /dev/null
@@ -1,90 +0,0 @@
-error: unknown directive
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:1
-   |
-LL | .intel_syntax noprefix
-   | ^
-
-error: unknown directive
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:1
-   |
-LL | .intel_syntax noprefix
-   | ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:26:15
-   |
-LL |         asm!(".intel_syntax noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .intel_syntax noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:30:15
-   |
-LL |         asm!(".intel_syntax aaa noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .intel_syntax aaa noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:34:15
-   |
-LL |         asm!(".att_syntax noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .att_syntax noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:38:15
-   |
-LL |         asm!(".att_syntax bbb noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .att_syntax bbb noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:42:15
-   |
-LL |         asm!(".intel_syntax noprefix; nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .intel_syntax noprefix; nop
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:49:13
-   |
-LL |             .intel_syntax noprefix
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:13
-   |
-LL |             .intel_syntax noprefix
-   |             ^
-
-error: aborting due to 8 previous errors
-
diff --git a/tests/ui/asm/inline-syntax.rs b/tests/ui/asm/inline-syntax.rs
index 78f30d50d8c..5f2f4e357f9 100644
--- a/tests/ui/asm/inline-syntax.rs
+++ b/tests/ui/asm/inline-syntax.rs
@@ -1,17 +1,12 @@
 //@ add-core-stubs
-//@ revisions: x86_64 arm_llvm_18 arm
+//@ revisions: x86_64 arm
 //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
 //@[x86_64] check-pass
 //@[x86_64] needs-llvm-components: x86
-//@[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
-//@[arm_llvm_18] build-fail
-//@[arm_llvm_18] needs-llvm-components: arm
-//@[arm_llvm_18] ignore-llvm-version: 19 - 99
 // LLVM 19+ has full support for 64-bit cookies.
 //@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
 //@[arm] build-fail
 //@[arm] needs-llvm-components: arm
-//@[arm] min-llvm-version: 19
 //@ needs-asm-support
 
 #![feature(no_core)]
@@ -26,23 +21,18 @@ pub fn main() {
         asm!(".intel_syntax noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".intel_syntax aaa noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".att_syntax noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.att_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".att_syntax bbb noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.att_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".intel_syntax noprefix; nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
 
         asm!(
             r"
@@ -51,7 +41,6 @@ pub fn main() {
         );
         //[x86_64]~^^^ WARN avoid using `.intel_syntax`
         //[arm]~^^^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^^^ ERROR unknown directive
     }
 }
 
@@ -59,7 +48,5 @@ global_asm!(".intel_syntax noprefix", "nop");
 //[x86_64]~^ WARN avoid using `.intel_syntax`
 // Global assembly errors don't have line numbers, so no error on ARM.
 
-//[arm_llvm_18]~? ERROR unknown directive
-//[arm_llvm_18]~? ERROR unknown directive
 //[arm]~? ERROR unknown directive
 //[arm]~? ERROR unknown directive
diff --git a/tests/ui/asm/inline-syntax.x86_64.stderr b/tests/ui/asm/inline-syntax.x86_64.stderr
index 369f7b66ae4..2d8091c2044 100644
--- a/tests/ui/asm/inline-syntax.x86_64.stderr
+++ b/tests/ui/asm/inline-syntax.x86_64.stderr
@@ -1,5 +1,5 @@
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:58:14
+  --> $DIR/inline-syntax.rs:47:14
    |
 LL | global_asm!(".intel_syntax noprefix", "nop");
    |              ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop");
    = note: `#[warn(bad_asm_style)]` on by default
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:26:15
+  --> $DIR/inline-syntax.rs:21:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:30:15
+  --> $DIR/inline-syntax.rs:24:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:34:15
+  --> $DIR/inline-syntax.rs:27:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:38:15
+  --> $DIR/inline-syntax.rs:30:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:42:15
+  --> $DIR/inline-syntax.rs:33:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:49:13
+  --> $DIR/inline-syntax.rs:39:13
    |
 LL |             .intel_syntax noprefix
    |             ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr
index 07c1bf21183..5d527cd70b8 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr
@@ -1,5 +1,5 @@
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:54:11
+  --> $DIR/riscv32e-registers.rs:42:11
    |
 LL |     asm!("li x16, 0");
    |           ^^^^^^^^^
@@ -11,7 +11,7 @@ LL |     li x16, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:57:11
+  --> $DIR/riscv32e-registers.rs:45:11
    |
 LL |     asm!("li x17, 0");
    |           ^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     li x17, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:60:11
+  --> $DIR/riscv32e-registers.rs:48:11
    |
 LL |     asm!("li x18, 0");
    |           ^^^^^^^^^
@@ -35,7 +35,7 @@ LL |     li x18, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:63:11
+  --> $DIR/riscv32e-registers.rs:51:11
    |
 LL |     asm!("li x19, 0");
    |           ^^^^^^^^^
@@ -47,7 +47,7 @@ LL |     li x19, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:66:11
+  --> $DIR/riscv32e-registers.rs:54:11
    |
 LL |     asm!("li x20, 0");
    |           ^^^^^^^^^
@@ -59,7 +59,7 @@ LL |     li x20, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:69:11
+  --> $DIR/riscv32e-registers.rs:57:11
    |
 LL |     asm!("li x21, 0");
    |           ^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     li x21, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:72:11
+  --> $DIR/riscv32e-registers.rs:60:11
    |
 LL |     asm!("li x22, 0");
    |           ^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     li x22, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:75:11
+  --> $DIR/riscv32e-registers.rs:63:11
    |
 LL |     asm!("li x23, 0");
    |           ^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     li x23, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:78:11
+  --> $DIR/riscv32e-registers.rs:66:11
    |
 LL |     asm!("li x24, 0");
    |           ^^^^^^^^^
@@ -107,7 +107,7 @@ LL |     li x24, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:81:11
+  --> $DIR/riscv32e-registers.rs:69:11
    |
 LL |     asm!("li x25, 0");
    |           ^^^^^^^^^
@@ -119,7 +119,7 @@ LL |     li x25, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:84:11
+  --> $DIR/riscv32e-registers.rs:72:11
    |
 LL |     asm!("li x26, 0");
    |           ^^^^^^^^^
@@ -131,7 +131,7 @@ LL |     li x26, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:87:11
+  --> $DIR/riscv32e-registers.rs:75:11
    |
 LL |     asm!("li x27, 0");
    |           ^^^^^^^^^
@@ -143,7 +143,7 @@ LL |     li x27, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:90:11
+  --> $DIR/riscv32e-registers.rs:78:11
    |
 LL |     asm!("li x28, 0");
    |           ^^^^^^^^^
@@ -155,7 +155,7 @@ LL |     li x28, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:93:11
+  --> $DIR/riscv32e-registers.rs:81:11
    |
 LL |     asm!("li x29, 0");
    |           ^^^^^^^^^
@@ -167,7 +167,7 @@ LL |     li x29, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:96:11
+  --> $DIR/riscv32e-registers.rs:84:11
    |
 LL |     asm!("li x30, 0");
    |           ^^^^^^^^^
@@ -179,7 +179,7 @@ LL |     li x30, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:99:11
+  --> $DIR/riscv32e-registers.rs:87:11
    |
 LL |     asm!("li x31, 0");
    |           ^^^^^^^^^
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr
deleted file mode 100644
index 59009b8c352..00000000000
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32e_llvm_18.stderr
+++ /dev/null
@@ -1,194 +0,0 @@
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:54:11
-   |
-LL |     asm!("li x16, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x16, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:57:11
-   |
-LL |     asm!("li x17, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x17, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:60:11
-   |
-LL |     asm!("li x18, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x18, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:63:11
-   |
-LL |     asm!("li x19, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x19, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:66:11
-   |
-LL |     asm!("li x20, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x20, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:69:11
-   |
-LL |     asm!("li x21, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x21, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:72:11
-   |
-LL |     asm!("li x22, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x22, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:75:11
-   |
-LL |     asm!("li x23, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x23, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:78:11
-   |
-LL |     asm!("li x24, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x24, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:81:11
-   |
-LL |     asm!("li x25, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x25, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:84:11
-   |
-LL |     asm!("li x26, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x26, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:87:11
-   |
-LL |     asm!("li x27, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x27, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:90:11
-   |
-LL |     asm!("li x28, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x28, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:93:11
-   |
-LL |     asm!("li x29, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x29, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:96:11
-   |
-LL |     asm!("li x30, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x30, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:99:11
-   |
-LL |     asm!("li x31, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x31, 0
-   |        ^
-
-error: aborting due to 16 previous errors
-
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr
index 07c1bf21183..5d527cd70b8 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr
@@ -1,5 +1,5 @@
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:54:11
+  --> $DIR/riscv32e-registers.rs:42:11
    |
 LL |     asm!("li x16, 0");
    |           ^^^^^^^^^
@@ -11,7 +11,7 @@ LL |     li x16, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:57:11
+  --> $DIR/riscv32e-registers.rs:45:11
    |
 LL |     asm!("li x17, 0");
    |           ^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     li x17, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:60:11
+  --> $DIR/riscv32e-registers.rs:48:11
    |
 LL |     asm!("li x18, 0");
    |           ^^^^^^^^^
@@ -35,7 +35,7 @@ LL |     li x18, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:63:11
+  --> $DIR/riscv32e-registers.rs:51:11
    |
 LL |     asm!("li x19, 0");
    |           ^^^^^^^^^
@@ -47,7 +47,7 @@ LL |     li x19, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:66:11
+  --> $DIR/riscv32e-registers.rs:54:11
    |
 LL |     asm!("li x20, 0");
    |           ^^^^^^^^^
@@ -59,7 +59,7 @@ LL |     li x20, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:69:11
+  --> $DIR/riscv32e-registers.rs:57:11
    |
 LL |     asm!("li x21, 0");
    |           ^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     li x21, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:72:11
+  --> $DIR/riscv32e-registers.rs:60:11
    |
 LL |     asm!("li x22, 0");
    |           ^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     li x22, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:75:11
+  --> $DIR/riscv32e-registers.rs:63:11
    |
 LL |     asm!("li x23, 0");
    |           ^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     li x23, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:78:11
+  --> $DIR/riscv32e-registers.rs:66:11
    |
 LL |     asm!("li x24, 0");
    |           ^^^^^^^^^
@@ -107,7 +107,7 @@ LL |     li x24, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:81:11
+  --> $DIR/riscv32e-registers.rs:69:11
    |
 LL |     asm!("li x25, 0");
    |           ^^^^^^^^^
@@ -119,7 +119,7 @@ LL |     li x25, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:84:11
+  --> $DIR/riscv32e-registers.rs:72:11
    |
 LL |     asm!("li x26, 0");
    |           ^^^^^^^^^
@@ -131,7 +131,7 @@ LL |     li x26, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:87:11
+  --> $DIR/riscv32e-registers.rs:75:11
    |
 LL |     asm!("li x27, 0");
    |           ^^^^^^^^^
@@ -143,7 +143,7 @@ LL |     li x27, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:90:11
+  --> $DIR/riscv32e-registers.rs:78:11
    |
 LL |     asm!("li x28, 0");
    |           ^^^^^^^^^
@@ -155,7 +155,7 @@ LL |     li x28, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:93:11
+  --> $DIR/riscv32e-registers.rs:81:11
    |
 LL |     asm!("li x29, 0");
    |           ^^^^^^^^^
@@ -167,7 +167,7 @@ LL |     li x29, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:96:11
+  --> $DIR/riscv32e-registers.rs:84:11
    |
 LL |     asm!("li x30, 0");
    |           ^^^^^^^^^
@@ -179,7 +179,7 @@ LL |     li x30, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:99:11
+  --> $DIR/riscv32e-registers.rs:87:11
    |
 LL |     asm!("li x31, 0");
    |           ^^^^^^^^^
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr
deleted file mode 100644
index 59009b8c352..00000000000
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32em_llvm_18.stderr
+++ /dev/null
@@ -1,194 +0,0 @@
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:54:11
-   |
-LL |     asm!("li x16, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x16, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:57:11
-   |
-LL |     asm!("li x17, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x17, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:60:11
-   |
-LL |     asm!("li x18, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x18, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:63:11
-   |
-LL |     asm!("li x19, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x19, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:66:11
-   |
-LL |     asm!("li x20, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x20, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:69:11
-   |
-LL |     asm!("li x21, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x21, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:72:11
-   |
-LL |     asm!("li x22, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x22, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:75:11
-   |
-LL |     asm!("li x23, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x23, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:78:11
-   |
-LL |     asm!("li x24, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x24, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:81:11
-   |
-LL |     asm!("li x25, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x25, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:84:11
-   |
-LL |     asm!("li x26, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x26, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:87:11
-   |
-LL |     asm!("li x27, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x27, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:90:11
-   |
-LL |     asm!("li x28, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x28, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:93:11
-   |
-LL |     asm!("li x29, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x29, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:96:11
-   |
-LL |     asm!("li x30, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x30, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:99:11
-   |
-LL |     asm!("li x31, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x31, 0
-   |        ^
-
-error: aborting due to 16 previous errors
-
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr
index 07c1bf21183..5d527cd70b8 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr
+++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr
@@ -1,5 +1,5 @@
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:54:11
+  --> $DIR/riscv32e-registers.rs:42:11
    |
 LL |     asm!("li x16, 0");
    |           ^^^^^^^^^
@@ -11,7 +11,7 @@ LL |     li x16, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:57:11
+  --> $DIR/riscv32e-registers.rs:45:11
    |
 LL |     asm!("li x17, 0");
    |           ^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     li x17, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:60:11
+  --> $DIR/riscv32e-registers.rs:48:11
    |
 LL |     asm!("li x18, 0");
    |           ^^^^^^^^^
@@ -35,7 +35,7 @@ LL |     li x18, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:63:11
+  --> $DIR/riscv32e-registers.rs:51:11
    |
 LL |     asm!("li x19, 0");
    |           ^^^^^^^^^
@@ -47,7 +47,7 @@ LL |     li x19, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:66:11
+  --> $DIR/riscv32e-registers.rs:54:11
    |
 LL |     asm!("li x20, 0");
    |           ^^^^^^^^^
@@ -59,7 +59,7 @@ LL |     li x20, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:69:11
+  --> $DIR/riscv32e-registers.rs:57:11
    |
 LL |     asm!("li x21, 0");
    |           ^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     li x21, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:72:11
+  --> $DIR/riscv32e-registers.rs:60:11
    |
 LL |     asm!("li x22, 0");
    |           ^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     li x22, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:75:11
+  --> $DIR/riscv32e-registers.rs:63:11
    |
 LL |     asm!("li x23, 0");
    |           ^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     li x23, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:78:11
+  --> $DIR/riscv32e-registers.rs:66:11
    |
 LL |     asm!("li x24, 0");
    |           ^^^^^^^^^
@@ -107,7 +107,7 @@ LL |     li x24, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:81:11
+  --> $DIR/riscv32e-registers.rs:69:11
    |
 LL |     asm!("li x25, 0");
    |           ^^^^^^^^^
@@ -119,7 +119,7 @@ LL |     li x25, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:84:11
+  --> $DIR/riscv32e-registers.rs:72:11
    |
 LL |     asm!("li x26, 0");
    |           ^^^^^^^^^
@@ -131,7 +131,7 @@ LL |     li x26, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:87:11
+  --> $DIR/riscv32e-registers.rs:75:11
    |
 LL |     asm!("li x27, 0");
    |           ^^^^^^^^^
@@ -143,7 +143,7 @@ LL |     li x27, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:90:11
+  --> $DIR/riscv32e-registers.rs:78:11
    |
 LL |     asm!("li x28, 0");
    |           ^^^^^^^^^
@@ -155,7 +155,7 @@ LL |     li x28, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:93:11
+  --> $DIR/riscv32e-registers.rs:81:11
    |
 LL |     asm!("li x29, 0");
    |           ^^^^^^^^^
@@ -167,7 +167,7 @@ LL |     li x29, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:96:11
+  --> $DIR/riscv32e-registers.rs:84:11
    |
 LL |     asm!("li x30, 0");
    |           ^^^^^^^^^
@@ -179,7 +179,7 @@ LL |     li x30, 0
    |        ^
 
 error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:99:11
+  --> $DIR/riscv32e-registers.rs:87:11
    |
 LL |     asm!("li x31, 0");
    |           ^^^^^^^^^
diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr
deleted file mode 100644
index 59009b8c352..00000000000
--- a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc_llvm_18.stderr
+++ /dev/null
@@ -1,194 +0,0 @@
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:54:11
-   |
-LL |     asm!("li x16, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x16, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:57:11
-   |
-LL |     asm!("li x17, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x17, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:60:11
-   |
-LL |     asm!("li x18, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x18, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:63:11
-   |
-LL |     asm!("li x19, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x19, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:66:11
-   |
-LL |     asm!("li x20, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x20, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:69:11
-   |
-LL |     asm!("li x21, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x21, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:72:11
-   |
-LL |     asm!("li x22, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x22, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:75:11
-   |
-LL |     asm!("li x23, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x23, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:78:11
-   |
-LL |     asm!("li x24, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x24, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:81:11
-   |
-LL |     asm!("li x25, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x25, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:84:11
-   |
-LL |     asm!("li x26, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x26, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:87:11
-   |
-LL |     asm!("li x27, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x27, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:90:11
-   |
-LL |     asm!("li x28, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x28, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:93:11
-   |
-LL |     asm!("li x29, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x29, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:96:11
-   |
-LL |     asm!("li x30, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x30, 0
-   |        ^
-
-error: invalid operand for instruction
-  --> $DIR/riscv32e-registers.rs:99:11
-   |
-LL |     asm!("li x31, 0");
-   |           ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:5
-   |
-LL |     li x31, 0
-   |        ^
-
-error: aborting due to 16 previous errors
-
diff --git a/tests/ui/asm/riscv/riscv32e-registers.rs b/tests/ui/asm/riscv/riscv32e-registers.rs
index 99cbdf5ead3..96bfe2af064 100644
--- a/tests/ui/asm/riscv/riscv32e-registers.rs
+++ b/tests/ui/asm/riscv/riscv32e-registers.rs
@@ -2,27 +2,15 @@
 //
 //@ add-core-stubs
 //@ build-fail
-//@ revisions: riscv32e riscv32em riscv32emc riscv32e_llvm_18 riscv32em_llvm_18 riscv32emc_llvm_18
+//@ revisions: riscv32e riscv32em riscv32emc
 //
 //@ compile-flags: --crate-type=rlib
 //@ [riscv32e] needs-llvm-components: riscv
 //@ [riscv32e] compile-flags: --target=riscv32e-unknown-none-elf
-//@ [riscv32e] min-llvm-version: 19
 //@ [riscv32em] needs-llvm-components: riscv
 //@ [riscv32em] compile-flags: --target=riscv32em-unknown-none-elf
-//@ [riscv32em] min-llvm-version: 19
 //@ [riscv32emc] needs-llvm-components: riscv
 //@ [riscv32emc] compile-flags: --target=riscv32emc-unknown-none-elf
-//@ [riscv32emc] min-llvm-version: 19
-//@ [riscv32e_llvm_18] needs-llvm-components: riscv
-//@ [riscv32e_llvm_18] compile-flags: --target=riscv32e-unknown-none-elf
-//@ [riscv32e_llvm_18] ignore-llvm-version: 19 - 99
-//@ [riscv32em_llvm_18] needs-llvm-components: riscv
-//@ [riscv32em_llvm_18] compile-flags: --target=riscv32em-unknown-none-elf
-//@ [riscv32em_llvm_18] ignore-llvm-version: 19 - 99
-//@ [riscv32emc_llvm_18] needs-llvm-components: riscv
-//@ [riscv32emc_llvm_18] compile-flags: --target=riscv32emc-unknown-none-elf
-//@ [riscv32emc_llvm_18] ignore-llvm-version: 19 - 99
 
 // Unlike bad-reg.rs, this tests if the assembler can reject invalid registers
 // usage in assembly code.
diff --git a/tests/ui/asm/x86_64/srcloc.old.stderr b/tests/ui/asm/x86_64/srcloc.old.stderr
deleted file mode 100644
index edb9ee46812..00000000000
--- a/tests/ui/asm/x86_64/srcloc.old.stderr
+++ /dev/null
@@ -1,302 +0,0 @@
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:14:15
-   |
-LL |         asm!("invalid_instruction");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction
-   |     ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:18:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:23:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:29:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:36:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:41:14
-   |
-LL |         asm!(concat!("invalid", "_", "instruction"));
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction
-   |     ^^^^^^^^^^^^^^^^^^^
-
-warning: scale factor without index register is ignored
-  --> $DIR/srcloc.rs:44:15
-   |
-LL |         asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:23
-   |
-LL |     movaps %xmm3, (%esi, 2)
-   |                          ^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:48:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction
-   |     ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:54:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:61:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:68:13
-   |
-LL |             concat!("invalid", "_", "instruction"),
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:75:13
-   |
-LL |             concat!("invalid", "_", "instruction"),
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:82:14
-   |
-LL |             "invalid_instruction1",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:83:14
-   |
-LL |             "invalid_instruction2",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:89:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:89:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:98:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:98:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:102:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:1
-   |
-LL | invalid_instruction3
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:102:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:5:1
-   |
-LL | invalid_instruction4
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:113:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:113:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:117:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:5:1
-   |
-LL | invalid_instruction3
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:117:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:6:1
-   |
-LL | invalid_instruction4
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:130:14
-   |
-LL |             "invalid_instruction"
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:5:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 24 previous errors; 1 warning emitted
-
diff --git a/tests/ui/asm/x86_64/srcloc.rs b/tests/ui/asm/x86_64/srcloc.rs
index 40fc66cbc92..2938bafe5e7 100644
--- a/tests/ui/asm/x86_64/srcloc.rs
+++ b/tests/ui/asm/x86_64/srcloc.rs
@@ -1,9 +1,6 @@
-//@ revisions: old new
 //@ only-x86_64
 //@ build-fail
 //@ compile-flags: -Ccodegen-units=1
-//@[old] ignore-llvm-version: 19 - 99
-//@[new] min-llvm-version: 19
 
 use std::arch::asm;
 
diff --git a/tests/ui/asm/x86_64/srcloc.new.stderr b/tests/ui/asm/x86_64/srcloc.stderr
index 7211f1ab69d..bb4e855163d 100644
--- a/tests/ui/asm/x86_64/srcloc.new.stderr
+++ b/tests/ui/asm/x86_64/srcloc.stderr
@@ -1,5 +1,5 @@
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:14:15
+  --> $DIR/srcloc.rs:11:15
    |
 LL |         asm!("invalid_instruction");
    |               ^^^^^^^^^^^^^^^^^^^
@@ -11,7 +11,7 @@ LL |     invalid_instruction
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:18:13
+  --> $DIR/srcloc.rs:15:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:23:13
+  --> $DIR/srcloc.rs:20:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:29:13
+  --> $DIR/srcloc.rs:26:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:36:13
+  --> $DIR/srcloc.rs:33:13
    |
 LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
@@ -59,7 +59,7 @@ LL |             invalid_instruction
    |             ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:41:14
+  --> $DIR/srcloc.rs:38:14
    |
 LL |         asm!(concat!("invalid", "_", "instruction"));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     invalid_instruction
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: scale factor without index register is ignored
-  --> $DIR/srcloc.rs:44:15
+  --> $DIR/srcloc.rs:41:15
    |
 LL |         asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
    |               ^^^^^^^^^^^^^^^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     movaps %xmm3, (%esi, 2)
    |                          ^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:48:14
+  --> $DIR/srcloc.rs:45:14
    |
 LL |             "invalid_instruction",
    |              ^^^^^^^^^^^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     invalid_instruction
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:54:14
+  --> $DIR/srcloc.rs:51:14
    |
 LL |             "invalid_instruction",
    |              ^^^^^^^^^^^^^^^^^^^
@@ -107,7 +107,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:61:14
+  --> $DIR/srcloc.rs:58:14
    |
 LL |             "invalid_instruction",
    |              ^^^^^^^^^^^^^^^^^^^
@@ -119,7 +119,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:68:13
+  --> $DIR/srcloc.rs:65:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:75:13
+  --> $DIR/srcloc.rs:72:13
    |
 LL |             concat!("invalid", "_", "instruction"),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -143,7 +143,7 @@ LL | invalid_instruction
    | ^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:82:14
+  --> $DIR/srcloc.rs:79:14
    |
 LL |             "invalid_instruction1",
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -155,7 +155,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:83:14
+  --> $DIR/srcloc.rs:80:14
    |
 LL |             "invalid_instruction2",
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -167,7 +167,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:89:13
+  --> $DIR/srcloc.rs:86:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -182,7 +182,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:89:13
+  --> $DIR/srcloc.rs:86:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -197,7 +197,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:98:13
+  --> $DIR/srcloc.rs:95:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -212,7 +212,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:98:13
+  --> $DIR/srcloc.rs:95:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -227,7 +227,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:102:13
+  --> $DIR/srcloc.rs:99:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -242,7 +242,7 @@ LL | invalid_instruction3
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:102:13
+  --> $DIR/srcloc.rs:99:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -257,7 +257,7 @@ LL | invalid_instruction4
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:113:13
+  --> $DIR/srcloc.rs:110:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -272,7 +272,7 @@ LL |     invalid_instruction1
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:113:13
+  --> $DIR/srcloc.rs:110:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction1", "\n",
@@ -287,7 +287,7 @@ LL | invalid_instruction2
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:117:13
+  --> $DIR/srcloc.rs:114:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -302,7 +302,7 @@ LL | invalid_instruction3
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:117:13
+  --> $DIR/srcloc.rs:114:13
    |
 LL | /             concat!(
 LL | |                 "invalid", "_", "instruction3", "\n",
@@ -317,7 +317,7 @@ LL | invalid_instruction4
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:130:14
+  --> $DIR/srcloc.rs:127:14
    |
 LL |             "invalid_instruction"
    |              ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs
index 048681f0477..d6c2acaa9ed 100644
--- a/tests/ui/associated-consts/issue-93835.rs
+++ b/tests/ui/associated-consts/issue-93835.rs
@@ -3,11 +3,10 @@
 fn e() {
     type_ascribe!(p, a<p:p<e=6>>);
     //~^ ERROR cannot find type `a` in this scope
-    //~| ERROR path separator must be a double colon
     //~| ERROR cannot find value
     //~| ERROR associated const equality
+    //~| ERROR cannot find trait `p` in this scope
     //~| ERROR associated const equality
-    //~| ERROR failed to resolve: use of unresolved module or unlinked crate `p`
 }
 
 fn main() {}
diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr
index e154ae25de2..551b50d0eb6 100644
--- a/tests/ui/associated-consts/issue-93835.stderr
+++ b/tests/ui/associated-consts/issue-93835.stderr
@@ -1,15 +1,3 @@
-error: path separator must be a double colon
-  --> $DIR/issue-93835.rs:4:25
-   |
-LL |     type_ascribe!(p, a<p:p<e=6>>);
-   |                         ^
-   |
-   = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
-help: use a double colon instead
-   |
-LL |     type_ascribe!(p, a<p::p<e=6>>);
-   |                          +
-
 error[E0425]: cannot find value `p` in this scope
   --> $DIR/issue-93835.rs:4:19
    |
@@ -22,6 +10,12 @@ error[E0412]: cannot find type `a` in this scope
 LL |     type_ascribe!(p, a<p:p<e=6>>);
    |                      ^ not found in this scope
 
+error[E0405]: cannot find trait `p` in this scope
+  --> $DIR/issue-93835.rs:4:26
+   |
+LL |     type_ascribe!(p, a<p:p<e=6>>);
+   |                          ^ not found in this scope
+
 error[E0658]: associated const equality is incomplete
   --> $DIR/issue-93835.rs:4:28
    |
@@ -43,15 +37,7 @@ LL |     type_ascribe!(p, a<p:p<e=6>>);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p`
-  --> $DIR/issue-93835.rs:4:24
-   |
-LL |     type_ascribe!(p, a<p:p<e=6>>);
-   |                        ^ use of unresolved module or unlinked crate `p`
-   |
-   = help: you might be missing a crate named `p`
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0412, E0425, E0433, E0658.
-For more information about an error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0405, E0412, E0425, E0658.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/tests/ui/associated-types/bound-lifetime-constrained.ok.stderr b/tests/ui/associated-types/bound-lifetime-constrained.ok.stderr
deleted file mode 100644
index 9082044fe06..00000000000
--- a/tests/ui/associated-types/bound-lifetime-constrained.ok.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/bound-lifetime-constrained.rs:48:1
-   |
-LL | fn main() { }
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/associated-types/bound-lifetime-constrained.rs b/tests/ui/associated-types/bound-lifetime-constrained.rs
index 1dc3b2f5c2b..3a5a77f57f2 100644
--- a/tests/ui/associated-types/bound-lifetime-constrained.rs
+++ b/tests/ui/associated-types/bound-lifetime-constrained.rs
@@ -1,7 +1,7 @@
 //@ revisions: func object clause ok
+//@[ok] check-pass
 
 #![allow(dead_code)]
-#![feature(rustc_attrs)]
 
 trait Foo<'a> {
     type Item;
@@ -44,5 +44,4 @@ fn clause2<T>() where T: for<'a> Fn() -> <() as Foo<'a>>::Item {
     //[clause]~^ ERROR `Output` references lifetime `'a`
 }
 
-#[rustc_error]
-fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
+fn main() { }
diff --git a/tests/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr b/tests/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
deleted file mode 100644
index 435e224bd89..00000000000
--- a/tests/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/bound-lifetime-in-binding-only.rs:71:1
-   |
-LL | fn main() { }
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/associated-types/bound-lifetime-in-binding-only.rs b/tests/ui/associated-types/bound-lifetime-in-binding-only.rs
index e973e58b629..2401fe0ef1f 100644
--- a/tests/ui/associated-types/bound-lifetime-in-binding-only.rs
+++ b/tests/ui/associated-types/bound-lifetime-in-binding-only.rs
@@ -1,7 +1,7 @@
 //@ revisions: angle paren ok elision
+//@[ok] check-pass
 
 #![allow(dead_code)]
-#![feature(rustc_attrs)]
 #![feature(unboxed_closures)]
 
 trait Foo {
@@ -67,5 +67,4 @@ fn ok2<T: for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>>() {
 fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
 }
 
-#[rustc_error]
-fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
+fn main() { }
diff --git a/tests/ui/associated-types/bound-lifetime-in-return-only.ok.stderr b/tests/ui/associated-types/bound-lifetime-in-return-only.ok.stderr
deleted file mode 100644
index 1815a7be7ee..00000000000
--- a/tests/ui/associated-types/bound-lifetime-in-return-only.ok.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/bound-lifetime-in-return-only.rs:49:1
-   |
-LL | fn main() { }
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/associated-types/bound-lifetime-in-return-only.rs b/tests/ui/associated-types/bound-lifetime-in-return-only.rs
index bf3aa6149cc..8a28f5b7786 100644
--- a/tests/ui/associated-types/bound-lifetime-in-return-only.rs
+++ b/tests/ui/associated-types/bound-lifetime-in-return-only.rs
@@ -1,7 +1,7 @@
 //@ revisions: sig local structure ok elision
+//@[ok] check-pass
 
 #![allow(dead_code)]
-#![feature(rustc_attrs)]
 #![feature(unboxed_closures)]
 
 trait Foo {
@@ -45,5 +45,4 @@ fn ok1(_: &dyn for<'a> Fn(&Parameterized<'a>) -> &'a i32) {
 fn ok2(_: &dyn for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>) {
 }
 
-#[rustc_error]
-fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
+fn main() { }
diff --git a/tests/ui/associated-types/issue-36499.rs b/tests/ui/associated-types/issue-36499.rs
index 25f4060fa6f..606918b40b7 100644
--- a/tests/ui/associated-types/issue-36499.rs
+++ b/tests/ui/associated-types/issue-36499.rs
@@ -1,5 +1,5 @@
 //@ error-pattern: aborting due to 1 previous error
 
 fn main() {
-    2 + +2;
+    2 + +2; //~ ERROR leading `+` is not supported
 }
diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr
index f5e696b7ac1..f79afc89d10 100644
--- a/tests/ui/associated-types/issue-59324.stderr
+++ b/tests/ui/associated-types/issue-59324.stderr
@@ -36,11 +36,18 @@ LL | |
 LL | |         &self,
 LL | |     ) -> Self::AssocType;
    | |_________________________^ the trait `Foo` is not implemented for `Bug`
+
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/issue-59324.rs:24:29
    |
-help: consider further restricting type parameter `Bug` with trait `Foo`
+LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
+   |                             ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
    |
-LL | pub trait ThriftService<Bug: NotFoo + Foo>:
-   |                                     +++++
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-59324.rs:3:1
+   |
+LL | pub trait Foo: NotFoo {
+   | ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `Bug: Foo` is not satisfied
   --> $DIR/issue-59324.rs:16:5
@@ -51,18 +58,11 @@ LL | |
 LL | |         &self,
 LL | |     ) -> Self::AssocType;
    | |_________________________^ the trait `Foo` is not implemented for `Bug`
-
-error[E0277]: the trait bound `(): Foo` is not satisfied
-  --> $DIR/issue-59324.rs:24:29
    |
-LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
-   |                             ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
-   |
-help: this trait has no implementations, consider adding one
-  --> $DIR/issue-59324.rs:3:1
+help: consider further restricting type parameter `Bug` with trait `Foo`
    |
-LL | pub trait Foo: NotFoo {
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | pub trait ThriftService<Bug: NotFoo + Foo>:
+   |                                     +++++
 
 error[E0277]: the trait bound `Bug: Foo` is not satisfied
   --> $DIR/issue-59324.rs:20:10
diff --git a/tests/ui/async-await/async-closures/by-move-body-inlined-attrs.rs b/tests/ui/async-await/async-closures/by-move-body-inlined-attrs.rs
new file mode 100644
index 00000000000..ecfc06d2bad
--- /dev/null
+++ b/tests/ui/async-await/async-closures/by-move-body-inlined-attrs.rs
@@ -0,0 +1,28 @@
+//@ check-pass
+//@ compile-flags: -Zinline-mir -Zvalidate-mir
+//@ edition: 2024
+
+// See comment below.
+
+use std::future::Future;
+use std::pin::pin;
+use std::task::{Context, Waker};
+
+fn call_once<T>(f: impl FnOnce() -> T) -> T { f() }
+
+fn main() {
+    let x = async || {};
+    // We first inline `call_once<{async closure}>`.
+    //
+    // This gives us a future whose type is the "FnOnce" flavor of the async closure's
+    // child coroutine. The body of this coroutine is synthetic, which we synthesize in
+    // the by-move body query.
+    let fut = pin!(call_once(x));
+    // We then try to inline that body in this poll call.
+    //
+    // The inliner does some inlinability checks; one of these checks involves checking
+    // the body for the `#[rustc_no_mir_inline]` attribute. Since the synthetic body had
+    // no HIR synthesized, but it's still a local def id, we end up ICEing in the
+    // `local_def_id_to_hir_id` call when trying to read its attrs.
+    fut.poll(&mut Context::from_waker(Waker::noop()));
+}
diff --git a/tests/ui/attributes/attr-bad-crate-attr.rs b/tests/ui/attributes/attr-bad-crate-attr.rs
index 9de0abca9a7..d37d349026a 100644
--- a/tests/ui/attributes/attr-bad-crate-attr.rs
+++ b/tests/ui/attributes/attr-bad-crate-attr.rs
@@ -3,7 +3,6 @@
 //!
 //! See <https://doc.rust-lang.org/reference/attributes.html>.
 
-//@ error-pattern: expected item
-
 #![attr = "val"]
 #[attr = "val"] // Unterminated
+//~^ ERROR expected item after attributes
diff --git a/tests/ui/attributes/attr-bad-crate-attr.stderr b/tests/ui/attributes/attr-bad-crate-attr.stderr
index 69eabd32230..22522896bd1 100644
--- a/tests/ui/attributes/attr-bad-crate-attr.stderr
+++ b/tests/ui/attributes/attr-bad-crate-attr.stderr
@@ -1,5 +1,5 @@
 error: expected item after attributes
-  --> $DIR/attr-bad-crate-attr.rs:9:1
+  --> $DIR/attr-bad-crate-attr.rs:7:1
    |
 LL | #[attr = "val"] // Unterminated
    | ^^^^^^^^^^^^^^^
diff --git a/tests/ui/attributes/dont-dup-expr-attrs.rs b/tests/ui/attributes/dont-dup-expr-attrs.rs
new file mode 100644
index 00000000000..21da6820a53
--- /dev/null
+++ b/tests/ui/attributes/dont-dup-expr-attrs.rs
@@ -0,0 +1,133 @@
+//@ check-pass
+//
+// During development of #124141 at one point expression on attributes were
+// being duplicated and `m1` caused an exponential blowup that caused OOM.
+// The number of recursive calls depends on the number of doc comments on the
+// expr block. On each recursive call, the `#[allow(deprecated)]` attribute(s) on
+// the `0` somehow get duplicated, resulting in 1, 2, 4, 8, ... identical
+// attributes.
+//
+// After the fix, the code compiles quickly and normally.
+
+macro_rules! m1 {
+    ($(#[$meta:meta])* { $e:expr }) => {
+        m1! { expr: { $e }, unprocessed: [$(#[$meta])*] }
+    };
+
+    (expr: { $e:expr }, unprocessed: [ #[$meta:meta] $($metas:tt)* ]) => {
+        m1! { expr: { $e }, unprocessed: [ $($metas)* ] }
+    };
+
+    (expr: { $e:expr }, unprocessed: []) => {
+        { $e }
+    }
+}
+
+macro_rules! m2 {
+    ($(#[$meta:meta])* { $e:stmt }) => {
+        m2! { stmt: { $e }, unprocessed: [$(#[$meta])*] }
+    };
+
+    (stmt: { $e:stmt }, unprocessed: [ #[$meta:meta] $($metas:tt)* ]) => {
+        m2! { stmt: { $e }, unprocessed: [ $($metas)* ] }
+    };
+
+    (stmt: { $e:stmt }, unprocessed: []) => {
+        { $e }
+    }
+}
+
+macro_rules! m3 {
+    ($(#[$meta:meta])* { $e:item }) => {
+        m3! { item: { $e }, unprocessed: [$(#[$meta])*] }
+    };
+
+    (item: { $e:item }, unprocessed: [ #[$meta:meta] $($metas:tt)* ]) => {
+        m3! { item: { $e }, unprocessed: [ $($metas)* ] }
+    };
+
+    (item: { $e:item }, unprocessed: []) => {
+        { $e }
+    }
+}
+
+fn main() {
+    // Each additional doc comment line doubles the compile time.
+    m1!(
+        /// a1
+        /// a2
+        /// a3
+        /// a4
+        /// a5
+        /// a6
+        /// a7
+        /// a8
+        /// a9
+        /// a10
+        /// a11
+        /// a12
+        /// a13
+        /// a14
+        /// a15
+        /// a16
+        /// a17
+        /// a18
+        /// a19
+        /// a20
+        {
+            #[allow(deprecated)] 0
+        }
+    );
+
+    m2!(
+        /// a1
+        /// a2
+        /// a3
+        /// a4
+        /// a5
+        /// a6
+        /// a7
+        /// a8
+        /// a9
+        /// a10
+        /// a11
+        /// a12
+        /// a13
+        /// a14
+        /// a15
+        /// a16
+        /// a17
+        /// a18
+        /// a19
+        /// a20
+        {
+            #[allow(deprecated)] let x = 5
+        }
+    );
+
+    m3!(
+        /// a1
+        /// a2
+        /// a3
+        /// a4
+        /// a5
+        /// a6
+        /// a7
+        /// a8
+        /// a9
+        /// a10
+        /// a11
+        /// a12
+        /// a13
+        /// a14
+        /// a15
+        /// a16
+        /// a17
+        /// a18
+        /// a19
+        /// a20
+        {
+            #[allow(deprecated)] struct S;
+        }
+    );
+}
diff --git a/tests/ui/attributes/inner-attr-metavar.rs b/tests/ui/attributes/inner-attr-metavar.rs
new file mode 100644
index 00000000000..345121c252e
--- /dev/null
+++ b/tests/ui/attributes/inner-attr-metavar.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+//
+// During `Nonterminal` removal (#124141) there was at one point a problem with
+// calling from_ast on expressions with inner attributes within metavars -- the
+// inner attributes were being inserted in the wrong place in `from_ast`. This
+// test covers that case.
+
+macro_rules! m3 { ($e:expr) => {} }
+macro_rules! m2 { ($e:expr) => { m3!($e); } }
+macro_rules! m1 { ($e:expr) => { m2!($e); } }
+
+m1!({ #![allow(unused)] 0 });
+
+fn main() {}
diff --git a/tests/ui/attributes/nonterminal-expansion.rs b/tests/ui/attributes/nonterminal-expansion.rs
index 83c8f00999a..004a8a23fd6 100644
--- a/tests/ui/attributes/nonterminal-expansion.rs
+++ b/tests/ui/attributes/nonterminal-expansion.rs
@@ -5,8 +5,7 @@
 macro_rules! pass_nonterminal {
     ($n:expr) => {
         #[repr(align($n))]
-        //~^ ERROR expected unsuffixed literal, found expression `n!()`
-        //~^^ ERROR incorrect `repr(align)` attribute format: `align` expects a literal integer as argument [E0693]
+        //~^ ERROR expected unsuffixed literal, found `expr` metavariable
         struct S;
     };
 }
@@ -16,5 +15,6 @@ macro_rules! n {
 }
 
 pass_nonterminal!(n!());
+//~^ ERROR incorrect `repr(align)` attribute format: `align` expects a literal integer as argument [E0693]
 
 fn main() {}
diff --git a/tests/ui/attributes/nonterminal-expansion.stderr b/tests/ui/attributes/nonterminal-expansion.stderr
index 8a85731bd5a..9c6cb98f619 100644
--- a/tests/ui/attributes/nonterminal-expansion.stderr
+++ b/tests/ui/attributes/nonterminal-expansion.stderr
@@ -1,4 +1,4 @@
-error: expected unsuffixed literal, found expression `n!()`
+error: expected unsuffixed literal, found `expr` metavariable
   --> $DIR/nonterminal-expansion.rs:7:22
    |
 LL |         #[repr(align($n))]
@@ -10,15 +10,10 @@ LL | pass_nonterminal!(n!());
    = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0693]: incorrect `repr(align)` attribute format: `align` expects a literal integer as argument
-  --> $DIR/nonterminal-expansion.rs:7:22
+  --> $DIR/nonterminal-expansion.rs:17:19
    |
-LL |         #[repr(align($n))]
-   |                      ^^
-...
 LL | pass_nonterminal!(n!());
-   | ----------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
+   |                   ^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/attributes/z-crate-attr/garbage.rs b/tests/ui/attributes/z-crate-attr/garbage.rs
index ec81dd1bcaa..69444e1935a 100644
--- a/tests/ui/attributes/z-crate-attr/garbage.rs
+++ b/tests/ui/attributes/z-crate-attr/garbage.rs
@@ -1,4 +1,7 @@
 // Show diagnostics for invalid tokens
 //@ compile-flags: -Zcrate-attr=`%~@$#
-//@ error-pattern:unknown start of token
+
 fn main() {}
+
+//~? ERROR unknown start of token: `
+//~? ERROR expected identifier, found `%`
diff --git a/tests/ui/attributes/z-crate-attr/injection.rs b/tests/ui/attributes/z-crate-attr/injection.rs
index 0c5c81ca71a..a91f9d2886e 100644
--- a/tests/ui/attributes/z-crate-attr/injection.rs
+++ b/tests/ui/attributes/z-crate-attr/injection.rs
@@ -1,3 +1,5 @@
 //@ compile-flags: '-Zcrate-attr=feature(yeet_expr)]fn main(){}#[inline'
-//@ error-pattern:unexpected closing delimiter
+
 fn foo() {}
+
+//~? ERROR unexpected closing delimiter: `]`
diff --git a/tests/ui/attributes/z-crate-attr/inner-attr.rs b/tests/ui/attributes/z-crate-attr/inner-attr.rs
index 522c906dcd8..47ecad70062 100644
--- a/tests/ui/attributes/z-crate-attr/inner-attr.rs
+++ b/tests/ui/attributes/z-crate-attr/inner-attr.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: -Zcrate-attr=#![feature(foo)]
-//@ error-pattern:expected identifier
 
 fn main() {}
+
+//~? ERROR expected identifier, found `#`
diff --git a/tests/ui/attributes/z-crate-attr/multiple.rs b/tests/ui/attributes/z-crate-attr/multiple.rs
index ee13253f625..47d35d2c3fd 100644
--- a/tests/ui/attributes/z-crate-attr/multiple.rs
+++ b/tests/ui/attributes/z-crate-attr/multiple.rs
@@ -1,3 +1,5 @@
 //@ compile-flags: -Zcrate-attr=feature(foo),feature(bar)
-//@ error-pattern:invalid crate attr
+
 fn main() {}
+
+//~? ERROR invalid crate attribute
diff --git a/tests/ui/attributes/z-crate-attr/unbalanced-paren.rs b/tests/ui/attributes/z-crate-attr/unbalanced-paren.rs
index fc1d7f39a59..77d5d698f65 100644
--- a/tests/ui/attributes/z-crate-attr/unbalanced-paren.rs
+++ b/tests/ui/attributes/z-crate-attr/unbalanced-paren.rs
@@ -1,4 +1,6 @@
 // Show diagnostics for unbalanced parens.
 //@ compile-flags: -Zcrate-attr=(
-//@ error-pattern:unclosed delimiter
+
 fn main() {}
+
+//~? ERROR this file contains an unclosed delimiter
diff --git a/tests/ui/autodiff/autodiff_illegal.rs b/tests/ui/autodiff/autodiff_illegal.rs
index e810b9ba565..2f2cd8d9353 100644
--- a/tests/ui/autodiff/autodiff_illegal.rs
+++ b/tests/ui/autodiff/autodiff_illegal.rs
@@ -177,4 +177,11 @@ fn f21(x: f32) -> f32 {
     unimplemented!()
 }
 
+struct DoesNotImplDefault;
+#[autodiff(df22, Forward, Dual)]
+pub fn f22() -> DoesNotImplDefault {
+    //~^^ ERROR the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied
+    unimplemented!()
+}
+
 fn main() {}
diff --git a/tests/ui/autodiff/autodiff_illegal.stderr b/tests/ui/autodiff/autodiff_illegal.stderr
index 47d53492700..3752b27e7dd 100644
--- a/tests/ui/autodiff/autodiff_illegal.stderr
+++ b/tests/ui/autodiff/autodiff_illegal.stderr
@@ -19,32 +19,24 @@ error: expected 1 activities, but found 2
    |
 LL | #[autodiff(df3, Reverse, Duplicated, Const)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected 1 activities, but found 0
   --> $DIR/autodiff_illegal.rs:27:1
    |
 LL | #[autodiff(df4, Reverse)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: Dual can not be used in Reverse Mode
   --> $DIR/autodiff_illegal.rs:34:1
    |
 LL | #[autodiff(df5, Reverse, Dual)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: Duplicated can not be used in Forward Mode
   --> $DIR/autodiff_illegal.rs:41:1
    |
 LL | #[autodiff(df6, Forward, Duplicated)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: Duplicated can not be used for this type
   --> $DIR/autodiff_illegal.rs:42:14
@@ -107,7 +99,6 @@ LL | #[autodiff(fn_exists, Reverse, Active)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fn_exists` redefined here
    |
    = note: `fn_exists` must be defined only once in the value namespace of this module
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: autodiff requires at least a name and mode
   --> $DIR/autodiff_illegal.rs:95:1
@@ -135,42 +126,49 @@ error: invalid return activity Active in Forward Mode
    |
 LL | #[autodiff(df19, Forward, Dual, Active)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: invalid return activity Dual in Reverse Mode
   --> $DIR/autodiff_illegal.rs:167:1
    |
 LL | #[autodiff(df20, Reverse, Active, Dual)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: invalid return activity Duplicated in Reverse Mode
   --> $DIR/autodiff_illegal.rs:174:1
    |
 LL | #[autodiff(df21, Reverse, Active, Duplicated)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0433]: failed to resolve: use of undeclared type `MyFloat`
   --> $DIR/autodiff_illegal.rs:130:1
    |
 LL | #[autodiff(df15, Reverse, Active, Active)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat`
-   |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0433]: failed to resolve: use of undeclared type `F64Trans`
   --> $DIR/autodiff_illegal.rs:154:1
    |
 LL | #[autodiff(df18, Reverse, Active, Active)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans`
+
+error[E0599]: the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied
+  --> $DIR/autodiff_illegal.rs:181:1
+   |
+LL | struct DoesNotImplDefault;
+   | ------------------------- doesn't satisfy `DoesNotImplDefault: Default`
+LL | #[autodiff(df22, Forward, Dual)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item cannot be called on `(DoesNotImplDefault, DoesNotImplDefault)` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `DoesNotImplDefault: Default`
+           which is required by `(DoesNotImplDefault, DoesNotImplDefault): Default`
+help: consider annotating `DoesNotImplDefault` with `#[derive(Default)]`
+   |
+LL + #[derive(Default)]
+LL | struct DoesNotImplDefault;
    |
-   = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 22 previous errors
+error: aborting due to 23 previous errors
 
-Some errors have detailed explanations: E0428, E0433, E0658.
+Some errors have detailed explanations: E0428, E0433, E0599, E0658.
 For more information about an error, try `rustc --explain E0428`.
diff --git a/tests/ui/binop/binop-bitxor-str.rs b/tests/ui/binop/binop-bitxor-str.rs
index d59e46167fe..3072fa6ae90 100644
--- a/tests/ui/binop/binop-bitxor-str.rs
+++ b/tests/ui/binop/binop-bitxor-str.rs
@@ -1,3 +1,2 @@
-//@ error-pattern:no implementation for `String ^ String`
-
 fn main() { let x = "a".to_string() ^ "b".to_string(); }
+//~^ ERROR no implementation for `String ^ String`
diff --git a/tests/ui/binop/binop-bitxor-str.stderr b/tests/ui/binop/binop-bitxor-str.stderr
index 9d9ec6c5af6..d4bb0c17bfa 100644
--- a/tests/ui/binop/binop-bitxor-str.stderr
+++ b/tests/ui/binop/binop-bitxor-str.stderr
@@ -1,5 +1,5 @@
 error[E0369]: no implementation for `String ^ String`
-  --> $DIR/binop-bitxor-str.rs:3:37
+  --> $DIR/binop-bitxor-str.rs:1:37
    |
 LL | fn main() { let x = "a".to_string() ^ "b".to_string(); }
    |                     --------------- ^ --------------- String
diff --git a/tests/ui/binop/binop-mul-bool.rs b/tests/ui/binop/binop-mul-bool.rs
index 0b4ed21a12d..706195d215c 100644
--- a/tests/ui/binop/binop-mul-bool.rs
+++ b/tests/ui/binop/binop-mul-bool.rs
@@ -1,3 +1 @@
-//@ error-pattern:cannot multiply `bool` by `bool`
-
-fn main() { let x = true * false; }
+fn main() { let x = true * false; } //~ ERROR cannot multiply `bool` by `bool`
diff --git a/tests/ui/binop/binop-mul-bool.stderr b/tests/ui/binop/binop-mul-bool.stderr
index 82d066f45a4..7fa70f65f56 100644
--- a/tests/ui/binop/binop-mul-bool.stderr
+++ b/tests/ui/binop/binop-mul-bool.stderr
@@ -1,5 +1,5 @@
 error[E0369]: cannot multiply `bool` by `bool`
-  --> $DIR/binop-mul-bool.rs:3:26
+  --> $DIR/binop-mul-bool.rs:1:26
    |
 LL | fn main() { let x = true * false; }
    |                     ---- ^ ----- bool
diff --git a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs
index 6f323d91227..9d323bf0324 100644
--- a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs
+++ b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs
@@ -1,6 +1,5 @@
-#![feature(rustc_attrs)]
 #![allow(dead_code)]
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
     // Original borrow ends at end of function
     let mut x = 1;
     let y = &mut x;
diff --git a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr
index db73d4c04ac..444a74cbfcf 100644
--- a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr
+++ b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr
@@ -1,5 +1,5 @@
 error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-report-with-custom-diagnostic.rs:8:13
+  --> $DIR/borrowck-report-with-custom-diagnostic.rs:7:13
    |
 LL |     let y = &mut x;
    |             ------ mutable borrow occurs here
@@ -11,7 +11,7 @@ LL |     y.use_mut();
    |     - mutable borrow later used here
 
 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-report-with-custom-diagnostic.rs:21:21
+  --> $DIR/borrowck-report-with-custom-diagnostic.rs:20:21
    |
 LL |             let y = &x;
    |                     -- immutable borrow occurs here
@@ -23,7 +23,7 @@ LL |             y.use_ref();
    |             - immutable borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/borrowck-report-with-custom-diagnostic.rs:36:17
+  --> $DIR/borrowck-report-with-custom-diagnostic.rs:35:17
    |
 LL |         let y = &mut x;
    |                 ------ first mutable borrow occurs here
diff --git a/tests/ui/borrowck/mut-borrow-in-loop-2.stderr b/tests/ui/borrowck/mut-borrow-in-loop-2.stderr
index 4f32df1eb24..46e06bc91b9 100644
--- a/tests/ui/borrowck/mut-borrow-in-loop-2.stderr
+++ b/tests/ui/borrowck/mut-borrow-in-loop-2.stderr
@@ -12,10 +12,6 @@ help: consider creating a fresh reborrow of `value` here
    |
 LL |         Other::handle(&mut *value);
    |                       ++++++
-help: consider creating a fresh reborrow of `value` here
-   |
-LL |         Other::handle(&mut *value);
-   |                       ++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/borrowck/mut-borrow-outside-loop.rs b/tests/ui/borrowck/mut-borrow-outside-loop.rs
index c02bfbf8739..3cc362def38 100644
--- a/tests/ui/borrowck/mut-borrow-outside-loop.rs
+++ b/tests/ui/borrowck/mut-borrow-outside-loop.rs
@@ -1,6 +1,6 @@
 // ensure borrowck messages are correct outside special case
-#![feature(rustc_attrs)]
-fn main() { #![rustc_error] // rust-lang/rust#49855
+
+fn main() {
     let mut void = ();
 
     let first = &mut void;
diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs
index f952235be98..8eeb99a4cc1 100644
--- a/tests/ui/c-variadic/issue-86053-1.rs
+++ b/tests/ui/c-variadic/issue-86053-1.rs
@@ -1,12 +1,18 @@
 // Regression test for the ICE described in issue #86053.
-//@ error-pattern:unexpected `self` parameter in function
-//@ error-pattern:`...` must be the last argument of a C-variadic function
-//@ error-pattern:cannot find type `F` in this scope
-
 
 #![feature(c_variadic)]
 #![crate_type="lib"]
 
 fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
+    //~^ ERROR expected type, found `,`
+    //~| ERROR unexpected `self` parameter in function
+    //~| ERROR unexpected `self` parameter in function
+    //~| ERROR unexpected `self` parameter in function
     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
+    //~^ ERROR unexpected `self` parameter in function
+    //~| ERROR unexpected `self` parameter in function
+    //~| ERROR unexpected `self` parameter in function
+    //~| ERROR `...` must be the last argument of a C-variadic function
+    //~| ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
+    //~| ERROR cannot find type `F` in this scope
 }
diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr
index ce31f0d300f..dc323f9a234 100644
--- a/tests/ui/c-variadic/issue-86053-1.stderr
+++ b/tests/ui/c-variadic/issue-86053-1.stderr
@@ -1,23 +1,23 @@
 error: expected type, found `,`
-  --> $DIR/issue-86053-1.rs:10:47
+  --> $DIR/issue-86053-1.rs:6:47
    |
 LL | fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
    |                                               ^ expected type
 
 error: unexpected `self` parameter in function
-  --> $DIR/issue-86053-1.rs:10:51
+  --> $DIR/issue-86053-1.rs:6:51
    |
 LL | fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
    |                                                   ^^^^ must be the first parameter of an associated function
 
 error: unexpected `self` parameter in function
-  --> $DIR/issue-86053-1.rs:10:58
+  --> $DIR/issue-86053-1.rs:6:58
    |
 LL | fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
    |                                                          ^^^^ must be the first parameter of an associated function
 
 error: unexpected `self` parameter in function
-  --> $DIR/issue-86053-1.rs:10:67
+  --> $DIR/issue-86053-1.rs:6:67
    |
 LL | fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
    |                                                                   ^^^^ must be the first parameter of an associated function
diff --git a/tests/ui/capture1.rs b/tests/ui/capture1.rs
index 9bf6532a7d3..4f8c04e3fa9 100644
--- a/tests/ui/capture1.rs
+++ b/tests/ui/capture1.rs
@@ -1,6 +1,4 @@
-//@ error-pattern: can't capture dynamic environment in a fn item
-
 fn main() {
     let bar: isize = 5;
-    fn foo() -> isize { return bar; }
+    fn foo() -> isize { return bar; } //~ ERROR can't capture dynamic environment in a fn item
 }
diff --git a/tests/ui/capture1.stderr b/tests/ui/capture1.stderr
index 067b85ba619..8027430de52 100644
--- a/tests/ui/capture1.stderr
+++ b/tests/ui/capture1.stderr
@@ -1,5 +1,5 @@
 error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/capture1.rs:5:32
+  --> $DIR/capture1.rs:3:32
    |
 LL |     fn foo() -> isize { return bar; }
    |                                ^^^
diff --git a/tests/ui/cast/cast-from-nil.rs b/tests/ui/cast/cast-from-nil.rs
index 8a677603aa9..65e1eb31b21 100644
--- a/tests/ui/cast/cast-from-nil.rs
+++ b/tests/ui/cast/cast-from-nil.rs
@@ -1,2 +1 @@
-//@ error-pattern: non-primitive cast: `()` as `u32`
-fn main() { let u = (assert!(true) as u32); }
+fn main() { let u = (assert!(true) as u32); } //~ ERROR non-primitive cast: `()` as `u32`
diff --git a/tests/ui/cast/cast-from-nil.stderr b/tests/ui/cast/cast-from-nil.stderr
index 991ff93a8bd..82c53d71e78 100644
--- a/tests/ui/cast/cast-from-nil.stderr
+++ b/tests/ui/cast/cast-from-nil.stderr
@@ -1,5 +1,5 @@
 error[E0605]: non-primitive cast: `()` as `u32`
-  --> $DIR/cast-from-nil.rs:2:21
+  --> $DIR/cast-from-nil.rs:1:21
    |
 LL | fn main() { let u = (assert!(true) as u32); }
    |                     ^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
diff --git a/tests/ui/cast/cast-to-nil.rs b/tests/ui/cast/cast-to-nil.rs
index d91f9a16a07..7cd864471dd 100644
--- a/tests/ui/cast/cast-to-nil.rs
+++ b/tests/ui/cast/cast-to-nil.rs
@@ -1,2 +1 @@
-//@ error-pattern: non-primitive cast: `u32` as `()`
-fn main() { let u = 0u32 as (); }
+fn main() { let u = 0u32 as (); } //~ ERROR non-primitive cast: `u32` as `()`
diff --git a/tests/ui/cast/cast-to-nil.stderr b/tests/ui/cast/cast-to-nil.stderr
index 14c75983b94..d7121a7adba 100644
--- a/tests/ui/cast/cast-to-nil.stderr
+++ b/tests/ui/cast/cast-to-nil.stderr
@@ -1,5 +1,5 @@
 error[E0605]: non-primitive cast: `u32` as `()`
-  --> $DIR/cast-to-nil.rs:2:21
+  --> $DIR/cast-to-nil.rs:1:21
    |
 LL | fn main() { let u = 0u32 as (); }
    |                     ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs
deleted file mode 100644
index cfc0a97989d..00000000000
--- a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Combination of `ptr-to-trait-obj-wrap.rs` and `ptr-to-trait-obj-add-auto.rs`.
-//
-// Checks that you *can't* add auto traits to trait object in pointer casts involving wrapping said
-// traits structures.
-
-trait A {}
-
-struct W<T: ?Sized>(T);
-struct X<T: ?Sized>(T);
-
-fn unwrap(a: *const W<dyn A>) -> *const (dyn A + Send) {
-    a as _
-    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
-}
-
-fn unwrap_nested(a: *const W<W<dyn A>>) -> *const W<dyn A + Send> {
-    a as _
-    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
-}
-
-fn rewrap(a: *const W<dyn A>) -> *const X<dyn A + Send> {
-    a as _
-    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
-}
-
-fn rewrap_nested(a: *const W<W<dyn A>>) -> *const W<X<dyn A + Send>> {
-    a as _
-    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
-}
-
-fn wrap(a: *const dyn A) -> *const W<dyn A + Send> {
-    a as _
-    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
-}
-
-fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr
deleted file mode 100644
index 42cdbc34ee8..00000000000
--- a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr
+++ /dev/null
@@ -1,48 +0,0 @@
-error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
-  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5
-   |
-LL |     a as _
-   |     ^^^^^^ unsupported cast
-   |
-   = note: this could allow UB elsewhere
-   = help: use `transmute` if you're sure this is sound
-
-error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
-  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:17:5
-   |
-LL |     a as _
-   |     ^^^^^^ unsupported cast
-   |
-   = note: this could allow UB elsewhere
-   = help: use `transmute` if you're sure this is sound
-
-error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
-  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:22:5
-   |
-LL |     a as _
-   |     ^^^^^^ unsupported cast
-   |
-   = note: this could allow UB elsewhere
-   = help: use `transmute` if you're sure this is sound
-
-error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
-  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:27:5
-   |
-LL |     a as _
-   |     ^^^^^^ unsupported cast
-   |
-   = note: this could allow UB elsewhere
-   = help: use `transmute` if you're sure this is sound
-
-error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
-  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:32:5
-   |
-LL |     a as _
-   |     ^^^^^^ unsupported cast
-   |
-   = note: this could allow UB elsewhere
-   = help: use `transmute` if you're sure this is sound
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0804`.
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs
deleted file mode 100644
index ebe7a06a7a1..00000000000
--- a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Combination of `ptr-to-trait-obj-different-args.rs` and `ptr-to-trait-obj-wrap.rs`.
-//
-// Checks that you *can't* change type arguments of trait objects in pointer casts involving
-// wrapping said traits structures.
-
-trait A<T> {}
-
-struct W<T: ?Sized>(T);
-struct X<T: ?Sized>(T);
-
-fn unwrap<F, G>(a: *const W<dyn A<F>>) -> *const dyn A<G> {
-    a as _
-    //~^ error casting `*const W<(dyn A<F> + 'static)>` as `*const dyn A<G>` is invalid
-}
-
-fn unwrap_nested<F, G>(a: *const W<W<dyn A<F>>>) -> *const W<dyn A<G>> {
-    a as _
-    //~^ error casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<dyn A<G>>` is invalid
-}
-
-fn rewrap<F, G>(a: *const W<dyn A<F>>) -> *const X<dyn A<G>> {
-    a as _
-    //~^ error: casting `*const W<(dyn A<F> + 'static)>` as `*const X<dyn A<G>>` is invalid
-}
-
-fn rewrap_nested<F, G>(a: *const W<W<dyn A<F>>>) -> *const W<X<dyn A<G>>> {
-    a as _
-    //~^ error: casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<X<dyn A<G>>>` is invalid
-}
-
-fn wrap<F, G>(a: *const dyn A<F>) -> *const W<dyn A<G>> {
-    a as _
-    //~^ error: casting `*const (dyn A<F> + 'static)` as `*const W<dyn A<G>>` is invalid
-}
-
-fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr
deleted file mode 100644
index 4f85b208d05..00000000000
--- a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr
+++ /dev/null
@@ -1,43 +0,0 @@
-error[E0606]: casting `*const W<(dyn A<F> + 'static)>` as `*const dyn A<G>` is invalid
-  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5
-   |
-LL |     a as _
-   |     ^^^^^^
-   |
-   = note: the trait objects may have different vtables
-
-error[E0606]: casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<dyn A<G>>` is invalid
-  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:17:5
-   |
-LL |     a as _
-   |     ^^^^^^
-   |
-   = note: the trait objects may have different vtables
-
-error[E0606]: casting `*const W<(dyn A<F> + 'static)>` as `*const X<dyn A<G>>` is invalid
-  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:22:5
-   |
-LL |     a as _
-   |     ^^^^^^
-   |
-   = note: the trait objects may have different vtables
-
-error[E0606]: casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<X<dyn A<G>>>` is invalid
-  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:27:5
-   |
-LL |     a as _
-   |     ^^^^^^
-   |
-   = note: the trait objects may have different vtables
-
-error[E0606]: casting `*const (dyn A<F> + 'static)` as `*const W<dyn A<G>>` is invalid
-  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:32:5
-   |
-LL |     a as _
-   |     ^^^^^^
-   |
-   = note: the trait objects may have different vtables
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0606`.
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs
deleted file mode 100644
index b0941277d01..00000000000
--- a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Combination of `ptr-to-trait-obj-different-regions-misc.rs` and `ptr-to-trait-obj-wrap.rs`.
-//
-// Checks that you *can't* change lifetime arguments of trait objects in pointer casts involving
-// wrapping said traits structures.
-
-trait A<'a> {}
-
-struct W<T: ?Sized>(T);
-struct X<T: ?Sized>(T);
-
-fn unwrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const dyn A<'b> {
-    a as _
-    //~^ error
-    //~| error
-}
-
-fn unwrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<dyn A<'b>> {
-    a as _
-    //~^ error
-    //~| error
-}
-
-fn rewrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const X<dyn A<'b>> {
-    a as _
-    //~^ error: lifetime may not live long enough
-    //~| error: lifetime may not live long enough
-}
-
-fn rewrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
-    a as _
-    //~^ error: lifetime may not live long enough
-    //~| error: lifetime may not live long enough
-}
-
-fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W<dyn A<'b>> {
-    a as _
-    //~^ error: lifetime may not live long enough
-    //~| error: lifetime may not live long enough
-}
-
-fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr
deleted file mode 100644
index 17a0ca3c34f..00000000000
--- a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr
+++ /dev/null
@@ -1,140 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5
-   |
-LL | fn unwrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const dyn A<'b> {
-   |           --  -- lifetime `'b` defined here
-   |           |
-   |           lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
-   |
-   = help: consider adding the following bound: `'b: 'a`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5
-   |
-LL | fn unwrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const dyn A<'b> {
-   |           --  -- lifetime `'b` defined here
-   |           |
-   |           lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
-   |
-   = help: consider adding the following bound: `'a: 'b`
-
-help: `'b` and `'a` must be the same: replace one with the other
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5
-   |
-LL | fn unwrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<dyn A<'b>> {
-   |                  --  -- lifetime `'b` defined here
-   |                  |
-   |                  lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
-   |
-   = help: consider adding the following bound: `'b: 'a`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5
-   |
-LL | fn unwrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<dyn A<'b>> {
-   |                  --  -- lifetime `'b` defined here
-   |                  |
-   |                  lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
-   |
-   = help: consider adding the following bound: `'a: 'b`
-
-help: `'b` and `'a` must be the same: replace one with the other
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5
-   |
-LL | fn rewrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const X<dyn A<'b>> {
-   |           --  -- lifetime `'b` defined here
-   |           |
-   |           lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
-   |
-   = help: consider adding the following bound: `'b: 'a`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5
-   |
-LL | fn rewrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const X<dyn A<'b>> {
-   |           --  -- lifetime `'b` defined here
-   |           |
-   |           lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
-   |
-   = help: consider adding the following bound: `'a: 'b`
-
-help: `'b` and `'a` must be the same: replace one with the other
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5
-   |
-LL | fn rewrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
-   |                  --  -- lifetime `'b` defined here
-   |                  |
-   |                  lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
-   |
-   = help: consider adding the following bound: `'b: 'a`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5
-   |
-LL | fn rewrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
-   |                  --  -- lifetime `'b` defined here
-   |                  |
-   |                  lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
-   |
-   = help: consider adding the following bound: `'a: 'b`
-
-help: `'b` and `'a` must be the same: replace one with the other
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5
-   |
-LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W<dyn A<'b>> {
-   |         --  -- lifetime `'b` defined here
-   |         |
-   |         lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
-   |
-   = help: consider adding the following bound: `'b: 'a`
-
-error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5
-   |
-LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W<dyn A<'b>> {
-   |         --  -- lifetime `'b` defined here
-   |         |
-   |         lifetime `'a` defined here
-LL |     a as _
-   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
-   |
-   = help: consider adding the following bound: `'a: 'b`
-
-help: `'b` and `'a` must be the same: replace one with the other
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 10 previous errors
-
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.rs b/tests/ui/cast/ptr-to-trait-obj-wrap.rs
deleted file mode 100644
index 9809ea80f95..00000000000
--- a/tests/ui/cast/ptr-to-trait-obj-wrap.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Checks that various casts of pointers to trait objects wrapped in structures
-// work. Note that the metadata doesn't change when a DST is wrapped in a
-// structure, so these casts *are* fine.
-//
-//@ check-pass
-
-trait A {}
-
-struct W<T: ?Sized>(T);
-struct X<T: ?Sized>(T);
-
-fn unwrap(a: *const W<dyn A>) -> *const dyn A {
-    a as _
-}
-
-fn unwrap_nested(a: *const W<W<dyn A>>) -> *const W<dyn A> {
-    a as _
-}
-
-fn rewrap(a: *const W<dyn A>) -> *const X<dyn A> {
-    a as _
-}
-
-fn rewrap_nested(a: *const W<W<dyn A>>) -> *const W<X<dyn A>> {
-    a as _
-}
-
-fn wrap(a: *const dyn A) -> *const W<dyn A> {
-    a as _
-}
-
-fn main() {}
diff --git a/tests/ui/cfg/cfg_false_no_std-2.rs b/tests/ui/cfg/cfg_false_no_std-2.rs
index cd337565872..35e545aae34 100644
--- a/tests/ui/cfg/cfg_false_no_std-2.rs
+++ b/tests/ui/cfg/cfg_false_no_std-2.rs
@@ -1,7 +1,8 @@
 // Error, the linked empty library is `no_std` and doesn't provide a panic handler.
 
-//@ dont-check-compiler-stderr
+//@ compile-flags: --error-format=human
 //@ error-pattern: `#[panic_handler]` function required, but not found
+//@ dont-check-compiler-stderr
 //@ aux-build: cfg_false_lib_no_std_before.rs
 
 #![no_std]
@@ -9,3 +10,7 @@
 extern crate cfg_false_lib_no_std_before as _;
 
 fn main() {}
+
+// FIXME: The second error is target-dependent.
+//FIXME~? ERROR `#[panic_handler]` function required, but not found
+//FIXME~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/cfg/raw-true-false.rs b/tests/ui/cfg/raw-true-false.rs
index 4cb8bb71c92..c92672fc144 100644
--- a/tests/ui/cfg/raw-true-false.rs
+++ b/tests/ui/cfg/raw-true-false.rs
@@ -1,19 +1,11 @@
 //@ check-pass
-//@ compile-flags: --cfg false --check-cfg=cfg(r#false)
-
-#![deny(warnings)]
-
-#[expect(unexpected_cfgs)]
-mod a {
-  #[cfg(r#true)]
-  pub fn foo() {}
-}
-
-mod b {
-  #[cfg(r#false)]
-  pub fn bar() {}
-}
-
+//@ revisions: r0x0 r0x1 r1x0 r1x1
+//@[r0x0] compile-flags: --cfg false --check-cfg=cfg(false)
+//@[r0x1] compile-flags: --cfg false --check-cfg=cfg(r#false)
+//@[r1x0] compile-flags: --cfg r#false --check-cfg=cfg(false)
+//@[r1x1] compile-flags: --cfg r#false --check-cfg=cfg(r#false)
+#![deny(unexpected_cfgs)]
 fn main() {
-    b::bar()
+    #[cfg(not(r#false))]
+    compile_error!("");
 }
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 e7b8f355057..b07d630e5f5 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr
@@ -14,7 +14,7 @@ warning: unexpected `cfg` condition value: `value`
 LL | #[cfg(target_vendor = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `openwrt`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition name: `feature`
diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
index 95af0a90929..80f8f36c23f 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
@@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value`
 LL | #[cfg(target_vendor = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `openwrt`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `unk`
diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
index 95af0a90929..80f8f36c23f 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
@@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value`
 LL | #[cfg(target_vendor = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `openwrt`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `unk`
diff --git a/tests/ui/check-cfg/invalid-arguments.boolean.stderr b/tests/ui/check-cfg/invalid-arguments.boolean.stderr
deleted file mode 100644
index 18734de9dac..00000000000
--- a/tests/ui/check-cfg/invalid-arguments.boolean.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-error: invalid `--check-cfg` argument: `cfg(true)`
-   |
-   = note: `true` is a boolean literal
-   = note: `cfg()` arguments must be simple identifiers, `any()` or `values(...)`
-   = note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
-
diff --git a/tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr b/tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr
new file mode 100644
index 00000000000..3aa2205d3b1
--- /dev/null
+++ b/tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr
@@ -0,0 +1,5 @@
+error: invalid `--check-cfg` argument: `cfg(values(),true)`
+   |
+   = note: `values()` cannot be specified before the names
+   = note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
+
diff --git a/tests/ui/check-cfg/invalid-arguments.rs b/tests/ui/check-cfg/invalid-arguments.rs
index 3bea128e3e4..279b13b6972 100644
--- a/tests/ui/check-cfg/invalid-arguments.rs
+++ b/tests/ui/check-cfg/invalid-arguments.rs
@@ -2,7 +2,7 @@
 //
 //@ check-fail
 //@ no-auto-check-cfg
-//@ revisions: anything_else boolean
+//@ revisions: anything_else boolean_after_values
 //@ revisions: string_for_name_1 string_for_name_2 multiple_any multiple_values
 //@ revisions: multiple_values_any not_empty_any not_empty_values_any
 //@ revisions: values_any_missing_values values_any_before_ident ident_in_values_1
@@ -11,7 +11,7 @@
 //@ revisions: none_not_empty cfg_none unsafe_attr
 //
 //@ [anything_else]compile-flags: --check-cfg=anything_else(...)
-//@ [boolean]compile-flags: --check-cfg=cfg(true)
+//@ [boolean_after_values]compile-flags: --check-cfg=cfg(values(),true)
 //@ [string_for_name_1]compile-flags: --check-cfg=cfg("NOT_IDENT")
 //@ [string_for_name_2]compile-flags: --check-cfg=cfg(foo,"NOT_IDENT",bar)
 //@ [multiple_any]compile-flags: --check-cfg=cfg(any(),any())
diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr
index a9d67481ba1..aa5fd09c0c7 100644
--- a/tests/ui/check-cfg/target_feature.stderr
+++ b/tests/ui/check-cfg/target_feature.stderr
@@ -17,11 +17,16 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `aes`
 `altivec`
 `alu32`
+`amx-avx512`
 `amx-bf16`
 `amx-complex`
 `amx-fp16`
+`amx-fp8`
 `amx-int8`
+`amx-movrs`
+`amx-tf32`
 `amx-tile`
+`amx-transpose`
 `atomics`
 `avx`
 `avx2`
@@ -152,6 +157,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `mclass`
 `mops`
 `movbe`
+`movrs`
 `mp`
 `mp1e2`
 `msa`
@@ -245,6 +251,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `trustzone`
 `ual`
 `unaligned-scalar-mem`
+`unaligned-vector-mem`
 `v`
 `v5te`
 `v6`
@@ -317,6 +324,11 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `zfinx`
 `zhinx`
 `zhinxmin`
+`zicntr`
+`zicsr`
+`zifencei`
+`zihintpause`
+`zihpm`
 `zk`
 `zkn`
 `zknd`
@@ -325,7 +337,42 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `zkr`
 `zks`
 `zksed`
-`zksh`, and `zkt`
+`zksh`
+`zkt`
+`zvbb`
+`zvbc`
+`zve32f`
+`zve32x`
+`zve64d`
+`zve64f`
+`zve64x`
+`zvfh`
+`zvfhmin`
+`zvkb`
+`zvkg`
+`zvkn`
+`zvknc`
+`zvkned`
+`zvkng`
+`zvknha`
+`zvknhb`
+`zvks`
+`zvksc`
+`zvksed`
+`zvksg`
+`zvksh`
+`zvkt`
+`zvl1024b`
+`zvl128b`
+`zvl16384b`
+`zvl2048b`
+`zvl256b`
+`zvl32768b`
+`zvl32b`
+`zvl4096b`
+`zvl512b`
+`zvl64b`
+`zvl65536b`, and `zvl8192b`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index ba1900fcddb..4636b6945d0 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -230,7 +230,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_vendor = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
+   = note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `openwrt`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs
deleted file mode 100644
index eda83e999a5..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
-
-fn main() {
-    let a = {
-        let v = 0;
-        &v as *const _ as usize
-    };
-    let b = {
-        let v = 0;
-        &v as *const _ as usize
-    };
-
-    assert_ne!(a, b);
-    assert_ne!(a, b);
-    let c = a;
-    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false");
-    println!("{a} {b}");
-    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true");
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
deleted file mode 100644
index c7f46318aae..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
-
-use std::ptr;
-
-fn main() {
-    let a: usize = {
-        let v = 0;
-        ptr::from_ref(&v).expose_provenance()
-    };
-    let b: usize = {
-        let v = 0;
-        ptr::from_ref(&v).expose_provenance()
-    };
-
-    assert_ne!(a, b);
-    assert_ne!(a, b);
-    let c = a;
-    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false");
-    println!("{a} {b}");
-    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true");
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
deleted file mode 100644
index a02ff30918d..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
-
-use std::ptr;
-
-fn main() {
-    let a: usize = {
-        let v = 0;
-        ptr::from_ref(&v).addr()
-    };
-    let b: usize = {
-        let v = 0;
-        ptr::from_ref(&v).addr()
-    };
-
-    assert_ne!(a, b);
-    assert_ne!(a, b);
-    let c = a;
-    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false");
-    println!("{a} {b}");
-    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true");
-}
diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs
index 955f917ee33..194bcaa307f 100644
--- a/tests/ui/codegen/mismatched-data-layouts.rs
+++ b/tests/ui/codegen/mismatched-data-layouts.rs
@@ -3,7 +3,6 @@
 //@ build-fail
 //@ needs-llvm-components: x86
 //@ compile-flags: --crate-type=lib --target={{src-base}}/codegen/mismatched-data-layout.json -Z unstable-options
-//@ error-pattern: differs from LLVM target's
 //@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`"
 //@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`"
 
@@ -12,3 +11,5 @@
 
 #[lang = "sized"]
 trait Sized {}
+
+//~? ERROR differs from LLVM target's
diff --git a/tests/ui/codegen/mono-impossible-drop.rs b/tests/ui/codegen/mono-impossible-drop.rs
index dec013cfe54..c8a9554da43 100644
--- a/tests/ui/codegen/mono-impossible-drop.rs
+++ b/tests/ui/codegen/mono-impossible-drop.rs
@@ -1,3 +1,6 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
 //@ compile-flags: -Clink-dead-code=on --crate-type=lib
 //@ build-pass
 
diff --git a/tests/ui/codemap_tests/issue-11715.rs b/tests/ui/codemap_tests/issue-11715.rs
index 617d57ff75a..d0daaf444b3 100644
--- a/tests/ui/codemap_tests/issue-11715.rs
+++ b/tests/ui/codemap_tests/issue-11715.rs
@@ -1,5 +1,4 @@
-#![feature(rustc_attrs)]
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
     let mut x = "foo";
     let y = &mut x;
     let z = &mut x; //~ ERROR cannot borrow
diff --git a/tests/ui/codemap_tests/issue-11715.stderr b/tests/ui/codemap_tests/issue-11715.stderr
index 5d0cf718761..6b330560adb 100644
--- a/tests/ui/codemap_tests/issue-11715.stderr
+++ b/tests/ui/codemap_tests/issue-11715.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/issue-11715.rs:5:13
+  --> $DIR/issue-11715.rs:4:13
    |
 LL |     let y = &mut x;
    |             ------ first mutable borrow occurs here
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-3.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-3.rs
index c086b8d8c3f..ba55b1c08b1 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-3.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-3.rs
@@ -1,3 +1,5 @@
 //@ compile-flags: --cfg a::b
-//@ error-pattern: invalid `--cfg` argument: `a::b` (argument key must be an identifier)
+
 fn main() {}
+
+//~? ERROR invalid `--cfg` argument: `a::b` (argument key must be an identifier)
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-5.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-5.rs
index 6f0bf8cf5fe..d64aeead79c 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-5.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-5.rs
@@ -1,3 +1,5 @@
 //@ compile-flags: --cfg a=10
-//@ error-pattern: invalid `--cfg` argument: `a=10` (argument value must be a string)
+
 fn main() {}
+
+//~? ERROR invalid `--cfg` argument: `a=10` (argument value must be a string)
diff --git a/tests/ui/conditional-compilation/cfg-attr-cfg-2.rs b/tests/ui/conditional-compilation/cfg-attr-cfg-2.rs
index c801bbccedd..80735990015 100644
--- a/tests/ui/conditional-compilation/cfg-attr-cfg-2.rs
+++ b/tests/ui/conditional-compilation/cfg-attr-cfg-2.rs
@@ -1,8 +1,7 @@
-//@ error-pattern: `main` function not found
 //@ compile-flags: --cfg foo --check-cfg=cfg(foo,bar)
 
 // main is conditionally compiled, but the conditional compilation
 // is conditional too!
 
 #[cfg_attr(foo, cfg(bar))]
-fn main() { }
+fn main() { } //~ ERROR `main` function not found in crate `cfg_attr_cfg_2`
diff --git a/tests/ui/conditional-compilation/cfg-attr-cfg-2.stderr b/tests/ui/conditional-compilation/cfg-attr-cfg-2.stderr
index 64595241dc7..1febb430863 100644
--- a/tests/ui/conditional-compilation/cfg-attr-cfg-2.stderr
+++ b/tests/ui/conditional-compilation/cfg-attr-cfg-2.stderr
@@ -1,5 +1,5 @@
 error[E0601]: `main` function not found in crate `cfg_attr_cfg_2`
-  --> $DIR/cfg-attr-cfg-2.rs:8:14
+  --> $DIR/cfg-attr-cfg-2.rs:7:14
    |
 LL | fn main() { }
    |              ^ consider adding a `main` function to `$DIR/cfg-attr-cfg-2.rs`
diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs
index 416145a0c15..47418b4e091 100644
--- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs
+++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs
@@ -28,7 +28,7 @@ struct S9;
 macro_rules! generate_s10 {
     ($expr: expr) => {
         #[cfg(feature = $expr)]
-        //~^ ERROR expected unsuffixed literal, found expression `concat!("nonexistent")`
+        //~^ ERROR expected unsuffixed literal, found `expr` metavariable
         struct S10;
     }
 }
diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr
index d02d0d70a8b..66ce2ee9858 100644
--- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr
+++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr
@@ -54,7 +54,7 @@ LL | #[cfg(a = b"hi")]
    |           |
    |           help: consider removing the prefix
 
-error: expected unsuffixed literal, found expression `concat!("nonexistent")`
+error: expected unsuffixed literal, found `expr` metavariable
   --> $DIR/cfg-attr-syntax-validation.rs:30:25
    |
 LL |         #[cfg(feature = $expr)]
diff --git a/tests/ui/conditional-compilation/cfg-in-crate-1.rs b/tests/ui/conditional-compilation/cfg-in-crate-1.rs
index ecd3722bf4c..a1faa2397a3 100644
--- a/tests/ui/conditional-compilation/cfg-in-crate-1.rs
+++ b/tests/ui/conditional-compilation/cfg-in-crate-1.rs
@@ -1,3 +1 @@
-//@ error-pattern: `main` function not found
-
-#![cfg(FALSE)]
+#![cfg(FALSE)] //~ ERROR `main` function not found in crate `cfg_in_crate_1`
diff --git a/tests/ui/conditional-compilation/cfg-in-crate-1.stderr b/tests/ui/conditional-compilation/cfg-in-crate-1.stderr
index 6067a3a921c..126e10cf040 100644
--- a/tests/ui/conditional-compilation/cfg-in-crate-1.stderr
+++ b/tests/ui/conditional-compilation/cfg-in-crate-1.stderr
@@ -1,5 +1,5 @@
 error[E0601]: `main` function not found in crate `cfg_in_crate_1`
-  --> $DIR/cfg-in-crate-1.rs:3:15
+  --> $DIR/cfg-in-crate-1.rs:1:15
    |
 LL | #![cfg(FALSE)]
    |               ^ consider adding a `main` function to `$DIR/cfg-in-crate-1.rs`
diff --git a/tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.rs b/tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.rs
new file mode 100644
index 00000000000..231bb5252de
--- /dev/null
+++ b/tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.rs
@@ -0,0 +1,41 @@
+// compile-flags: -Znext-solver
+
+// Test for a weird diagnostics corner case. In the error reporting code, when reporting
+// fulfillment errors for goals A and B, we try to see if elaborating A will result in
+// another goal that can equate with B. That would signal that B is "implied by" A,
+// allowing us to skip reporting it, which is beneficial for cutting down on the number
+// of diagnostics we report. In the new trait solver especially, but even in the old trait
+// solver through things like defining opaque type usages, this `can_equate` call was not
+// properly taking the param-env of the goals, resulting in nested obligations that had
+// empty param-envs. If one of these nested obligations was a `ConstParamHasTy` goal, then
+// we would ICE, since those goals are particularly strict about the param-env they're
+// evaluated in.
+
+// This is morally a fix for <https://github.com/rust-lang/rust/issues/139314>, but that
+// repro uses details about how defining usages in the `check_opaque_well_formed` code
+// can spring out of type equality, and will likely stop failing soon coincidentally once
+// we start using `PostBorrowck` mode in that check.
+
+trait Foo: Baz<()> {}
+trait Baz<T> {}
+
+trait IdentityWithConstArgGoal<const N: usize> {
+    type Assoc;
+}
+impl<T, const N: usize> IdentityWithConstArgGoal<N> for T {
+    type Assoc = T;
+}
+
+fn unsatisfied<T, const N: usize>()
+where
+    T: Foo,
+    T: Baz<<T as IdentityWithConstArgGoal<N>>::Assoc>,
+{
+}
+
+fn test<const N: usize>() {
+    unsatisfied::<(), N>();
+    //~^ ERROR the trait bound `(): Foo` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.stderr b/tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.stderr
new file mode 100644
index 00000000000..77bba494552
--- /dev/null
+++ b/tests/ui/const-generics/const-param-has-ty-goal-in-error-implies.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/const-param-has-ty-goal-in-error-implies.rs:37:19
+   |
+LL |     unsatisfied::<(), N>();
+   |                   ^^ the trait `Foo` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/const-param-has-ty-goal-in-error-implies.rs:19:1
+   |
+LL | trait Foo: Baz<()> {}
+   | ^^^^^^^^^^^^^^^^^^
+note: required by a bound in `unsatisfied`
+  --> $DIR/const-param-has-ty-goal-in-error-implies.rs:31:8
+   |
+LL | fn unsatisfied<T, const N: usize>()
+   |    ----------- required by a bound in this function
+LL | where
+LL |     T: Foo,
+   |        ^^^ required by this bound in `unsatisfied`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-ptr/out_of_bounds_read.rs b/tests/ui/const-ptr/out_of_bounds_read.rs
index 312b53432b4..ccf45bf324a 100644
--- a/tests/ui/const-ptr/out_of_bounds_read.rs
+++ b/tests/ui/const-ptr/out_of_bounds_read.rs
@@ -1,5 +1,3 @@
-//@ error-pattern: evaluation of constant value failed
-
 fn main() {
     use std::ptr;
 
@@ -8,6 +6,9 @@ fn main() {
     const PAST_END_PTR: *const u32 = unsafe { DATA.as_ptr().add(1) };
 
     const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
+    //~^ ERROR evaluation of constant value failed
     const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
+    //~^ ERROR evaluation of constant value failed
     const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
+    //~^ ERROR evaluation of constant value failed
 }
diff --git a/tests/ui/const-ptr/out_of_bounds_read.stderr b/tests/ui/const-ptr/out_of_bounds_read.stderr
index 899e151c9b8..b396fc4d71b 100644
--- a/tests/ui/const-ptr/out_of_bounds_read.stderr
+++ b/tests/ui/const-ptr/out_of_bounds_read.stderr
@@ -1,5 +1,5 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/out_of_bounds_read.rs:10:33
+  --> $DIR/out_of_bounds_read.rs:8:33
    |
 LL |     const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes
@@ -8,7 +8,7 @@ note: inside `std::ptr::read::<u32>`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/out_of_bounds_read.rs:11:39
+  --> $DIR/out_of_bounds_read.rs:10:39
    |
 LL |     const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
    |                                       ^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes
diff --git a/tests/ui/consts/async-block.rs b/tests/ui/consts/async-block.rs
index 40be4d195d4..1211a150f7d 100644
--- a/tests/ui/consts/async-block.rs
+++ b/tests/ui/consts/async-block.rs
@@ -2,8 +2,8 @@
 
 //@ edition:2018
 //@ revisions: with_feature without_feature
+//@[with_feature] check-pass
 
-#![feature(rustc_attrs)]
 #![cfg_attr(with_feature, feature(const_async_blocks))]
 
 use std::future::Future;
@@ -15,5 +15,4 @@ const _: i32 = { core::mem::ManuallyDrop::new(async { 0 }); 4 };
 static _FUT: &(dyn Future<Output = ()> + Sync) = &async {};
 //[without_feature]~^ `async` block
 
-#[rustc_error]
-fn main() {} //[with_feature]~ fatal error triggered by #[rustc_error]
+fn main() {}
diff --git a/tests/ui/consts/async-block.with_feature.stderr b/tests/ui/consts/async-block.with_feature.stderr
deleted file mode 100644
index 8228fa29edf..00000000000
--- a/tests/ui/consts/async-block.with_feature.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/async-block.rs:19:1
-   |
-LL | fn main() {}
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr
index 14c62fb4d25..624772f5aed 100644
--- a/tests/ui/consts/const-block-const-bound.stderr
+++ b/tests/ui/consts/const-block-const-bound.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `f`
   --> $DIR/const-block-const-bound.rs:6:15
    |
 LL | const fn f<T: ~const Destruct>(x: T) {}
-   |               ^^^^^^ required by this bound in `f`
+   |               ^^^^^^^^^^^^^^^ required by this bound in `f`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-size_of-cycle.rs b/tests/ui/consts/const-size_of-cycle.rs
index cfb2294c445..f45d96d43f8 100644
--- a/tests/ui/consts/const-size_of-cycle.rs
+++ b/tests/ui/consts/const-size_of-cycle.rs
@@ -1,7 +1,6 @@
-//@ error-pattern: cycle detected
-
 struct Foo {
     bytes: [u8; std::mem::size_of::<Foo>()]
+    //~^ ERROR cycle detected when evaluating type-level constant
 }
 
 fn main() {}
diff --git a/tests/ui/consts/const-size_of-cycle.stderr b/tests/ui/consts/const-size_of-cycle.stderr
index cd0ea556425..bf17d76a092 100644
--- a/tests/ui/consts/const-size_of-cycle.stderr
+++ b/tests/ui/consts/const-size_of-cycle.stderr
@@ -1,11 +1,11 @@
 error[E0391]: cycle detected when evaluating type-level constant
-  --> $DIR/const-size_of-cycle.rs:4:17
+  --> $DIR/const-size_of-cycle.rs:2:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`...
-  --> $DIR/const-size_of-cycle.rs:4:17
+  --> $DIR/const-size_of-cycle.rs:2:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -14,7 +14,7 @@ LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    = note: ...which requires normalizing `[u8; std::mem::size_of::<Foo>()]`...
    = note: ...which again requires evaluating type-level constant, completing the cycle
 note: cycle used when checking that `Foo` is well-formed
-  --> $DIR/const-size_of-cycle.rs:3:1
+  --> $DIR/const-size_of-cycle.rs:1:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
diff --git a/tests/ui/consts/const_in_pattern/arrays-and-slices.rs b/tests/ui/consts/const_in_pattern/arrays-and-slices.rs
new file mode 100644
index 00000000000..bb38490206b
--- /dev/null
+++ b/tests/ui/consts/const_in_pattern/arrays-and-slices.rs
@@ -0,0 +1,53 @@
+//! Tests that arrays and slices in constants aren't interchangeable when used as patterns.
+
+#[derive(PartialEq, Eq)]
+struct SomeStruct<T: ?Sized>(T);
+
+const BSTR_SIZED: &'static [u8; 3] = b"012";
+const BSTR_UNSIZED: &'static [u8] = BSTR_SIZED;
+const STRUCT_SIZED: &'static SomeStruct<[u8; 3]> = &SomeStruct(*BSTR_SIZED);
+const STRUCT_UNSIZED: &'static SomeStruct<[u8]> = STRUCT_SIZED;
+
+fn type_mismatches() {
+    // Test that array consts can't be used where a slice pattern is expected. This helps ensure
+    // that `const_to_pat` won't produce irrefutable `thir::PatKind::Array` patterns when matching
+    // on slices, which would result in missing length checks.
+    // See also `tests/ui/match/pattern-deref-miscompile.rs`, which tests that byte string literal
+    // patterns check slices' length appropriately when matching on slices.
+    match BSTR_UNSIZED {
+        BSTR_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+    match STRUCT_UNSIZED {
+        STRUCT_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+
+    // Test that slice consts can't be used where an array pattern is expected.
+    match BSTR_UNSIZED {
+        BSTR_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+    // If the types matched here, this would still error, since unsized structs aren't permitted in
+    // constant patterns. See the `invalid_patterns` test below.
+    match STRUCT_UNSIZED {
+        STRUCT_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+}
+
+fn invalid_patterns() {
+    // Test that unsized structs containing slices can't be used as patterns.
+    // See `tests/ui/consts/issue-87046.rs` for an example with `str`.
+    match STRUCT_UNSIZED {
+        STRUCT_UNSIZED => {}
+        //~^ ERROR: cannot use unsized non-slice type `SomeStruct<[u8]>` in constant patterns
+        _ => {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const_in_pattern/arrays-and-slices.stderr b/tests/ui/consts/const_in_pattern/arrays-and-slices.stderr
new file mode 100644
index 00000000000..412caf60f7d
--- /dev/null
+++ b/tests/ui/consts/const_in_pattern/arrays-and-slices.stderr
@@ -0,0 +1,84 @@
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:18:9
+   |
+LL | const BSTR_SIZED: &'static [u8; 3] = b"012";
+   | ---------------------------------- constant defined here
+...
+LL |     match BSTR_UNSIZED {
+   |           ------------ this expression has type `&[u8]`
+LL |         BSTR_SIZED => {}
+   |         ^^^^^^^^^^
+   |         |
+   |         expected `&[u8]`, found `&[u8; 3]`
+   |         `BSTR_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_bstr_sized`
+   |
+   = note: expected reference `&[u8]`
+              found reference `&'static [u8; 3]`
+
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:23:9
+   |
+LL | const STRUCT_SIZED: &'static SomeStruct<[u8; 3]> = &SomeStruct(*BSTR_SIZED);
+   | ------------------------------------------------ constant defined here
+...
+LL |     match STRUCT_UNSIZED {
+   |           -------------- this expression has type `&SomeStruct<[u8]>`
+LL |         STRUCT_SIZED => {}
+   |         ^^^^^^^^^^^^
+   |         |
+   |         expected `&SomeStruct<[u8]>`, found `&SomeStruct<[u8; 3]>`
+   |         `STRUCT_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_struct_sized`
+   |
+   = note: expected reference `&SomeStruct<[u8]>`
+              found reference `&'static SomeStruct<[u8; 3]>`
+
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:30:9
+   |
+LL | const BSTR_SIZED: &'static [u8; 3] = b"012";
+   | ---------------------------------- constant defined here
+...
+LL |     match BSTR_UNSIZED {
+   |           ------------ this expression has type `&[u8]`
+LL |         BSTR_SIZED => {}
+   |         ^^^^^^^^^^
+   |         |
+   |         expected `&[u8]`, found `&[u8; 3]`
+   |         `BSTR_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_bstr_sized`
+   |
+   = note: expected reference `&[u8]`
+              found reference `&'static [u8; 3]`
+
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:37:9
+   |
+LL | const STRUCT_SIZED: &'static SomeStruct<[u8; 3]> = &SomeStruct(*BSTR_SIZED);
+   | ------------------------------------------------ constant defined here
+...
+LL |     match STRUCT_UNSIZED {
+   |           -------------- this expression has type `&SomeStruct<[u8]>`
+LL |         STRUCT_SIZED => {}
+   |         ^^^^^^^^^^^^
+   |         |
+   |         expected `&SomeStruct<[u8]>`, found `&SomeStruct<[u8; 3]>`
+   |         `STRUCT_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_struct_sized`
+   |
+   = note: expected reference `&SomeStruct<[u8]>`
+              found reference `&'static SomeStruct<[u8; 3]>`
+
+error: cannot use unsized non-slice type `SomeStruct<[u8]>` in constant patterns
+  --> $DIR/arrays-and-slices.rs:47:9
+   |
+LL | const STRUCT_UNSIZED: &'static SomeStruct<[u8]> = STRUCT_SIZED;
+   | ----------------------------------------------- constant defined here
+...
+LL |         STRUCT_UNSIZED => {}
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.rs b/tests/ui/consts/invalid-inline-const-in-match-arm.rs
deleted file mode 100644
index 4fe4b0d33c8..00000000000
--- a/tests/ui/consts/invalid-inline-const-in-match-arm.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#![feature(inline_const_pat)]
-
-fn main() {
-    match () {
-        const { (|| {})() } => {}
-        //~^ ERROR cannot call non-const closure in constants
-        //~| ERROR could not evaluate constant pattern
-    }
-}
diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr
deleted file mode 100644
index b22f99f40d3..00000000000
--- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0015]: cannot call non-const closure in constants
-  --> $DIR/invalid-inline-const-in-match-arm.rs:5:17
-   |
-LL |         const { (|| {})() } => {}
-   |                 ^^^^^^^^^
-   |
-   = note: closures need an RFC before allowed to be called in constants
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
-error: could not evaluate constant pattern
-  --> $DIR/invalid-inline-const-in-match-arm.rs:5:9
-   |
-LL |         const { (|| {})() } => {}
-   |         ^^^^^^^^^^^^^^^^^^^ could not evaluate constant
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/miri_unleashed/drop.rs b/tests/ui/consts/miri_unleashed/drop.rs
index 45ade4906b8..17d089222d9 100644
--- a/tests/ui/consts/miri_unleashed/drop.rs
+++ b/tests/ui/consts/miri_unleashed/drop.rs
@@ -14,4 +14,6 @@ static TEST_OK: () = {
 // The actual error is tested by the error-pattern above.
 static TEST_BAD: () = {
     let _v: Vec<i32> = Vec::new();
-};
+}; //~ ERROR could not evaluate static initializer
+
+//~? WARN skipping const checks
diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
index b50bf01453d..1e12259e483 100644
--- a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
+++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
@@ -17,4 +17,17 @@ impl Bar<'static> for B {
     const STATIC: &str = "";
 }
 
+struct C;
+impl Bar<'_> for C {
+    // make  ^^ not cause
+    const STATIC: &'static str = {
+        struct B;
+        impl Bar<'static> for B {
+            const STATIC: &str = "";
+            //            ^ to emit a future incompat warning
+        }
+        ""
+    };
+}
+
 fn main() {}
diff --git a/tests/ui/consts/timeout.rs b/tests/ui/consts/timeout.rs
index c4fb8bab663..8dab87ac8e1 100644
--- a/tests/ui/consts/timeout.rs
+++ b/tests/ui/consts/timeout.rs
@@ -3,7 +3,6 @@
 //! ICE.
 
 //@ compile-flags: --crate-type=lib -Ztiny-const-eval-limit
-//@ error-pattern: constant evaluation is taking a long time
 
 static ROOK_ATTACKS_TABLE: () = {
     0_u64.count_ones();
@@ -23,3 +22,5 @@ static ROOK_ATTACKS_TABLE: () = {
     0_u64.count_ones();
     0_u64.count_ones();
 };
+
+//~? ERROR constant evaluation is taking a long time
diff --git a/tests/ui/consts/timeout.stderr b/tests/ui/consts/timeout.stderr
index 6bfa06d86d1..ecefeff76e9 100644
--- a/tests/ui/consts/timeout.stderr
+++ b/tests/ui/consts/timeout.stderr
@@ -4,7 +4,7 @@ error: constant evaluation is taking a long time
    = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
            If your compilation actually takes a long time, you can safely allow the lint.
 help: the constant being evaluated
-  --> $DIR/timeout.rs:8:1
+  --> $DIR/timeout.rs:7:1
    |
 LL | static ROOK_ATTACKS_TABLE: () = {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr
index c223f1f211a..213e9e908f5 100644
--- a/tests/ui/coroutine/clone-rpit.next.stderr
+++ b/tests/ui/coroutine/clone-rpit.next.stderr
@@ -35,11 +35,11 @@ note: ...which requires type-checking `foo::{closure#0}`...
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
    = note: ...which again requires type-checking `foo`, completing the cycle
-note: cycle used when computing type of opaque `foo::{opaque#0}`
-  --> $DIR/clone-rpit.rs:13:25
+note: cycle used when match-checking `foo`
+  --> $DIR/clone-rpit.rs:13:1
    |
 LL | pub fn foo<'a, 'b>() -> impl Clone {
-   |                         ^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr
index 31a635b57e5..f24db78415e 100644
--- a/tests/ui/coverage-attr/name-value.stderr
+++ b/tests/ui/coverage-attr/name-value.stderr
@@ -44,6 +44,21 @@ LL + #[coverage(on)]
    |
 
 error: malformed `coverage` attribute input
+  --> $DIR/name-value.rs:26:1
+   |
+LL | #[coverage = "off"]
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+help: the following are the possible correct uses
+   |
+LL - #[coverage = "off"]
+LL + #[coverage(off)]
+   |
+LL - #[coverage = "off"]
+LL + #[coverage(on)]
+   |
+
+error: malformed `coverage` attribute input
   --> $DIR/name-value.rs:29:5
    |
 LL |     #[coverage = "off"]
@@ -59,7 +74,7 @@ LL +     #[coverage(on)]
    |
 
 error: malformed `coverage` attribute input
-  --> $DIR/name-value.rs:26:1
+  --> $DIR/name-value.rs:35:1
    |
 LL | #[coverage = "off"]
    | ^^^^^^^^^^^^^^^^^^^
@@ -104,7 +119,7 @@ LL +     #[coverage(on)]
    |
 
 error: malformed `coverage` attribute input
-  --> $DIR/name-value.rs:35:1
+  --> $DIR/name-value.rs:50:1
    |
 LL | #[coverage = "off"]
    | ^^^^^^^^^^^^^^^^^^^
@@ -149,21 +164,6 @@ LL +     #[coverage(on)]
    |
 
 error: malformed `coverage` attribute input
-  --> $DIR/name-value.rs:50:1
-   |
-LL | #[coverage = "off"]
-   | ^^^^^^^^^^^^^^^^^^^
-   |
-help: the following are the possible correct uses
-   |
-LL - #[coverage = "off"]
-LL + #[coverage(off)]
-   |
-LL - #[coverage = "off"]
-LL + #[coverage(on)]
-   |
-
-error: malformed `coverage` attribute input
   --> $DIR/name-value.rs:64:1
    |
 LL | #[coverage = "off"]
diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr
index 612301885dc..2773db9c857 100644
--- a/tests/ui/coverage-attr/word-only.stderr
+++ b/tests/ui/coverage-attr/word-only.stderr
@@ -38,6 +38,19 @@ LL | #[coverage(on)]
    |           ++++
 
 error: malformed `coverage` attribute input
+  --> $DIR/word-only.rs:26:1
+   |
+LL | #[coverage]
+   | ^^^^^^^^^^^
+   |
+help: the following are the possible correct uses
+   |
+LL | #[coverage(off)]
+   |           +++++
+LL | #[coverage(on)]
+   |           ++++
+
+error: malformed `coverage` attribute input
   --> $DIR/word-only.rs:29:5
    |
 LL |     #[coverage]
@@ -51,7 +64,7 @@ LL |     #[coverage(on)]
    |               ++++
 
 error: malformed `coverage` attribute input
-  --> $DIR/word-only.rs:26:1
+  --> $DIR/word-only.rs:35:1
    |
 LL | #[coverage]
    | ^^^^^^^^^^^
@@ -90,7 +103,7 @@ LL |     #[coverage(on)]
    |               ++++
 
 error: malformed `coverage` attribute input
-  --> $DIR/word-only.rs:35:1
+  --> $DIR/word-only.rs:50:1
    |
 LL | #[coverage]
    | ^^^^^^^^^^^
@@ -129,19 +142,6 @@ LL |     #[coverage(on)]
    |               ++++
 
 error: malformed `coverage` attribute input
-  --> $DIR/word-only.rs:50:1
-   |
-LL | #[coverage]
-   | ^^^^^^^^^^^
-   |
-help: the following are the possible correct uses
-   |
-LL | #[coverage(off)]
-   |           +++++
-LL | #[coverage(on)]
-   |           ++++
-
-error: malformed `coverage` attribute input
   --> $DIR/word-only.rs:64:1
    |
 LL | #[coverage]
diff --git a/tests/ui/crate_type_flag.rs b/tests/ui/crate_type_flag.rs
index 4f3cfbae45d..03bea3638e1 100644
--- a/tests/ui/crate_type_flag.rs
+++ b/tests/ui/crate_type_flag.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: --crate-type dynlib
-//@ error-pattern: unknown crate type: `dynlib`, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`
 
 fn main() {}
+
+//~? ERROR unknown crate type: `dynlib`
diff --git a/tests/ui/custom_test_frameworks/full.rs b/tests/ui/custom_test_frameworks/full.rs
index 289767b1f69..57b55e9437b 100644
--- a/tests/ui/custom_test_frameworks/full.rs
+++ b/tests/ui/custom_test_frameworks/full.rs
@@ -25,4 +25,17 @@ impl example_runner::Testable for IsFoo {
 const TEST_1: IsFoo = IsFoo("hello");
 
 #[test_case]
-const TEST_2: IsFoo = IsFoo("foo");
+static TEST_2: IsFoo = IsFoo("foo");
+
+// FIXME: `test_case` is currently ignored on anything other than
+// fn/const/static. This should be an error. Compare this with `#[test]` and
+// #[bench] whose expanders emit "error: expected a non-associated function,
+// found […]" if applied to invalid items.
+#[test_case]
+struct _S;
+
+// FIXME: as above.
+#[test_case]
+impl _S {
+    fn _f() {}
+}
diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
index 3bff4471698..7f85cbf227a 100644
--- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
+++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
@@ -1,9 +1,9 @@
+//~ ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture
 // Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that
 // causes a layout error. See https://github.com/rust-lang/rust/issues/94961.
 
 //@ compile-flags:-C debuginfo=2
 //@ build-fail
-//@ error-pattern: too big for the target architecture
 
 #![crate_type = "rlib"]
 
diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
index 6a3f8f4c249..b79b5ff6fdb 100644
--- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
+++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
@@ -1,11 +1,12 @@
+//FIXME~ ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture
 // Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that
 // causes a layout error.
 // This version of the test already ICE'd before the commit that introduce the ICE described in
 // https://github.com/rust-lang/rust/issues/94961.
 
-//@ compile-flags:-C debuginfo=2
+//@ compile-flags:-C debuginfo=2 --error-format=human
 //@ build-fail
-//@ error-pattern: too big for the target architecture
+//@ error-pattern: values of the type `[u8; usize::MAX]` are too big for the target architecture
 
 #![crate_type = "rlib"]
 
@@ -16,3 +17,6 @@ pub enum Foo<T> {
 pub fn foo() -> usize {
     std::mem::size_of::<Foo<u8>>()
 }
+
+// FIXME: the error is reported on different lines on different targets
+//FIXME~? ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture
diff --git a/tests/ui/debuginfo/dwarf-versions.rs b/tests/ui/debuginfo/dwarf-versions.rs
index 806ade51a99..6030b2fcf3c 100644
--- a/tests/ui/debuginfo/dwarf-versions.rs
+++ b/tests/ui/debuginfo/dwarf-versions.rs
@@ -4,7 +4,6 @@
 //@ revisions: zero one two three four five six
 
 //@[zero] compile-flags: -Zdwarf-version=0
-//@[zero] error-pattern: requested DWARF version 0 is not supported
 
 //@[one] compile-flags: -Zdwarf-version=1
 //@[one] error-pattern: requested DWARF version 1 is not supported
@@ -22,7 +21,6 @@
 //@[five] check-pass
 
 //@[six] compile-flags: -Zdwarf-version=6
-//@[six] error-pattern: requested DWARF version 6 is not supported
 
 //@ compile-flags: -g --target x86_64-unknown-linux-gnu --crate-type cdylib
 //@ needs-llvm-components: x86
@@ -36,3 +34,7 @@
 pub trait Sized {}
 
 pub fn foo() {}
+
+//[zero]~? ERROR requested DWARF version 0 is not supported
+//[one]~? ERROR requested DWARF version 1 is not supported
+//[six]~? ERROR requested DWARF version 6 is not supported
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs
index 896bbac7d8e..75b8141cc38 100644
--- a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs
@@ -1,6 +1,5 @@
 //@ revisions: aarch64_gl i686_g i686_gl i686_uwp_g x86_64_g x86_64_gl x86_64_uwp_g
 //@ compile-flags: --crate-type cdylib -Csplit-debuginfo=packed
-//@ error-pattern: error: `-Csplit-debuginfo=packed` is unstable on this platform
 
 //@[aarch64_gl] compile-flags: --target aarch64-pc-windows-gnullvm
 //@[aarch64_gl] needs-llvm-components: aarch64
@@ -27,3 +26,5 @@
 
 #![no_core]
 #![no_std]
+
+//~? ERROR `-Csplit-debuginfo=packed` is unstable on this platform
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs
index 54a88c91217..3f4da555aad 100644
--- a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs
@@ -1,6 +1,5 @@
 //@ revisions: aarch64_gl i686_g i686_gl i686_uwp_g x86_64_g x86_64_gl x86_64_uwp_g
 //@ compile-flags: --crate-type cdylib -Csplit-debuginfo=unpacked
-//@ error-pattern: error: `-Csplit-debuginfo=unpacked` is unstable on this platform
 
 //@[aarch64_gl] compile-flags: --target aarch64-pc-windows-gnullvm
 //@[aarch64_gl] needs-llvm-components: aarch64
@@ -27,3 +26,5 @@
 
 #![no_core]
 #![no_std]
+
+//~? ERROR `-Csplit-debuginfo=unpacked` is unstable on this platform
diff --git a/tests/ui/deprecation/deprecation-lint-2.rs b/tests/ui/deprecation/deprecation-lint-2.rs
index 553b1afe45c..f22eebb53a0 100644
--- a/tests/ui/deprecation/deprecation-lint-2.rs
+++ b/tests/ui/deprecation/deprecation-lint-2.rs
@@ -1,5 +1,4 @@
 //@ aux-build:deprecation-lint.rs
-//@ error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 
@@ -9,5 +8,5 @@ extern crate deprecation_lint;
 use deprecation_lint::*;
 
 fn main() {
-    macro_test!();
+    macro_test!(); //~ ERROR use of deprecated function `deprecation_lint::deprecated`: text
 }
diff --git a/tests/ui/deprecation/deprecation-lint-2.stderr b/tests/ui/deprecation/deprecation-lint-2.stderr
index 7d411c00445..ebc760bfe7b 100644
--- a/tests/ui/deprecation/deprecation-lint-2.stderr
+++ b/tests/ui/deprecation/deprecation-lint-2.stderr
@@ -1,11 +1,11 @@
 error: use of deprecated function `deprecation_lint::deprecated`: text
-  --> $DIR/deprecation-lint-2.rs:12:5
+  --> $DIR/deprecation-lint-2.rs:11:5
    |
 LL |     macro_test!();
    |     ^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/deprecation-lint-2.rs:4:9
+  --> $DIR/deprecation-lint-2.rs:3:9
    |
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
diff --git a/tests/ui/deprecation/deprecation-lint-3.rs b/tests/ui/deprecation/deprecation-lint-3.rs
index f01fc924457..5a9ca9a2d0a 100644
--- a/tests/ui/deprecation/deprecation-lint-3.rs
+++ b/tests/ui/deprecation/deprecation-lint-3.rs
@@ -1,5 +1,4 @@
 //@ aux-build:deprecation-lint.rs
-//@ error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 #![allow(warnings)]
@@ -11,4 +10,5 @@ use deprecation_lint::*;
 
 fn main() {
     macro_test_arg_nested!(deprecated_text);
+    //~^ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text
 }
diff --git a/tests/ui/deprecation/deprecation-lint-3.stderr b/tests/ui/deprecation/deprecation-lint-3.stderr
index 1723b7bbd05..8bfe08cf6d5 100644
--- a/tests/ui/deprecation/deprecation-lint-3.stderr
+++ b/tests/ui/deprecation/deprecation-lint-3.stderr
@@ -1,11 +1,11 @@
 error: use of deprecated function `deprecation_lint::deprecated_text`: text
-  --> $DIR/deprecation-lint-3.rs:13:28
+  --> $DIR/deprecation-lint-3.rs:12:28
    |
 LL |     macro_test_arg_nested!(deprecated_text);
    |                            ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/deprecation-lint-3.rs:4:9
+  --> $DIR/deprecation-lint-3.rs:3:9
    |
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
diff --git a/tests/ui/diagnostic-flags/allow-non-lint-warnings.rs b/tests/ui/diagnostic-flags/allow-non-lint-warnings.rs
index 8980ef9c422..f928e112289 100644
--- a/tests/ui/diagnostic-flags/allow-non-lint-warnings.rs
+++ b/tests/ui/diagnostic-flags/allow-non-lint-warnings.rs
@@ -13,14 +13,16 @@
 //! - Original impl PR: <https://github.com/rust-lang/rust/pull/21248>.
 //! - RFC 507 "Release channels":
 //!   <https://github.com/rust-lang/rfcs/blob/c017755b9bfa0421570d92ba38082302e0f3ad4f/text/0507-release-channels.md>.
-#![feature(rustc_attrs)]
 
 //@ revisions: without_flag with_flag
 
+//@ check-pass
+//@ compile-flags: -Zunleash-the-miri-inside-of-you
 //@[with_flag] compile-flags: -Awarnings
 
-//@ check-pass
+fn non_constant() {}
+const fn constant() { non_constant() }
 
-#[rustc_error(warn)]
 fn main() {}
-//[without_flag]~^ WARN unexpected annotation used with `#[rustc_error(...)]`!
+
+//[without_flag]~? WARN skipping const checks
diff --git a/tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr b/tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr
index 3f33ccbd1c9..08ae11fc18a 100644
--- a/tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr
+++ b/tests/ui/diagnostic-flags/allow-non-lint-warnings.without_flag.stderr
@@ -1,8 +1,10 @@
-warning: unexpected annotation used with `#[rustc_error(...)]`!
-  --> $DIR/allow-non-lint-warnings.rs:25:1
+warning: skipping const checks
    |
-LL | fn main() {}
-   | ^^^^^^^^^
+help: skipping check that does not even have a feature gate
+  --> $DIR/allow-non-lint-warnings.rs:24:23
+   |
+LL | const fn constant() { non_constant() }
+   |                       ^^^^^^^^^^^^^^
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/drop/nonsense-drop-impl-issue-139278.rs b/tests/ui/drop/nonsense-drop-impl-issue-139278.rs
new file mode 100644
index 00000000000..86f4e4d8607
--- /dev/null
+++ b/tests/ui/drop/nonsense-drop-impl-issue-139278.rs
@@ -0,0 +1,10 @@
+//@ check-fail
+struct Foo;
+
+impl Drop for Foo { //~ ERROR: not all trait items implemented
+    const SPLOK: u32 = 0; //~ ERROR: not a member of trait
+}
+
+const X: Foo = Foo;
+
+fn main() {}
diff --git a/tests/ui/drop/nonsense-drop-impl-issue-139278.stderr b/tests/ui/drop/nonsense-drop-impl-issue-139278.stderr
new file mode 100644
index 00000000000..825e883fa6d
--- /dev/null
+++ b/tests/ui/drop/nonsense-drop-impl-issue-139278.stderr
@@ -0,0 +1,18 @@
+error[E0438]: const `SPLOK` is not a member of trait `Drop`
+  --> $DIR/nonsense-drop-impl-issue-139278.rs:5:5
+   |
+LL |     const SPLOK: u32 = 0;
+   |     ^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Drop`
+
+error[E0046]: not all trait items implemented, missing: `drop`
+  --> $DIR/nonsense-drop-impl-issue-139278.rs:4:1
+   |
+LL | impl Drop for Foo {
+   | ^^^^^^^^^^^^^^^^^ missing `drop` in implementation
+   |
+   = help: implement the missing item: `fn drop(&mut self) { todo!() }`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0046, E0438.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/duplicate/dupe-symbols-4.rs b/tests/ui/duplicate/dupe-symbols-4.rs
index a9b7d689ad4..d961ba10e72 100644
--- a/tests/ui/duplicate/dupe-symbols-4.rs
+++ b/tests/ui/duplicate/dupe-symbols-4.rs
@@ -1,7 +1,5 @@
 //@ build-fail
 
-//
-//@ error-pattern: symbol `fail` is already defined
 #![crate_type="rlib"]
 #![allow(warnings)]
 
@@ -20,5 +18,5 @@ impl A for B {
 
 impl A for C {
     #[no_mangle]
-    fn fail(self) {}
+    fn fail(self) {} //~ ERROR symbol `fail` is already defined
 }
diff --git a/tests/ui/duplicate/dupe-symbols-4.stderr b/tests/ui/duplicate/dupe-symbols-4.stderr
index 4c5f1e7867f..e85d3f2b063 100644
--- a/tests/ui/duplicate/dupe-symbols-4.stderr
+++ b/tests/ui/duplicate/dupe-symbols-4.stderr
@@ -1,5 +1,5 @@
 error: symbol `fail` is already defined
-  --> $DIR/dupe-symbols-4.rs:23:5
+  --> $DIR/dupe-symbols-4.rs:21:5
    |
 LL |     fn fail(self) {}
    |     ^^^^^^^^^^^^^
diff --git a/tests/ui/duplicate/dupe-symbols-7.rs b/tests/ui/duplicate/dupe-symbols-7.rs
index 162c3c40446..ea17942493c 100644
--- a/tests/ui/duplicate/dupe-symbols-7.rs
+++ b/tests/ui/duplicate/dupe-symbols-7.rs
@@ -1,10 +1,7 @@
 //@ build-fail
 //@ ignore-wasi wasi does different things with the `main` symbol
 
-//
-//@ error-pattern: entry symbol `main` declared multiple times
-
 #![allow(warnings)]
 
 #[no_mangle]
-fn main(){}
+fn main(){} //~ ERROR entry symbol `main` declared multiple times
diff --git a/tests/ui/duplicate/dupe-symbols-7.stderr b/tests/ui/duplicate/dupe-symbols-7.stderr
index aa6213af2e4..d7503856939 100644
--- a/tests/ui/duplicate/dupe-symbols-7.stderr
+++ b/tests/ui/duplicate/dupe-symbols-7.stderr
@@ -1,5 +1,5 @@
 error: entry symbol `main` declared multiple times
-  --> $DIR/dupe-symbols-7.rs:10:1
+  --> $DIR/dupe-symbols-7.rs:7:1
    |
 LL | fn main(){}
    | ^^^^^^^^^
diff --git a/tests/ui/duplicate/dupe-symbols-8.rs b/tests/ui/duplicate/dupe-symbols-8.rs
index 258e91fa8c8..b3c635f38ed 100644
--- a/tests/ui/duplicate/dupe-symbols-8.rs
+++ b/tests/ui/duplicate/dupe-symbols-8.rs
@@ -1,11 +1,10 @@
 //@ build-fail
-//@ error-pattern: entry symbol `main` declared multiple times
 //@ ignore-wasi wasi does different things with the `main` symbol
 //
 // See #67946.
 
 #![allow(warnings)]
-fn main() {
+fn main() { //~ ERROR entry symbol `main` declared multiple times
     extern "Rust" {
      fn main();
     }
diff --git a/tests/ui/duplicate/dupe-symbols-8.stderr b/tests/ui/duplicate/dupe-symbols-8.stderr
index 0f47d3683b5..494fdcca327 100644
--- a/tests/ui/duplicate/dupe-symbols-8.stderr
+++ b/tests/ui/duplicate/dupe-symbols-8.stderr
@@ -1,5 +1,5 @@
 error: entry symbol `main` declared multiple times
-  --> $DIR/dupe-symbols-8.rs:8:1
+  --> $DIR/dupe-symbols-8.rs:7:1
    |
 LL | fn main() {
    | ^^^^^^^^^
diff --git a/tests/ui/elided-test.rs b/tests/ui/elided-test.rs
index 025b75c1b5c..2bedc25e17b 100644
--- a/tests/ui/elided-test.rs
+++ b/tests/ui/elided-test.rs
@@ -1,7 +1,5 @@
-//@ error-pattern: `main` function not found
-
 // Since we're not compiling a test runner this function should be elided
 // and the build will fail because main doesn't exist
 #[test]
 fn main() {
-}
+} //~ ERROR `main` function not found in crate `elided_test`
diff --git a/tests/ui/elided-test.stderr b/tests/ui/elided-test.stderr
index e323b8ba7ea..7aebe5d8264 100644
--- a/tests/ui/elided-test.stderr
+++ b/tests/ui/elided-test.stderr
@@ -1,5 +1,5 @@
 error[E0601]: `main` function not found in crate `elided_test`
-  --> $DIR/elided-test.rs:7:2
+  --> $DIR/elided-test.rs:5:2
    |
 LL | }
    |  ^ consider adding a `main` function to `$DIR/elided-test.rs`
diff --git a/tests/ui/error-codes/E0602.rs b/tests/ui/error-codes/E0602.rs
index 1849fd2d895..cba15bb92d4 100644
--- a/tests/ui/error-codes/E0602.rs
+++ b/tests/ui/error-codes/E0602.rs
@@ -1,8 +1,11 @@
 //@ compile-flags:-D bogus
 //@ check-pass
 
-//@ error-pattern:E0602
 //@ error-pattern:requested on the command line with `-D bogus`
 //@ error-pattern:`#[warn(unknown_lints)]` on by default
 
 fn main() {}
+
+//~? WARN unknown lint: `bogus`
+//~? WARN unknown lint: `bogus`
+//~? WARN unknown lint: `bogus`
diff --git a/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr b/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr
index 7aa66be0d09..b4f83f6bfc0 100644
--- a/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr
+++ b/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr
@@ -1,7 +1,7 @@
 error[E0423]: expected value, found struct `remapped_dep::SomeStruct`
   --> $DIR/remap-path-prefix-reverse.rs:16:13
    |
-LL |     let _ = remapped_dep::SomeStruct; // ~ERROR E0423
+LL |     let _ = remapped_dep::SomeStruct;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `remapped_dep::SomeStruct {}`
    |
   ::: remapped-aux/remapped_dep.rs:4:1
diff --git a/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr b/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr
index 7aa66be0d09..b4f83f6bfc0 100644
--- a/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr
+++ b/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr
@@ -1,7 +1,7 @@
 error[E0423]: expected value, found struct `remapped_dep::SomeStruct`
   --> $DIR/remap-path-prefix-reverse.rs:16:13
    |
-LL |     let _ = remapped_dep::SomeStruct; // ~ERROR E0423
+LL |     let _ = remapped_dep::SomeStruct;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `remapped_dep::SomeStruct {}`
    |
   ::: remapped-aux/remapped_dep.rs:4:1
diff --git a/tests/ui/errors/remap-path-prefix-reverse.rs b/tests/ui/errors/remap-path-prefix-reverse.rs
index 7743e38f50f..28fdabb8f4d 100644
--- a/tests/ui/errors/remap-path-prefix-reverse.rs
+++ b/tests/ui/errors/remap-path-prefix-reverse.rs
@@ -13,5 +13,6 @@ extern crate remapped_dep;
 fn main() {
     // The actual error is irrelevant. The important part it that is should show
     // a snippet of the dependency's source.
-    let _ = remapped_dep::SomeStruct; // ~ERROR E0423
+    let _ = remapped_dep::SomeStruct;
+    //~^ ERROR expected value, found struct `remapped_dep::SomeStruct`
 }
diff --git a/tests/ui/errors/remap-path-prefix-sysroot.rs b/tests/ui/errors/remap-path-prefix-sysroot.rs
index 7281e6da094..5e2e4fab51d 100644
--- a/tests/ui/errors/remap-path-prefix-sysroot.rs
+++ b/tests/ui/errors/remap-path-prefix-sysroot.rs
@@ -3,7 +3,6 @@
 //@ [with-remap]compile-flags: --remap-path-prefix={{rust-src-base}}=remapped
 //@ [with-remap]compile-flags: --remap-path-prefix={{src-base}}=remapped-tests-ui
 //@ [without-remap]compile-flags:
-//@ error-pattern: E0507
 
 // The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically
 // as the remapped revision will not begin with $SRC_DIR_REAL,
@@ -18,7 +17,10 @@ struct Worker {
 impl Drop for Worker {
     fn drop(&mut self) {
         self.thread.join().unwrap();
+        //[without-remap]~^ ERROR cannot move out of `self.thread` which is behind a mutable reference
     }
 }
 
 pub fn main(){}
+
+//[with-remap]~? ERROR cannot move out of `self.thread` which is behind a mutable reference
diff --git a/tests/ui/errors/remap-path-prefix.normal.stderr b/tests/ui/errors/remap-path-prefix.normal.stderr
index 46d33d26052..5a125a7024a 100644
--- a/tests/ui/errors/remap-path-prefix.normal.stderr
+++ b/tests/ui/errors/remap-path-prefix.normal.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `ferris` in this scope
-  --> remapped/errors/remap-path-prefix.rs:19:5
+  --> remapped/errors/remap-path-prefix.rs:15:5
    |
 LL |     ferris
    |     ^^^^^^ not found in this scope
diff --git a/tests/ui/errors/remap-path-prefix.rs b/tests/ui/errors/remap-path-prefix.rs
index 8809caa4d4f..7e38e16280f 100644
--- a/tests/ui/errors/remap-path-prefix.rs
+++ b/tests/ui/errors/remap-path-prefix.rs
@@ -7,14 +7,13 @@
 // The remapped paths are not normalized by compiletest.
 //@ normalize-stderr: "\\(errors)" -> "/$1"
 
-// The remapped paths aren't recognized by compiletest, so we
-// cannot use line-specific patterns.
-//@ error-pattern: E0425
-
 fn main() {
     // We cannot actually put an ERROR marker here because
     // the file name in the error message is not what the
     // test framework expects (since the filename gets remapped).
     // We still test the expected error in the stderr file.
-    ferris
+    ferris //[without-diagnostic-scope]~ ERROR cannot find value `ferris` in this scope
 }
+
+//[normal]~? ERROR cannot find value `ferris` in this scope
+//[with-diagnostic-scope]~? ERROR cannot find value `ferris` in this scope
diff --git a/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr b/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr
index 46d33d26052..5a125a7024a 100644
--- a/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr
+++ b/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `ferris` in this scope
-  --> remapped/errors/remap-path-prefix.rs:19:5
+  --> remapped/errors/remap-path-prefix.rs:15:5
    |
 LL |     ferris
    |     ^^^^^^ not found in this scope
diff --git a/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr b/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr
index 0badea6e27b..b6332685dbf 100644
--- a/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr
+++ b/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `ferris` in this scope
-  --> $DIR/remap-path-prefix.rs:19:5
+  --> $DIR/remap-path-prefix.rs:15:5
    |
 LL |     ferris
    |     ^^^^^^ not found in this scope
diff --git a/tests/ui/errors/wrong-target-spec.rs b/tests/ui/errors/wrong-target-spec.rs
index 9b31c943e3e..a3a0e05d826 100644
--- a/tests/ui/errors/wrong-target-spec.rs
+++ b/tests/ui/errors/wrong-target-spec.rs
@@ -7,4 +7,4 @@
 
 fn main() {}
 
-//~? ERROR Error loading target specification: Could not find specification for target "x86_64_unknown-linux-musl"
+//~? ERROR error loading target specification: could not find specification for target "x86_64_unknown-linux-musl"
diff --git a/tests/ui/errors/wrong-target-spec.stderr b/tests/ui/errors/wrong-target-spec.stderr
index 8b06f404078..98b03ae00cb 100644
--- a/tests/ui/errors/wrong-target-spec.stderr
+++ b/tests/ui/errors/wrong-target-spec.stderr
@@ -1,2 +1,4 @@
-error: Error loading target specification: Could not find specification for target "x86_64_unknown-linux-musl". Run `rustc --print target-list` for a list of built-in targets
+error: error loading target specification: could not find specification for target "x86_64_unknown-linux-musl"
+  |
+  = help: run `rustc --print target-list` for a list of built-in targets
 
diff --git a/tests/ui/expr/if/if-typeck.rs b/tests/ui/expr/if/if-typeck.rs
index ba828f11e79..0985598f0f7 100644
--- a/tests/ui/expr/if/if-typeck.rs
+++ b/tests/ui/expr/if/if-typeck.rs
@@ -1,4 +1,3 @@
-//@ error-pattern:mismatched types
 // issue #513
 
 fn f() { }
@@ -6,5 +5,5 @@ fn f() { }
 fn main() {
 
     // f is not a bool
-    if f { }
+    if f { } //~ ERROR mismatched types
 }
diff --git a/tests/ui/expr/if/if-typeck.stderr b/tests/ui/expr/if/if-typeck.stderr
index 1be43a20105..bca00f890cb 100644
--- a/tests/ui/expr/if/if-typeck.stderr
+++ b/tests/ui/expr/if/if-typeck.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/if-typeck.rs:9:8
+  --> $DIR/if-typeck.rs:8:8
    |
 LL |     if f { }
    |        ^ expected `bool`, found fn item
diff --git a/tests/ui/ext-nonexistent.rs b/tests/ui/ext-nonexistent.rs
index a66407953a9..1293324b67e 100644
--- a/tests/ui/ext-nonexistent.rs
+++ b/tests/ui/ext-nonexistent.rs
@@ -1,2 +1,2 @@
-//@ error-pattern:cannot find macro
 fn main() { iamnotanextensionthatexists!(""); }
+//~^ ERROR cannot find macro `iamnotanextensionthatexists` in this scope
diff --git a/tests/ui/ext-nonexistent.stderr b/tests/ui/ext-nonexistent.stderr
index 8891e823e4a..edb59bba6e5 100644
--- a/tests/ui/ext-nonexistent.stderr
+++ b/tests/ui/ext-nonexistent.stderr
@@ -1,5 +1,5 @@
 error: cannot find macro `iamnotanextensionthatexists` in this scope
-  --> $DIR/ext-nonexistent.rs:2:13
+  --> $DIR/ext-nonexistent.rs:1:13
    |
 LL | fn main() { iamnotanextensionthatexists!(""); }
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/extern-flag/empty-extern-arg.rs b/tests/ui/extern-flag/empty-extern-arg.rs
index dea68b5b1ad..2dee721ed03 100644
--- a/tests/ui/extern-flag/empty-extern-arg.rs
+++ b/tests/ui/extern-flag/empty-extern-arg.rs
@@ -1,6 +1,9 @@
+//~ ERROR extern location for std does not exist
 //@ compile-flags: --extern std=
-//@ error-pattern: extern location for std does not exist
 //@ needs-unwind since it affects the error output
 //@ ignore-emscripten missing eh_catch_typeinfo lang item
 
 fn main() {}
+
+//~? ERROR `#[panic_handler]` function required, but not found
+//~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/extern-flag/invalid-crate-name-dashed.rs b/tests/ui/extern-flag/invalid-crate-name-dashed.rs
index b846214175e..b336cc84569 100644
--- a/tests/ui/extern-flag/invalid-crate-name-dashed.rs
+++ b/tests/ui/extern-flag/invalid-crate-name-dashed.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: --extern=my-awesome-library=libawesome.rlib
-//@ error-pattern: crate name `my-awesome-library` passed to `--extern` is not a valid ASCII identifier
 //@ error-pattern: consider replacing the dashes with underscores: `my_awesome_library`
 
 // In a sense, this is a regression test for issue #113035. We no longer suggest
@@ -8,3 +7,5 @@
 pub use my_awesome_library::*;
 
 fn main() {}
+
+//~? ERROR crate name `my-awesome-library` passed to `--extern` is not a valid ASCII identifier
diff --git a/tests/ui/extern-flag/invalid-crate-name-non-ascii.rs b/tests/ui/extern-flag/invalid-crate-name-non-ascii.rs
index 5231503820f..71818938283 100644
--- a/tests/ui/extern-flag/invalid-crate-name-non-ascii.rs
+++ b/tests/ui/extern-flag/invalid-crate-name-non-ascii.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: --extern čɍαţē=libnon_ascii.rlib
-//@ error-pattern: crate name `čɍαţē` passed to `--extern` is not a valid ASCII identifier
 
 fn main() {}
+
+//~? ERROR crate name `čɍαţē` passed to `--extern` is not a valid ASCII identifier
diff --git a/tests/ui/extern-flag/invalid-crate-name.rs b/tests/ui/extern-flag/invalid-crate-name.rs
index c7b5b637217..5d73e119673 100644
--- a/tests/ui/extern-flag/invalid-crate-name.rs
+++ b/tests/ui/extern-flag/invalid-crate-name.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: --extern=?#1%$
-//@ error-pattern: crate name `?#1%$` passed to `--extern` is not a valid ASCII identifier
 
 fn main() {}
+
+//~? ERROR crate name `?#1%$` passed to `--extern` is not a valid ASCII identifier
diff --git a/tests/ui/extern-flag/no-force-extern.rs b/tests/ui/extern-flag/no-force-extern.rs
index 11d2f91c7bb..c9317abe292 100644
--- a/tests/ui/extern-flag/no-force-extern.rs
+++ b/tests/ui/extern-flag/no-force-extern.rs
@@ -1,10 +1,12 @@
 //@ aux-crate:panic_handler=panic_handler.rs
 //@ ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header)
 // compile_flags: -Zunstable-options --crate-type dylib
-//@ error-pattern: `#[panic_handler]` function required, but not found
 //@ dont-check-compiler-stderr
 //@ edition: 2018
 
 #![no_std]
 
-fn foo() {}
+fn foo() {} //~ ERROR `main` function not found in crate `no_force_extern`
+
+//~? ERROR `#[panic_handler]` function required, but not found
+//~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/feature-gates/feature-gate-f128.e2015.stderr b/tests/ui/feature-gates/feature-gate-f128.e2015.stderr
index 771aee79dce..7e8ea5e948d 100644
--- a/tests/ui/feature-gates/feature-gate-f128.e2015.stderr
+++ b/tests/ui/feature-gates/feature-gate-f128.e2015.stderr
@@ -19,7 +19,7 @@ LL |     let a: f128 = 100.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:15:11
+  --> $DIR/feature-gate-f128.rs:16:11
    |
 LL | fn foo(a: f128) {}
    |           ^^^^
@@ -29,7 +29,7 @@ LL | fn foo(a: f128) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:18:8
+  --> $DIR/feature-gate-f128.rs:19:8
    |
 LL |     a: f128,
    |        ^^^^
@@ -48,6 +48,16 @@ LL |     let b = 0.0f128;
    = help: add `#![feature(f128)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 5 previous errors
+error[E0658]: the type `f128` is unstable
+  --> $DIR/feature-gate-f128.rs:12:13
+   |
+LL |     let c = 0f128;
+   |             ^^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f128)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-f128.e2018.stderr b/tests/ui/feature-gates/feature-gate-f128.e2018.stderr
index 771aee79dce..7e8ea5e948d 100644
--- a/tests/ui/feature-gates/feature-gate-f128.e2018.stderr
+++ b/tests/ui/feature-gates/feature-gate-f128.e2018.stderr
@@ -19,7 +19,7 @@ LL |     let a: f128 = 100.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:15:11
+  --> $DIR/feature-gate-f128.rs:16:11
    |
 LL | fn foo(a: f128) {}
    |           ^^^^
@@ -29,7 +29,7 @@ LL | fn foo(a: f128) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:18:8
+  --> $DIR/feature-gate-f128.rs:19:8
    |
 LL |     a: f128,
    |        ^^^^
@@ -48,6 +48,16 @@ LL |     let b = 0.0f128;
    = help: add `#![feature(f128)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 5 previous errors
+error[E0658]: the type `f128` is unstable
+  --> $DIR/feature-gate-f128.rs:12:13
+   |
+LL |     let c = 0f128;
+   |             ^^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f128)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-f128.rs b/tests/ui/feature-gates/feature-gate-f128.rs
index d25b6dde4ee..dcbe60e934a 100644
--- a/tests/ui/feature-gates/feature-gate-f128.rs
+++ b/tests/ui/feature-gates/feature-gate-f128.rs
@@ -9,6 +9,7 @@ const A: f128 = 10.0; //~ ERROR the type `f128` is unstable
 pub fn main() {
     let a: f128 = 100.0; //~ ERROR the type `f128` is unstable
     let b = 0.0f128; //~ ERROR the type `f128` is unstable
+    let c = 0f128; //~ ERROR the type `f128` is unstable
     foo(1.23);
 }
 
diff --git a/tests/ui/feature-gates/feature-gate-f16.e2015.stderr b/tests/ui/feature-gates/feature-gate-f16.e2015.stderr
index 2bb3b59465a..5d1ca8f6d04 100644
--- a/tests/ui/feature-gates/feature-gate-f16.e2015.stderr
+++ b/tests/ui/feature-gates/feature-gate-f16.e2015.stderr
@@ -19,7 +19,7 @@ LL |     let a: f16 = 100.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:15:11
+  --> $DIR/feature-gate-f16.rs:16:11
    |
 LL | fn foo(a: f16) {}
    |           ^^^
@@ -29,7 +29,7 @@ LL | fn foo(a: f16) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:18:8
+  --> $DIR/feature-gate-f16.rs:19:8
    |
 LL |     a: f16,
    |        ^^^
@@ -48,6 +48,16 @@ LL |     let b = 0.0f16;
    = help: add `#![feature(f16)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 5 previous errors
+error[E0658]: the type `f16` is unstable
+  --> $DIR/feature-gate-f16.rs:12:13
+   |
+LL |     let c = 0f16;
+   |             ^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f16)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-f16.e2018.stderr b/tests/ui/feature-gates/feature-gate-f16.e2018.stderr
index 2bb3b59465a..5d1ca8f6d04 100644
--- a/tests/ui/feature-gates/feature-gate-f16.e2018.stderr
+++ b/tests/ui/feature-gates/feature-gate-f16.e2018.stderr
@@ -19,7 +19,7 @@ LL |     let a: f16 = 100.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:15:11
+  --> $DIR/feature-gate-f16.rs:16:11
    |
 LL | fn foo(a: f16) {}
    |           ^^^
@@ -29,7 +29,7 @@ LL | fn foo(a: f16) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:18:8
+  --> $DIR/feature-gate-f16.rs:19:8
    |
 LL |     a: f16,
    |        ^^^
@@ -48,6 +48,16 @@ LL |     let b = 0.0f16;
    = help: add `#![feature(f16)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 5 previous errors
+error[E0658]: the type `f16` is unstable
+  --> $DIR/feature-gate-f16.rs:12:13
+   |
+LL |     let c = 0f16;
+   |             ^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f16)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-f16.rs b/tests/ui/feature-gates/feature-gate-f16.rs
index af906d71f5f..f748c603efe 100644
--- a/tests/ui/feature-gates/feature-gate-f16.rs
+++ b/tests/ui/feature-gates/feature-gate-f16.rs
@@ -9,6 +9,7 @@ const A: f16 = 10.0; //~ ERROR the type `f16` is unstable
 pub fn main() {
     let a: f16 = 100.0; //~ ERROR the type `f16` is unstable
     let b = 0.0f16; //~ ERROR the type `f16` is unstable
+    let c = 0f16; //~ ERROR the type `f16` is unstable
     foo(1.23);
 }
 
diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs
index 2c130664e9a..f9b5176d78a 100644
--- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs
+++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs
@@ -17,4 +17,13 @@ impl Mop {
     //~| ERROR: unconstrained opaque type
 }
 
+fn funky(_: [(); {
+    impl Foo for fn() {
+        type Bar = impl Sized;
+        //~^ ERROR: `impl Trait` in associated types is unstable
+        //~| ERROR: unconstrained opaque type
+    }
+    0
+}]) {}
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
index 7dfd79c7286..01d25c16228 100644
--- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
+++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
@@ -18,6 +18,16 @@ LL |     type Bop = impl std::fmt::Debug;
    = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+error[E0658]: `impl Trait` in associated types is unstable
+  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:22:20
+   |
+LL |         type Bar = impl Sized;
+   |                    ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0658]: inherent associated types are unstable
   --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:5
    |
@@ -44,6 +54,14 @@ LL |     type Bop = impl std::fmt::Debug;
    |
    = note: `Bop` must be used in combination with a concrete type within the same impl
 
-error: aborting due to 5 previous errors
+error: unconstrained opaque type
+  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:22:20
+   |
+LL |         type Bar = impl Sized;
+   |                    ^^^^^^^^^^
+   |
+   = note: `Bar` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-inline_const_pat.rs b/tests/ui/feature-gates/feature-gate-inline_const_pat.rs
deleted file mode 100644
index 3d0df289fb7..00000000000
--- a/tests/ui/feature-gates/feature-gate-inline_const_pat.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    let const { () } = ();
-    //~^ ERROR inline-const in pattern position is experimental [E0658]
-}
diff --git a/tests/ui/feature-gates/feature-gate-inline_const_pat.stderr b/tests/ui/feature-gates/feature-gate-inline_const_pat.stderr
deleted file mode 100644
index 7d7376fa818..00000000000
--- a/tests/ui/feature-gates/feature-gate-inline_const_pat.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: inline-const in pattern position is experimental
-  --> $DIR/feature-gate-inline_const_pat.rs:2:9
-   |
-LL |     let const { () } = ();
-   |         ^^^^^
-   |
-   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
-   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-movrs_target_feature.rs b/tests/ui/feature-gates/feature-gate-movrs_target_feature.rs
new file mode 100644
index 00000000000..738cab5a06d
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-movrs_target_feature.rs
@@ -0,0 +1,6 @@
+//@ only-x86_64
+#[target_feature(enable = "movrs")]
+//~^ ERROR: currently unstable
+unsafe fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-movrs_target_feature.stderr b/tests/ui/feature-gates/feature-gate-movrs_target_feature.stderr
new file mode 100644
index 00000000000..16fe7aaead5
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-movrs_target_feature.stderr
@@ -0,0 +1,13 @@
+error[E0658]: the target feature `movrs` is currently unstable
+  --> $DIR/feature-gate-movrs_target_feature.rs:2:18
+   |
+LL | #[target_feature(enable = "movrs")]
+   |                  ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #137976 <https://github.com/rust-lang/rust/issues/137976> for more information
+   = help: add `#![feature(movrs_target_feature)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs b/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs
index 7ae4a8d911b..025b4b52f12 100644
--- a/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs
+++ b/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs
@@ -1,7 +1,6 @@
 // Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.
 
 #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable
-#[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
 #[rustc_nonnull_optimization_guaranteed] //~ ERROR the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document guaranteed niche optimizations in libcore and libstd and will never be stable
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs-1.stderr b/tests/ui/feature-gates/feature-gate-rustc-attrs-1.stderr
index 8c3a8eb2df8..0f760e0602d 100644
--- a/tests/ui/feature-gates/feature-gate-rustc-attrs-1.stderr
+++ b/tests/ui/feature-gates/feature-gate-rustc-attrs-1.stderr
@@ -7,18 +7,9 @@ LL | #[rustc_variance]
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
-  --> $DIR/feature-gate-rustc-attrs-1.rs:4:1
-   |
-LL | #[rustc_error]
-   | ^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
 error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document guaranteed niche optimizations in libcore and libstd and will never be stable
               (note that the compiler does not even check whether the type indeed is being non-null-optimized; it is your responsibility to ensure that the attribute is only used on types that are optimized)
-  --> $DIR/feature-gate-rustc-attrs-1.rs:5:1
+  --> $DIR/feature-gate-rustc-attrs-1.rs:4:1
    |
 LL | #[rustc_nonnull_optimization_guaranteed]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,6 +17,6 @@ LL | #[rustc_nonnull_optimization_guaranteed]
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-super-let.rs b/tests/ui/feature-gates/feature-gate-super-let.rs
new file mode 100644
index 00000000000..cfe92a42669
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-super-let.rs
@@ -0,0 +1,4 @@
+fn main() {
+    super let a = 1;
+    //~^ ERROR `super let` is experimental
+}
diff --git a/tests/ui/feature-gates/feature-gate-super-let.stderr b/tests/ui/feature-gates/feature-gate-super-let.stderr
new file mode 100644
index 00000000000..a64e1b374f9
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-super-let.stderr
@@ -0,0 +1,13 @@
+error[E0658]: `super let` is experimental
+  --> $DIR/feature-gate-super-let.rs:2:5
+   |
+LL |     super let a = 1;
+   |     ^^^^^
+   |
+   = note: see issue #139076 <https://github.com/rust-lang/rust/issues/139076> for more information
+   = help: add `#![feature(super_let)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
index ec70a20844a..d332fba0623 100644
--- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
+++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
@@ -1,38 +1,42 @@
-//@ check-pass
-#![feature(type_alias_impl_trait)]
 use std::fmt::Debug;
 
-type Foo = impl Debug;
+type Foo = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
 struct Bar(Foo);
-#[define_opaque(Foo)]
+#[define_opaque(Foo)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define() -> Bar {
     Bar(42)
 }
 
-type Foo2 = impl Debug;
+type Foo2 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
-#[define_opaque(Foo2)]
+#[define_opaque(Foo2)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define2() {
     let x = || -> Foo2 { 42 };
 }
 
-type Foo3 = impl Debug;
+type Foo3 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
-#[define_opaque(Foo3)]
+#[define_opaque(Foo3)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define3(x: Foo3) {
     let y: i32 = x;
 }
-#[define_opaque(Foo3)]
+#[define_opaque(Foo3)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define3_1() {
     define3(42)
 }
 
-type Foo4 = impl Debug;
+type Foo4 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
-#[define_opaque(Foo4)]
+#[define_opaque(Foo4)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define4(_: Foo4) {
     let y: Foo4 = 42;
 }
 
+type Foo5 = [(); {
+    type Foo = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
+    //~^ ERROR unconstrained opaque type
+    0
+}];
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
new file mode 100644
index 00000000000..bab60eb4293
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
@@ -0,0 +1,111 @@
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:6:3
+   |
+LL | #[define_opaque(Foo)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:13:3
+   |
+LL | #[define_opaque(Foo2)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:20:3
+   |
+LL | #[define_opaque(Foo3)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:3
+   |
+LL | #[define_opaque(Foo3)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:31:3
+   |
+LL | #[define_opaque(Foo4)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:3:12
+   |
+LL | type Foo = impl Debug;
+   |            ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:11:13
+   |
+LL | type Foo2 = impl Debug;
+   |             ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:18:13
+   |
+LL | type Foo3 = impl Debug;
+   |             ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:29:13
+   |
+LL | type Foo4 = impl Debug;
+   |             ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:37:16
+   |
+LL |     type Foo = impl Debug;
+   |                ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: unconstrained opaque type
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:37:16
+   |
+LL |     type Foo = impl Debug;
+   |                ^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same crate
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/fn/bad-turbofish-hints-issue-121901.rs b/tests/ui/fn/bad-turbofish-hints-issue-121901.rs
new file mode 100644
index 00000000000..1425e576d75
--- /dev/null
+++ b/tests/ui/fn/bad-turbofish-hints-issue-121901.rs
@@ -0,0 +1,8 @@
+// Regression test for the parser wrongfully suggesting turbofish syntax in below syntax errors
+
+type One = for<'a> fn(Box<dyn Send + 'a);
+//~^ ERROR: expected one of `+`, `,`, or `>`, found `)`
+type Two = for<'a> fn(Box<dyn Send + 'a>>);
+//~^ ERROR: unmatched angle bracket
+
+fn main() {}
diff --git a/tests/ui/fn/bad-turbofish-hints-issue-121901.stderr b/tests/ui/fn/bad-turbofish-hints-issue-121901.stderr
new file mode 100644
index 00000000000..aacb326f8a2
--- /dev/null
+++ b/tests/ui/fn/bad-turbofish-hints-issue-121901.stderr
@@ -0,0 +1,25 @@
+error: expected one of `+`, `,`, or `>`, found `)`
+  --> $DIR/bad-turbofish-hints-issue-121901.rs:3:40
+   |
+LL | type One = for<'a> fn(Box<dyn Send + 'a);
+   |                                        ^ expected one of `+`, `,`, or `>`
+   |
+help: you might have meant to end the type parameters here
+   |
+LL | type One = for<'a> fn(Box<dyn Send + 'a>);
+   |                                        +
+
+error: unmatched angle bracket
+  --> $DIR/bad-turbofish-hints-issue-121901.rs:5:41
+   |
+LL | type Two = for<'a> fn(Box<dyn Send + 'a>>);
+   |                                         ^
+   |
+help: remove extra angle bracket
+   |
+LL - type Two = for<'a> fn(Box<dyn Send + 'a>>);
+LL + type Two = for<'a> fn(Box<dyn Send + 'a>);
+   |
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/fn/fn-bad-block-type.rs b/tests/ui/fn/fn-bad-block-type.rs
index c7ad462f143..47ddc583c87 100644
--- a/tests/ui/fn/fn-bad-block-type.rs
+++ b/tests/ui/fn/fn-bad-block-type.rs
@@ -1,5 +1,3 @@
-//@ error-pattern:mismatched types
-
-fn f() -> isize { true }
+fn f() -> isize { true } //~ ERROR mismatched types
 
 fn main() { }
diff --git a/tests/ui/fn/fn-bad-block-type.stderr b/tests/ui/fn/fn-bad-block-type.stderr
index 6917bea6591..287caee4582 100644
--- a/tests/ui/fn/fn-bad-block-type.stderr
+++ b/tests/ui/fn/fn-bad-block-type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/fn-bad-block-type.rs:3:19
+  --> $DIR/fn-bad-block-type.rs:1:19
    |
 LL | fn f() -> isize { true }
    |           -----   ^^^^ expected `isize`, found `bool`
diff --git a/tests/ui/generic-associated-types/issue-87258_a.rs b/tests/ui/generic-associated-types/issue-87258_a.rs
index 6f737b21f53..2ea77bbca76 100644
--- a/tests/ui/generic-associated-types/issue-87258_a.rs
+++ b/tests/ui/generic-associated-types/issue-87258_a.rs
@@ -15,8 +15,8 @@ pub trait Trait2 {
 
 impl<'c, S: Trait2> Trait2 for &'c mut S {
     type FooFuture<'a> = impl Trait1;
-    //~^ ERROR unconstrained opaque type
     fn foo<'a>() -> Self::FooFuture<'a> {
+        //~^ ERROR item does not constrain `<&'c mut S as Trait2>::FooFuture::{opaque#0}`
         Struct(unimplemented!())
     }
 }
diff --git a/tests/ui/generic-associated-types/issue-87258_a.stderr b/tests/ui/generic-associated-types/issue-87258_a.stderr
index 01f2a92f94a..f175c15bd02 100644
--- a/tests/ui/generic-associated-types/issue-87258_a.stderr
+++ b/tests/ui/generic-associated-types/issue-87258_a.stderr
@@ -1,10 +1,15 @@
-error: unconstrained opaque type
+error: item does not constrain `<&'c mut S as Trait2>::FooFuture::{opaque#0}`
+  --> $DIR/issue-87258_a.rs:18:8
+   |
+LL |     fn foo<'a>() -> Self::FooFuture<'a> {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/issue-87258_a.rs:17:26
    |
 LL |     type FooFuture<'a> = impl Trait1;
    |                          ^^^^^^^^^^^
-   |
-   = note: `FooFuture` must be used in combination with a concrete type within the same impl
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generic-associated-types/issue-87258_b.rs b/tests/ui/generic-associated-types/issue-87258_b.rs
index 84c7182cdcb..8b820e75f60 100644
--- a/tests/ui/generic-associated-types/issue-87258_b.rs
+++ b/tests/ui/generic-associated-types/issue-87258_b.rs
@@ -14,12 +14,12 @@ pub trait Trait2 {
 }
 
 type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1;
-//~^ ERROR unconstrained opaque type
 
 impl<'c, S: Trait2> Trait2 for &'c mut S {
     type FooFuture<'a> = Helper<'c, 'a, S>;
     #[define_opaque(Helper)]
     fn foo<'a>() -> Self::FooFuture<'a> {
+        //~^ ERROR item does not constrain `Helper::{opaque#0}`
         Struct(unimplemented!())
     }
 }
diff --git a/tests/ui/generic-associated-types/issue-87258_b.stderr b/tests/ui/generic-associated-types/issue-87258_b.stderr
index 906ce1f50da..56abcef0d37 100644
--- a/tests/ui/generic-associated-types/issue-87258_b.stderr
+++ b/tests/ui/generic-associated-types/issue-87258_b.stderr
@@ -1,10 +1,15 @@
-error: unconstrained opaque type
+error: item does not constrain `Helper::{opaque#0}`
+  --> $DIR/issue-87258_b.rs:21:8
+   |
+LL |     fn foo<'a>() -> Self::FooFuture<'a> {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/issue-87258_b.rs:16:49
    |
 LL | type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1;
    |                                                 ^^^^^^^^^^^
-   |
-   = note: `Helper` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions0.rs b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs
index f943ea0271d..f79001ff1f1 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions0.rs
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs
@@ -1,7 +1,5 @@
 //@ run-pass
 #![allow(non_contiguous_range_endpoints)]
-#![feature(inline_const_pat)]
-
 fn main() {
     let mut if_lettable = vec![];
     let mut first_or = vec![];
@@ -16,7 +14,6 @@ fn main() {
         match x {
             1 | -3..0 => first_or.push(x),
             y @ (0..5 | 6) => or_two.push(y),
-            y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
             y @ -5.. => range_from.push(y),
             y @ ..-7 => assert_eq!(y, -8),
             y => bottom.push(y),
@@ -25,6 +22,6 @@ fn main() {
     assert_eq!(if_lettable, [-1, 0, 2, 4]);
     assert_eq!(first_or, [-3, -2, -1, 1]);
     assert_eq!(or_two, [0, 2, 3, 4, 6]);
-    assert_eq!(range_from, [-5, -4, 7]);
+    assert_eq!(range_from, [-5, -4, 5, 7]);
     assert_eq!(bottom, [-7, -6]);
 }
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
index 4d7c9f10261..c5705d5db60 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
@@ -18,8 +18,6 @@ fn main() {
             //~^ error: expected a pattern range bound, found an expression
             1 | -3..0 => first_or.push(x),
             y @ (0..5 | 6) => or_two.push(y),
-            y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
-            //~^ error: inline-const in pattern position is experimental [E0658]
             y @ -5.. => range_from.push(y),
             y @ ..-7 => assert_eq!(y, -8),
             y => bottom.push(y),
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
index 62be2ef7a4d..5cd98faa8ab 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
@@ -11,10 +11,6 @@ LL +         const VAL: /* Type */ = 5+1;
 LL ~         match x as i32 {
 LL ~             0..VAL => errors_only.push(x),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |             0..const { 5+1 } => errors_only.push(x),
-   |                +++++++     +
 
 error[E0408]: variable `n` is not bound in all patterns
   --> $DIR/range_pat_interactions1.rs:10:25
@@ -24,17 +20,6 @@ LL |         if let n @ 2..3|4 = x {
    |                |
    |                variable not in all patterns
 
-error[E0658]: inline-const in pattern position is experimental
-  --> $DIR/range_pat_interactions1.rs:21:20
-   |
-LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
-   |                    ^^^^^
-   |
-   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
-   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0408, E0658.
-For more information about an error, try `rustc --explain E0408`.
+For more information about this error, try `rustc --explain E0408`.
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
deleted file mode 100644
index 0dbdb8fe7b6..00000000000
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-fn main() {
-    let mut first_or = Vec::<i32>::new();
-    let mut or_two = Vec::<i32>::new();
-    let mut range_from = Vec::<i32>::new();
-    let mut bottom = Vec::<i32>::new();
-    let mut errors_only = Vec::<i32>::new();
-
-    for x in -9 + 1..=(9 - 2) {
-        match x as i32 {
-            0..=(5+1) => errors_only.push(x),
-            //~^ error: expected a pattern range bound, found an expression
-            //~| error: range pattern bounds cannot have parentheses
-            1 | -3..0 => first_or.push(x),
-            y @ (0..5 | 6) => or_two.push(y),
-            y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
-            //~^ error: inline-const in pattern position is experimental
-            y @ -5.. => range_from.push(y),
-            y @ ..-7 => assert_eq!(y, -8),
-            y => bottom.push(y),
-        }
-    }
-}
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
deleted file mode 100644
index dbe7f4482ee..00000000000
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
+++ /dev/null
@@ -1,43 +0,0 @@
-error: range pattern bounds cannot have parentheses
-  --> $DIR/range_pat_interactions2.rs:10:17
-   |
-LL |             0..=(5+1) => errors_only.push(x),
-   |                 ^   ^
-   |
-help: remove these parentheses
-   |
-LL -             0..=(5+1) => errors_only.push(x),
-LL +             0..=5+1 => errors_only.push(x),
-   |
-
-error: expected a pattern range bound, found an expression
-  --> $DIR/range_pat_interactions2.rs:10:18
-   |
-LL |             0..=(5+1) => errors_only.push(x),
-   |                  ^^^ not a pattern
-   |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
-help: consider extracting the expression into a `const`
-   |
-LL +         const VAL: /* Type */ = 5+1;
-LL ~         match x as i32 {
-LL ~             0..=(VAL) => errors_only.push(x),
-   |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |             0..=(const { 5+1 }) => errors_only.push(x),
-   |                  +++++++     +
-
-error[E0658]: inline-const in pattern position is experimental
-  --> $DIR/range_pat_interactions2.rs:15:20
-   |
-LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
-   |                    ^^^^^
-   |
-   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
-   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions3.rs b/tests/ui/half-open-range-patterns/range_pat_interactions3.rs
deleted file mode 100644
index 2f2778095cf..00000000000
--- a/tests/ui/half-open-range-patterns/range_pat_interactions3.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-fn main() {
-    let mut first_or = Vec::<i32>::new();
-    let mut or_two = Vec::<i32>::new();
-    let mut range_from = Vec::<i32>::new();
-    let mut bottom = Vec::<i32>::new();
-
-    for x in -9 + 1..=(9 - 2) {
-        match x as i32 {
-            8.. => bottom.push(x),
-            1 | -3..0 => first_or.push(x),
-            y @ (0..5 | 6) => or_two.push(y),
-            y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
-            //~^ inline-const in pattern position is experimental
-            y @ -5.. => range_from.push(y),
-            y @ ..-7 => assert_eq!(y, -8),
-            y => bottom.push(y),
-        }
-    }
-}
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr
deleted file mode 100644
index dc7dc0efa7a..00000000000
--- a/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: inline-const in pattern position is experimental
-  --> $DIR/range_pat_interactions3.rs:12:20
-   |
-LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
-   |                    ^^^^^
-   |
-   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
-   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr
index 34617448a69..79ded34d9cd 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr
@@ -1,18 +1,5 @@
-error: item does not constrain `Foo::{opaque#0}`
-  --> $DIR/norm-before-method-resolution-opaque-type.rs:17:4
-   |
-LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X
-   |    ^^^^^^^^^^^
-   |
-   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
-note: this opaque type is supposed to be constrained
-  --> $DIR/norm-before-method-resolution-opaque-type.rs:14:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-
 error[E0507]: cannot move out of `*x` which is behind a shared reference
-  --> $DIR/norm-before-method-resolution-opaque-type.rs:23:13
+  --> $DIR/norm-before-method-resolution-opaque-type.rs:22:13
    |
 LL |     let x = *x;
    |             ^^ move occurs because `*x` has type `<X as Trait<'_>>::Out<Foo>`, which does not implement the `Copy` trait
@@ -23,6 +10,6 @@ LL -     let x = *x;
 LL +     let x = x;
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0507`.
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs
index bb663c82abb..f881fcb779f 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs
@@ -15,7 +15,6 @@ type Foo = impl Sized;
 
 #[define_opaque(Foo)]
 fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X
-//[old]~^ ERROR: item does not constrain
 where
     for<'a> X: Trait<'a>,
     for<'a> <X as Trait<'a>>::Out<()>: Copy,
diff --git a/tests/ui/impl-trait/impl_trait_projections.rs b/tests/ui/impl-trait/impl_trait_projections.rs
index 2c277aee06d..89fe3c1509c 100644
--- a/tests/ui/impl-trait/impl_trait_projections.rs
+++ b/tests/ui/impl-trait/impl_trait_projections.rs
@@ -35,4 +35,9 @@ fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
     panic!()
 }
 
+fn parametrized_value_in_anon_const_is_disallowed() -> [(); None::<impl Sized>] {
+    //~^ ERROR `impl Trait` is not allowed in paths
+    loop {}
+}
+
 fn main() {}
diff --git a/tests/ui/impl-trait/impl_trait_projections.stderr b/tests/ui/impl-trait/impl_trait_projections.stderr
index 5e0b80fcd59..21f45613938 100644
--- a/tests/ui/impl-trait/impl_trait_projections.stderr
+++ b/tests/ui/impl-trait/impl_trait_projections.stderr
@@ -30,6 +30,14 @@ LL |     -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error: aborting due to 4 previous errors
+error[E0562]: `impl Trait` is not allowed in paths
+  --> $DIR/impl_trait_projections.rs:38:68
+   |
+LL | fn parametrized_value_in_anon_const_is_disallowed() -> [(); None::<impl Sized>] {
+   |                                                                    ^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0562`.
diff --git a/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs b/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs
new file mode 100644
index 00000000000..ab54d5f87ba
--- /dev/null
+++ b/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs
@@ -0,0 +1,25 @@
+// Ensure we don't misclassify `impl Trait` as TAIT/ATPIT if located inside an anon const in a
+// type alias/assoc type.
+// issue: <https://github.com/rust-lang/rust/issues/139055>
+//@ check-pass
+#![forbid(unstable_features)]
+
+struct Girder<const N: usize>;
+
+type Alias = Girder<{
+    fn pass(input: impl Sized) -> impl Sized { input }
+    0
+}>;
+
+trait Trait {
+    type Assoc;
+}
+
+impl Trait for () {
+    type Assoc = [(); {
+        fn pass(input: impl Sized) -> impl Sized { input }
+        0
+    }];
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/issue-55872-1.rs b/tests/ui/impl-trait/issue-55872-1.rs
index f36a310ddf3..663cdbc2f5c 100644
--- a/tests/ui/impl-trait/issue-55872-1.rs
+++ b/tests/ui/impl-trait/issue-55872-1.rs
@@ -13,6 +13,7 @@ impl<S: Default> Bar for S {
         //~^ ERROR impl has stricter requirements than trait
         //~| ERROR the trait bound `S: Copy` is not satisfied in `(S, T)` [E0277]
         //~| ERROR the trait bound `T: Copy` is not satisfied in `(S, T)` [E0277]
+        //~| ERROR type parameter `T` is part of concrete type
         (S::default(), T::default())
     }
 }
diff --git a/tests/ui/impl-trait/issue-55872-1.stderr b/tests/ui/impl-trait/issue-55872-1.stderr
index 81759760bf1..e048bec1b6d 100644
--- a/tests/ui/impl-trait/issue-55872-1.stderr
+++ b/tests/ui/impl-trait/issue-55872-1.stderr
@@ -37,7 +37,13 @@ help: consider further restricting type parameter `T` with trait `Copy`
 LL |     fn foo<T: Default + std::marker::Copy>() -> Self::E {
    |                       +++++++++++++++++++
 
-error: aborting due to 3 previous errors
+error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/issue-55872-1.rs:12:29
+   |
+LL |     fn foo<T: Default>() -> Self::E {
+   |                             ^^^^^^^
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0276, E0277.
 For more information about an error, try `rustc --explain E0276`.
diff --git a/tests/ui/impl-trait/issue-55872-2.rs b/tests/ui/impl-trait/issue-55872-2.rs
index caca5c69a4a..a3b2225126a 100644
--- a/tests/ui/impl-trait/issue-55872-2.rs
+++ b/tests/ui/impl-trait/issue-55872-2.rs
@@ -11,9 +11,9 @@ pub trait Bar {
 impl<S> Bar for S {
     type E = impl std::marker::Send;
     fn foo<T>() -> Self::E {
-        async {}
         //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
         //~| ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+        async {}
     }
 }
 
diff --git a/tests/ui/impl-trait/issue-55872-2.stderr b/tests/ui/impl-trait/issue-55872-2.stderr
index b5b7f293a40..51a7dd00ade 100644
--- a/tests/ui/impl-trait/issue-55872-2.stderr
+++ b/tests/ui/impl-trait/issue-55872-2.stderr
@@ -1,14 +1,14 @@
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:14:9
+  --> $DIR/issue-55872-2.rs:13:20
    |
-LL |         async {}
-   |         ^^^^^^^^
+LL |     fn foo<T>() -> Self::E {
+   |                    ^^^^^^^
 
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:14:9
+  --> $DIR/issue-55872-2.rs:13:20
    |
-LL |         async {}
-   |         ^^^^^^^^
+LL |     fn foo<T>() -> Self::E {
+   |                    ^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
diff --git a/tests/ui/impl-trait/issue-55872-3.rs b/tests/ui/impl-trait/issue-55872-3.rs
index 50b9eb3ce0e..698e7f36234 100644
--- a/tests/ui/impl-trait/issue-55872-3.rs
+++ b/tests/ui/impl-trait/issue-55872-3.rs
@@ -13,6 +13,7 @@ impl<S> Bar for S {
     type E = impl std::marker::Copy;
     fn foo<T>() -> Self::E {
         //~^ ERROR : Copy` is not satisfied [E0277]
+        //~| ERROR type parameter `T` is part of concrete type
         async {}
     }
 }
diff --git a/tests/ui/impl-trait/issue-55872-3.stderr b/tests/ui/impl-trait/issue-55872-3.stderr
index 827155d48b8..3281dcc3501 100644
--- a/tests/ui/impl-trait/issue-55872-3.stderr
+++ b/tests/ui/impl-trait/issue-55872-3.stderr
@@ -1,12 +1,18 @@
-error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:16:9: 16:14}: Copy` is not satisfied
+error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}: Copy` is not satisfied
   --> $DIR/issue-55872-3.rs:14:20
    |
 LL |     fn foo<T>() -> Self::E {
-   |                    ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:16:9: 16:14}`
-LL |
+   |                    ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}`
+...
 LL |         async {}
-   |         -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:16:9: 16:14}` here
+   |         -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}` here
 
-error: aborting due to 1 previous error
+error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/issue-55872-3.rs:14:20
+   |
+LL |     fn foo<T>() -> Self::E {
+   |                    ^^^^^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/issue-55872.rs b/tests/ui/impl-trait/issue-55872.rs
index 10850f0a933..b76f8182b20 100644
--- a/tests/ui/impl-trait/issue-55872.rs
+++ b/tests/ui/impl-trait/issue-55872.rs
@@ -10,8 +10,8 @@ impl<S> Bar for S {
     type E = impl Copy;
 
     fn foo<T>() -> Self::E {
-        || ()
         //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+        || ()
     }
 }
 
diff --git a/tests/ui/impl-trait/issue-55872.stderr b/tests/ui/impl-trait/issue-55872.stderr
index 4ff8527bbe9..54e852f8edf 100644
--- a/tests/ui/impl-trait/issue-55872.stderr
+++ b/tests/ui/impl-trait/issue-55872.stderr
@@ -1,8 +1,8 @@
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872.rs:13:9
+  --> $DIR/issue-55872.rs:12:20
    |
-LL |         || ()
-   |         ^^^^^
+LL |     fn foo<T>() -> Self::E {
+   |                    ^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/issue-99073-2.rs b/tests/ui/impl-trait/issue-99073-2.rs
index 37ea211bec3..bfb8850857d 100644
--- a/tests/ui/impl-trait/issue-99073-2.rs
+++ b/tests/ui/impl-trait/issue-99073-2.rs
@@ -7,8 +7,7 @@ fn main() {
 fn test<T: Display>(t: T, recurse: bool) -> impl Display {
     let f = || {
         let i: u32 = test::<i32>(-1, false);
-        //~^ ERROR concrete type differs from previous defining opaque type use
-        //~| ERROR expected generic type parameter, found `i32`
+        //~^ ERROR expected generic type parameter, found `i32`
         println!("{i}");
     };
     if recurse {
diff --git a/tests/ui/impl-trait/issue-99073-2.stderr b/tests/ui/impl-trait/issue-99073-2.stderr
index 0bcac7c7c53..519530b5396 100644
--- a/tests/ui/impl-trait/issue-99073-2.stderr
+++ b/tests/ui/impl-trait/issue-99073-2.stderr
@@ -1,15 +1,3 @@
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/issue-99073-2.rs:9:22
-   |
-LL |         let i: u32 = test::<i32>(-1, false);
-   |                      ^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `u32`
-   |
-note: previous use here
-  --> $DIR/issue-99073-2.rs:7:45
-   |
-LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display {
-   |                                             ^^^^^^^^^^^^
-
 error[E0792]: expected generic type parameter, found `i32`
   --> $DIR/issue-99073-2.rs:9:22
    |
@@ -19,6 +7,6 @@ LL |     let f = || {
 LL |         let i: u32 = test::<i32>(-1, false);
    |                      ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/issue-99073.rs b/tests/ui/impl-trait/issue-99073.rs
index b4ef3e66f96..d2a2a61a408 100644
--- a/tests/ui/impl-trait/issue-99073.rs
+++ b/tests/ui/impl-trait/issue-99073.rs
@@ -4,6 +4,5 @@ fn main() {
 
 fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
   move || f(fix(&f))
-  //~^ ERROR concrete type differs from previous defining opaque type use
-  //~| ERROR expected generic type parameter, found `&F`
+  //~^ ERROR expected generic type parameter, found `&F`
 }
diff --git a/tests/ui/impl-trait/issue-99073.stderr b/tests/ui/impl-trait/issue-99073.stderr
index 19854ef8940..1917c1bfd6b 100644
--- a/tests/ui/impl-trait/issue-99073.stderr
+++ b/tests/ui/impl-trait/issue-99073.stderr
@@ -1,23 +1,11 @@
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/issue-99073.rs:6:13
-   |
-LL |   move || f(fix(&f))
-   |             ^^^^^^^ expected `{closure@$DIR/issue-99073.rs:6:3: 6:10}`, got `G`
-   |
-note: previous use here
-  --> $DIR/issue-99073.rs:5:36
-   |
-LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
-   |                                    ^^^^^^^^^
-
 error[E0792]: expected generic type parameter, found `&F`
-  --> $DIR/issue-99073.rs:6:11
+  --> $DIR/issue-99073.rs:6:13
    |
 LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
    |        - this generic parameter must be used with a generic type parameter
 LL |   move || f(fix(&f))
-   |           ^^^^^^^^^^
+   |             ^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs
new file mode 100644
index 00000000000..a76ed7b0947
--- /dev/null
+++ b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs
@@ -0,0 +1,17 @@
+// Regression test for #112201. This recursive call previously meant that
+// we delay an error when checking opaques at the end of writeback but don't
+// encounter that incorrect defining use during borrowck as it's in dead code.
+
+pub fn wrap<T>(x: T) -> impl Sized {
+    x
+}
+
+fn repeat_helper<T>(x: T) -> impl Sized {
+    return x;
+    repeat_helper(wrap(x))
+    //~^ ERROR expected generic type parameter, found `impl Sized`
+    //~| ERROR type parameter `T` is part of concrete type
+}
+
+
+fn main() {}
diff --git a/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr
new file mode 100644
index 00000000000..f507ad385a1
--- /dev/null
+++ b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr
@@ -0,0 +1,18 @@
+error[E0792]: expected generic type parameter, found `impl Sized`
+  --> $DIR/fuzzer-ice-issue-112201.rs:11:5
+   |
+LL | fn repeat_helper<T>(x: T) -> impl Sized {
+   |                  - this generic parameter must be used with a generic type parameter
+LL |     return x;
+LL |     repeat_helper(wrap(x))
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/fuzzer-ice-issue-112201.rs:11:5
+   |
+LL |     repeat_helper(wrap(x))
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs
index 9e8ea439dde..cf82467b72e 100644
--- a/tests/ui/impl-trait/issues/issue-86800.rs
+++ b/tests/ui/impl-trait/issues/issue-86800.rs
@@ -29,7 +29,6 @@ where
     F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f,
 {
     f
-    //~^ ERROR expected generic lifetime parameter, found `'_`
 }
 
 impl Context {
@@ -39,7 +38,6 @@ impl Context {
         &self,
         f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>,
     ) -> TransactionResult<O> {
-        //~^ ERROR expected generic lifetime parameter, found `'_`
         let mut conn = Connection {};
         let mut transaction = TestTransaction { conn: &mut conn };
         f(&mut transaction).await
diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr
index 80aa5d75c3c..e122fc229cc 100644
--- a/tests/ui/impl-trait/issues/issue-86800.stderr
+++ b/tests/ui/impl-trait/issues/issue-86800.stderr
@@ -12,7 +12,7 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResu
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: item does not constrain `TransactionFuture::{opaque#0}`
-  --> $DIR/issue-86800.rs:37:14
+  --> $DIR/issue-86800.rs:36:14
    |
 LL |     async fn do_transaction<O>(
    |              ^^^^^^^^^^^^^^
@@ -24,30 +24,5 @@ note: this opaque type is supposed to be constrained
 LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/issue-86800.rs:31:5
-   |
-LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
-   |                        --- this generic parameter must be used with a generic lifetime parameter
-...
-LL |     f
-   |     ^
-
-error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/issue-86800.rs:41:31
-   |
-LL |   type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
-   |                          --- this generic parameter must be used with a generic lifetime parameter
-...
-LL |       ) -> TransactionResult<O> {
-   |  _______________________________^
-LL | |
-LL | |         let mut conn = Connection {};
-LL | |         let mut transaction = TestTransaction { conn: &mut conn };
-LL | |         f(&mut transaction).await
-LL | |     }
-   | |_____^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr b/tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr
new file mode 100644
index 00000000000..08c8365b180
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr
@@ -0,0 +1,12 @@
+error[E0792]: expected generic lifetime parameter, found `'_`
+  --> $DIR/as-projection-term.rs:14:19
+   |
+LL | fn recur<'a>() -> impl Sized + 'a {
+   |                                -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |     prove_proj(|| recur());
+   |                   ^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/non-defining-uses/as-projection-term.rs b/tests/ui/impl-trait/non-defining-uses/as-projection-term.rs
new file mode 100644
index 00000000000..4c5adc7a00a
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/as-projection-term.rs
@@ -0,0 +1,17 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[current] check-pass
+
+fn prove_proj<R>(_: impl FnOnce() -> R) {}
+fn recur<'a>() -> impl Sized + 'a {
+    // The closure has the signature `fn() -> opaque<'1>`. `prove_proj`
+    // requires us to prove `<closure as FnOnce<()>>::Output = opaque<'2>`.
+    // The old solver uses `replace_opaque_types_with_infer` during normalization
+    // to replace `opaque<'2>` with its hidden type. If that hidden type is still an
+    // inference variable at this point, we unify it with `opaque<'1>` and
+    // end up ignoring that defining use as the hidden type is equal to its key.
+    prove_proj(|| recur());
+    //[next]~^ ERROR expected generic lifetime parameter, found `'_`
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/recursive-ice-101862.stderr b/tests/ui/impl-trait/recursive-ice-101862.stderr
index 970373422e8..85745c25e2b 100644
--- a/tests/ui/impl-trait/recursive-ice-101862.stderr
+++ b/tests/ui/impl-trait/recursive-ice-101862.stderr
@@ -1,3 +1,12 @@
+error[E0792]: expected generic type parameter, found `&str`
+  --> $DIR/recursive-ice-101862.rs:6:19
+   |
+LL | pub fn ice(x: impl AsRef<str>) -> impl IntoIterator<Item = ()> {
+   |               --------------- this generic parameter must be used with a generic type parameter
+LL |
+LL |     vec![].append(&mut ice(x.as_ref()));
+   |                   ^^^^^^^^^^^^^^^^^^^^
+
 warning: function cannot return without recursing
   --> $DIR/recursive-ice-101862.rs:4:1
    |
@@ -10,15 +19,6 @@ LL |     vec![].append(&mut ice(x.as_ref()));
    = help: a `loop` may express intention better if this is on purpose
    = note: `#[warn(unconditional_recursion)]` on by default
 
-error[E0792]: expected generic type parameter, found `&str`
-  --> $DIR/recursive-ice-101862.rs:6:19
-   |
-LL | pub fn ice(x: impl AsRef<str>) -> impl IntoIterator<Item = ()> {
-   |               --------------- this generic parameter must be used with a generic type parameter
-LL |
-LL |     vec![].append(&mut ice(x.as_ref()));
-   |                   ^^^^^^^^^^^^^^^^^^^^
-
 error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/rpit/early_bound.rs b/tests/ui/impl-trait/rpit/early_bound.rs
index 005bcea59f2..0337f605e48 100644
--- a/tests/ui/impl-trait/rpit/early_bound.rs
+++ b/tests/ui/impl-trait/rpit/early_bound.rs
@@ -1,11 +1,10 @@
 use std::convert::identity;
 
 fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
-    //~^ ERROR concrete type differs from previous defining opaque type use
     let true = n else { loop {} };
     let _ = || {
         let _ = identity::<&'a ()>(test(false));
-        //~^ ERROR expected generic lifetime parameter, found `'_`
+        //~^ ERROR concrete type differs from previous defining opaque type use
     };
     loop {}
 }
diff --git a/tests/ui/impl-trait/rpit/early_bound.stderr b/tests/ui/impl-trait/rpit/early_bound.stderr
index 230dde95764..d00005f20d4 100644
--- a/tests/ui/impl-trait/rpit/early_bound.stderr
+++ b/tests/ui/impl-trait/rpit/early_bound.stderr
@@ -1,24 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/early_bound.rs:3:29
+  --> $DIR/early_bound.rs:6:36
    |
-LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
-   |                             ^^^^^^^^^^^^^^^ expected `&()`, got `()`
+LL |         let _ = identity::<&'a ()>(test(false));
+   |                                    ^^^^^^^^^^^ expected `()`, got `&()`
    |
 note: previous use here
-  --> $DIR/early_bound.rs:7:36
-   |
-LL |         let _ = identity::<&'a ()>(test(false));
-   |                                    ^^^^^^^^^^^
-
-error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/early_bound.rs:7:17
+  --> $DIR/early_bound.rs:3:29
    |
 LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
-   |                                          -- this generic parameter must be used with a generic lifetime parameter
-...
-LL |         let _ = identity::<&'a ()>(test(false));
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                             ^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/rpit/non-defining-use.rs b/tests/ui/impl-trait/rpit/non-defining-use.rs
index 255a8929a87..3ab0e0ee4e2 100644
--- a/tests/ui/impl-trait/rpit/non-defining-use.rs
+++ b/tests/ui/impl-trait/rpit/non-defining-use.rs
@@ -6,8 +6,7 @@ fn foo<T>() -> impl Sized {
 
 fn bar<T>(val: T) -> impl Sized {
     let _: u8 = bar(0u8);
-    //~^ ERROR concrete type differs from previous defining opaque type use
-    //~| ERROR expected generic type parameter, found `u8`
+    //~^ ERROR expected generic type parameter, found `u8`
     val
 }
 
diff --git a/tests/ui/impl-trait/rpit/non-defining-use.stderr b/tests/ui/impl-trait/rpit/non-defining-use.stderr
index 10a8232e646..c2b1b0f8249 100644
--- a/tests/ui/impl-trait/rpit/non-defining-use.stderr
+++ b/tests/ui/impl-trait/rpit/non-defining-use.stderr
@@ -1,31 +1,19 @@
 error[E0792]: expected generic type parameter, found `u8`
-  --> $DIR/non-defining-use.rs:4:12
+  --> $DIR/non-defining-use.rs:4:17
    |
 LL | fn foo<T>() -> impl Sized {
    |        - this generic parameter must be used with a generic type parameter
 LL |     let _: () = foo::<u8>();
-   |            ^^
-
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/non-defining-use.rs:8:17
-   |
-LL |     let _: u8 = bar(0u8);
-   |                 ^^^^^^^^ expected `T`, got `u8`
-   |
-note: previous use here
-  --> $DIR/non-defining-use.rs:7:22
-   |
-LL | fn bar<T>(val: T) -> impl Sized {
-   |                      ^^^^^^^^^^
+   |                 ^^^^^^^^^^^
 
 error[E0792]: expected generic type parameter, found `u8`
-  --> $DIR/non-defining-use.rs:8:12
+  --> $DIR/non-defining-use.rs:8:17
    |
 LL | fn bar<T>(val: T) -> impl Sized {
    |        - this generic parameter must be used with a generic type parameter
 LL |     let _: u8 = bar(0u8);
-   |            ^^
+   |                 ^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.stderr b/tests/ui/impl-trait/transmute/in-defining-scope.stderr
index 7172bfdf0d7..31535695178 100644
--- a/tests/ui/impl-trait/transmute/in-defining-scope.stderr
+++ b/tests/ui/impl-trait/transmute/in-defining-scope.stderr
@@ -9,6 +9,31 @@ note: ...which requires computing type of opaque `foo::{opaque#0}`...
    |
 LL | fn foo() -> impl Sized {
    |             ^^^^^^^^^^
+note: ...which requires borrow-checking `foo`...
+  --> $DIR/in-defining-scope.rs:6:1
+   |
+LL | fn foo() -> impl Sized {
+   | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires promoting constants in MIR for `foo`...
+  --> $DIR/in-defining-scope.rs:6:1
+   |
+LL | fn foo() -> impl Sized {
+   | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires checking if `foo` contains FFI-unwind calls...
+  --> $DIR/in-defining-scope.rs:6:1
+   |
+LL | fn foo() -> impl Sized {
+   | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires building MIR for `foo`...
+  --> $DIR/in-defining-scope.rs:6:1
+   |
+LL | fn foo() -> impl Sized {
+   | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires match-checking `foo`...
+  --> $DIR/in-defining-scope.rs:6:1
+   |
+LL | fn foo() -> impl Sized {
+   | ^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `foo`...
   --> $DIR/in-defining-scope.rs:6:1
    |
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
index 0711af1cad4..11b57ad98c4 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
@@ -1,18 +1,5 @@
-error: item does not constrain `A::{opaque#0}`
-  --> $DIR/two_tait_defining_each_other2.rs:12:4
-   |
-LL | fn muh(x: A) -> B {
-   |    ^^^
-   |
-   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
-note: this opaque type is supposed to be constrained
-  --> $DIR/two_tait_defining_each_other2.rs:6:10
-   |
-LL | type A = impl Foo;
-   |          ^^^^^^^^
-
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/two_tait_defining_each_other2.rs:15:5
+  --> $DIR/two_tait_defining_each_other2.rs:14:5
    |
 LL |     x // B's hidden type is A (opaquely)
    |     ^ one of the two opaque types used here has to be outside its defining scope
@@ -28,5 +15,5 @@ note: opaque type being used as hidden type
 LL | type A = impl Foo;
    |          ^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
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 a3223b07a7e..6c454bba502 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs
@@ -10,8 +10,7 @@ trait Foo {}
 
 #[define_opaque(A, B)]
 fn muh(x: A) -> B {
-    //[current]~^ ERROR: item does not constrain `A::{opaque#0}`
-    //[next]~^^ ERROR: cannot satisfy `_ == A`
+    //[next]~^ ERROR: cannot satisfy `_ == A`
     x // B's hidden type is A (opaquely)
     //[current]~^ ERROR opaque type's hidden type cannot be another opaque type
 }
diff --git a/tests/ui/imports/glob-resolve1.stderr b/tests/ui/imports/glob-resolve1.stderr
index 75e65681c3a..23b0db0fa46 100644
--- a/tests/ui/imports/glob-resolve1.stderr
+++ b/tests/ui/imports/glob-resolve1.stderr
@@ -58,6 +58,11 @@ error[E0425]: cannot find function `import` in this scope
 LL |     import();
    |     ^^^^^^ not found in this scope
    |
+note: function `bar::import` exists but is inaccessible
+  --> $DIR/glob-resolve1.rs:7:5
+   |
+LL |     fn fpriv() {}
+   |     ^^^^^^^^^^ not accessible
 help: consider importing this function
    |
 LL + use other::import;
diff --git a/tests/ui/imports/import-loop-2.rs b/tests/ui/imports/import-loop-2.rs
index d9a56cb1378..1bd0f06c671 100644
--- a/tests/ui/imports/import-loop-2.rs
+++ b/tests/ui/imports/import-loop-2.rs
@@ -1,11 +1,9 @@
-//@ error-pattern:import
-
 mod a {
     pub use b::x;
 }
 
 mod b {
-    pub use a::x;
+    pub use a::x; //~ ERROR unresolved import `a::x`
 
     fn main() { let y = x; }
 }
diff --git a/tests/ui/imports/import-loop-2.stderr b/tests/ui/imports/import-loop-2.stderr
index 1a95200a662..2521b6e7c04 100644
--- a/tests/ui/imports/import-loop-2.stderr
+++ b/tests/ui/imports/import-loop-2.stderr
@@ -1,5 +1,5 @@
 error[E0432]: unresolved import `a::x`
-  --> $DIR/import-loop-2.rs:8:13
+  --> $DIR/import-loop-2.rs:6:13
    |
 LL |     pub use a::x;
    |             ^^^^ no `x` in `a`
diff --git a/tests/ui/imports/import-loop.rs b/tests/ui/imports/import-loop.rs
index 1ba9e090033..fc5bd32adee 100644
--- a/tests/ui/imports/import-loop.rs
+++ b/tests/ui/imports/import-loop.rs
@@ -1,9 +1,7 @@
-//@ error-pattern:import
-
 use y::x;
 
 mod y {
-    pub use y::x;
+    pub use y::x; //~ ERROR unresolved import `y::x`
 }
 
 fn main() { }
diff --git a/tests/ui/imports/import-loop.stderr b/tests/ui/imports/import-loop.stderr
index 8ad2d6be4d2..801fc2552b6 100644
--- a/tests/ui/imports/import-loop.stderr
+++ b/tests/ui/imports/import-loop.stderr
@@ -1,5 +1,5 @@
 error[E0432]: unresolved import `y::x`
-  --> $DIR/import-loop.rs:6:13
+  --> $DIR/import-loop.rs:4:13
    |
 LL |     pub use y::x;
    |             ^^^^ no `x` in `y`
diff --git a/tests/ui/imports/import3.rs b/tests/ui/imports/import3.rs
index 71eea0ebb26..7bd6458cba1 100644
--- a/tests/ui/imports/import3.rs
+++ b/tests/ui/imports/import3.rs
@@ -1,4 +1,3 @@
-//@ error-pattern: unresolved
-use main::bar;
+use main::bar; //~ ERROR unresolved import `main`
 
 fn main() { println!("foo"); }
diff --git a/tests/ui/imports/import3.stderr b/tests/ui/imports/import3.stderr
index 7f581146781..871104ce50d 100644
--- a/tests/ui/imports/import3.stderr
+++ b/tests/ui/imports/import3.stderr
@@ -1,5 +1,5 @@
 error[E0432]: unresolved import `main`
-  --> $DIR/import3.rs:2:5
+  --> $DIR/import3.rs:1:5
    |
 LL | use main::bar;
    |     ^^^^ use of unresolved module or unlinked crate `main`
diff --git a/tests/ui/imports/import4.rs b/tests/ui/imports/import4.rs
index 8d727ced890..01535fc6f45 100644
--- a/tests/ui/imports/import4.rs
+++ b/tests/ui/imports/import4.rs
@@ -1,7 +1,4 @@
-//@ error-pattern: import
-
-
 mod a { pub use b::foo; }
-mod b { pub use a::foo; }
+mod b { pub use a::foo; } //~ ERROR unresolved import `a::foo`
 
 fn main() { println!("loop"); }
diff --git a/tests/ui/imports/import4.stderr b/tests/ui/imports/import4.stderr
index c99e8385118..c979d6c9ae2 100644
--- a/tests/ui/imports/import4.stderr
+++ b/tests/ui/imports/import4.stderr
@@ -1,5 +1,5 @@
 error[E0432]: unresolved import `a::foo`
-  --> $DIR/import4.rs:5:17
+  --> $DIR/import4.rs:2:17
    |
 LL | mod b { pub use a::foo; }
    |                 ^^^^^^ no `foo` in `a`
diff --git a/tests/ui/imports/issue-4366-2.stderr b/tests/ui/imports/issue-4366-2.stderr
index 412423f4d59..b1c0092b05d 100644
--- a/tests/ui/imports/issue-4366-2.stderr
+++ b/tests/ui/imports/issue-4366-2.stderr
@@ -16,6 +16,11 @@ error[E0423]: expected function, found module `foo`
 LL |     foo();
    |     ^^^ not a function
    |
+note: function `m1::foo` exists but is inaccessible
+  --> $DIR/issue-4366-2.rs:21:5
+   |
+LL |     fn foo() {}
+   |     ^^^^^^^^ not accessible
 help: consider importing this function instead
    |
 LL + use foo::foo;
diff --git a/tests/ui/imports/issue-4366.stderr b/tests/ui/imports/issue-4366.stderr
index e63399d554e..54b7f31b231 100644
--- a/tests/ui/imports/issue-4366.stderr
+++ b/tests/ui/imports/issue-4366.stderr
@@ -4,6 +4,11 @@ error[E0425]: cannot find function `foo` in this scope
 LL |         fn sub() -> isize { foo(); 1 }
    |                             ^^^ not found in this scope
    |
+note: function `m1::foo` exists but is inaccessible
+  --> $DIR/issue-4366.rs:23:5
+   |
+LL |     fn foo() {}
+   |     ^^^^^^^^ not accessible
 help: consider importing this function
    |
 LL +         use foo::foo;
diff --git a/tests/ui/imports/show-private-items-issue-138626.rs b/tests/ui/imports/show-private-items-issue-138626.rs
new file mode 100644
index 00000000000..d9708fc33c2
--- /dev/null
+++ b/tests/ui/imports/show-private-items-issue-138626.rs
@@ -0,0 +1,19 @@
+pub mod one {
+    mod foo {
+        pub struct Foo;
+    }
+
+    pub use self::foo::Foo;
+}
+
+pub mod two {
+    mod foo {
+        mod bar {
+            pub struct Foo;
+        }
+    }
+
+    pub use crate::two::foo::Foo; //~ ERROR unresolved import `crate::two::foo::Foo` [E0432]
+}
+
+fn main() {}
diff --git a/tests/ui/imports/show-private-items-issue-138626.stderr b/tests/ui/imports/show-private-items-issue-138626.stderr
new file mode 100644
index 00000000000..b664462daed
--- /dev/null
+++ b/tests/ui/imports/show-private-items-issue-138626.stderr
@@ -0,0 +1,20 @@
+error[E0432]: unresolved import `crate::two::foo::Foo`
+  --> $DIR/show-private-items-issue-138626.rs:16:13
+   |
+LL |     pub use crate::two::foo::Foo;
+   |             ^^^^^^^^^^^^^^^^^^^^ no `Foo` in `two::foo`
+   |
+note: struct `two::foo::bar::Foo` exists but is inaccessible
+  --> $DIR/show-private-items-issue-138626.rs:12:13
+   |
+LL |             pub struct Foo;
+   |             ^^^^^^^^^^^^^^^ not accessible
+help: consider importing this struct through its public re-export instead
+   |
+LL -     pub use crate::two::foo::Foo;
+LL +     pub use one::Foo;
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr
index 1974e13eabc..ac79e3f12bd 100644
--- a/tests/ui/indexing/index-help.stderr
+++ b/tests/ui/indexing/index-help.stderr
@@ -5,8 +5,9 @@ LL |     x[0i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<{integer}>` to implement `Index<i32>`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr
index 5c60a30946d..62a1ca3d057 100644
--- a/tests/ui/indexing/indexing-requires-a-uint.stderr
+++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
@@ -5,8 +5,9 @@ LL |     [0][0u8];
    |         ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[{integer}]` to implement `Index<u8>`
    = note: 1 redundant requirement hidden
    = note: required for `[{integer}; 1]` to implement `Index<u8>`
diff --git a/tests/ui/infinite/infinite-autoderef.stderr b/tests/ui/infinite/infinite-autoderef.stderr
index 7d09af9a7d4..7770cc8a720 100644
--- a/tests/ui/infinite/infinite-autoderef.stderr
+++ b/tests/ui/infinite/infinite-autoderef.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Box<_>` to `_`
-  --> $DIR/infinite-autoderef.rs:16:13
+  --> $DIR/infinite-autoderef.rs:16:22
    |
 LL |         x = Box::new(x);
-   |             ^^^^^^^^^^^
+   |                      ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
index e28b8f373da..f50c4a5207a 100644
--- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
+++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
@@ -1,8 +1,6 @@
+//~ ERROR reached the recursion limit while instantiating `<VirtualWrapper<VirtualWrapper<VirtualWrapper
 //@ build-fail
 
-//@ error-pattern: reached the recursion limit while instantiating
-//@ error-pattern: reached the recursion limit finding the struct tail
-
 // Regression test for #114484: This used to ICE during monomorphization, because we treated
 // `<VirtualWrapper<...> as Pointee>::Metadata` as a rigid projection after reaching the recursion
 // limit when finding the struct tail.
@@ -73,3 +71,16 @@ fn main() {
     let test = SomeData([0; 256]);
     test.virtualize();
 }
+
+//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]`
+//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]`
+//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]`
+//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]`
+//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>`
+//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>`
+//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>`
+//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>`
+//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
+//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
+//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
+//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
index 475e26fd0f0..59addc5cc4a 100644
--- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
+++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
@@ -18,7 +18,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:24:18
    |
 LL |         unsafe { virtualize_my_trait(L, self) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,7 +43,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:24:18
    |
 LL |         unsafe { virtualize_my_trait(L, self) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -68,7 +68,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper<S
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:24:18
    |
 LL |         unsafe { virtualize_my_trait(L, self) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -76,7 +76,7 @@ LL |         unsafe { virtualize_my_trait(L, self) }
 error: reached the recursion limit while instantiating `<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<..., 1>, 1>, 1>, 1>, 1> as MyTrait>::virtualize`
    |
 note: `<VirtualWrapper<T, L> as MyTrait>::virtualize` defined here
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:5
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:23:5
    |
 LL |     fn virtualize(&self) -> &dyn MyTrait {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/inline-const/collect-scopes-in-pat.rs b/tests/ui/inline-const/collect-scopes-in-pat.rs
deleted file mode 100644
index 16baf920f58..00000000000
--- a/tests/ui/inline-const/collect-scopes-in-pat.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ compile-flags: -Zlint-mir
-//@ check-pass
-
-#![feature(inline_const_pat)]
-
-fn main() {
-    match 1 {
-        const {
-            || match 0 {
-                x => 0,
-            };
-            0
-        } => (),
-        _ => (),
-    }
-}
diff --git a/tests/ui/inline-const/const-block-pat-liveness.rs b/tests/ui/inline-const/const-block-pat-liveness.rs
deleted file mode 100644
index 26393a4f65b..00000000000
--- a/tests/ui/inline-const/const-block-pat-liveness.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//! This test used to ICE because const blocks didn't have a body
-//! anymore, making a lot of logic very fragile around handling the
-//! HIR of a const block.
-//! https://github.com/rust-lang/rust/issues/125846
-
-//@ check-pass
-
-#![feature(inline_const_pat)]
-
-fn main() {
-    match 0 {
-        const {
-            let a = 10_usize;
-            *&a
-        }
-        | _ => {}
-    }
-}
diff --git a/tests/ui/inline-const/const-match-pat-generic.rs b/tests/ui/inline-const/const-match-pat-generic.rs
deleted file mode 100644
index 889c015e9ac..00000000000
--- a/tests/ui/inline-const/const-match-pat-generic.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-#![feature(inline_const_pat)]
-
-// rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter
-
-fn foo<const V: usize>() {
-    match 0 {
-        const { V } => {},
-        //~^ ERROR constant pattern cannot depend on generic parameters
-        _ => {},
-    }
-}
-
-const fn f(x: usize) -> usize {
-    x + 1
-}
-
-fn bar<const V: usize>() {
-    match 0 {
-        const { f(V) } => {},
-        //~^ ERROR constant pattern cannot depend on generic parameters
-        _ => {},
-    }
-}
-
-fn main() {
-    foo::<1>();
-    bar::<1>();
-}
diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr
deleted file mode 100644
index 7d9e1d9e407..00000000000
--- a/tests/ui/inline-const/const-match-pat-generic.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0158]: constant pattern cannot depend on generic parameters
-  --> $DIR/const-match-pat-generic.rs:7:9
-   |
-LL |         const { V } => {},
-   |         ^^^^^^^^^^^ `const` depends on a generic parameter
-
-error[E0158]: constant pattern cannot depend on generic parameters
-  --> $DIR/const-match-pat-generic.rs:19:9
-   |
-LL |         const { f(V) } => {},
-   |         ^^^^^^^^^^^^^^ `const` depends on a generic parameter
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0158`.
diff --git a/tests/ui/inline-const/const-match-pat-inference.rs b/tests/ui/inline-const/const-match-pat-inference.rs
deleted file mode 100644
index 3d3533839bc..00000000000
--- a/tests/ui/inline-const/const-match-pat-inference.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ check-pass
-
-#![feature(inline_const_pat)]
-
-fn main() {
-    match 1u64 {
-        0 => (),
-        const { 0 + 1 } => (),
-        const { 2 - 1 } ..= const { u64::MAX } => (),
-    }
-}
diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.rs b/tests/ui/inline-const/const-match-pat-lifetime-err.rs
deleted file mode 100644
index 7f450ebe6fc..00000000000
--- a/tests/ui/inline-const/const-match-pat-lifetime-err.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-#![feature(inline_const_pat)]
-
-use std::marker::PhantomData;
-
-#[derive(PartialEq, Eq)]
-pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
-
-#[derive(PartialEq, Eq)]
-pub struct CovariantRef<'a, T: ?Sized>(&'a T);
-
-impl<'a, T: ?Sized> InvariantRef<'a, T> {
-    pub const fn new(r: &'a T) -> Self {
-        InvariantRef(r, PhantomData)
-    }
-}
-
-impl<'a> InvariantRef<'a, ()> {
-    pub const NEW: Self = InvariantRef::new(&());
-}
-
-impl<'a> CovariantRef<'a, ()> {
-    pub const NEW: Self = CovariantRef(&());
-}
-
-fn match_invariant_ref<'a>() {
-    let y = ();
-    match InvariantRef::new(&y) {
-        //~^ ERROR `y` does not live long enough [E0597]
-        const { InvariantRef::<'a>::NEW } => (),
-    }
-}
-
-fn match_covariant_ref<'a>() {
-    // Unclear if we should error here (should we be able to subtype the type of
-    // `y.0`), but using the associated const directly in the pattern also
-    // errors.
-    let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
-    //~^ ERROR lifetime may not live long enough
-    match y.0 {
-        const { CovariantRef::<'a>::NEW } => (),
-    }
-}
-
-fn main() {
-    match_invariant_ref();
-    match_covariant_ref();
-}
diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.stderr b/tests/ui/inline-const/const-match-pat-lifetime-err.stderr
deleted file mode 100644
index 7eea1846057..00000000000
--- a/tests/ui/inline-const/const-match-pat-lifetime-err.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error[E0597]: `y` does not live long enough
-  --> $DIR/const-match-pat-lifetime-err.rs:27:29
-   |
-LL | fn match_invariant_ref<'a>() {
-   |                        -- lifetime `'a` defined here
-LL |     let y = ();
-   |         - binding `y` declared here
-LL |     match InvariantRef::new(&y) {
-   |                             ^^ borrowed value does not live long enough
-LL |
-LL |         const { InvariantRef::<'a>::NEW } => (),
-   |                 ----------------------- using this value as a constant requires that `y` is borrowed for `'a`
-LL |     }
-LL | }
-   | - `y` dropped here while still borrowed
-
-error: lifetime may not live long enough
-  --> $DIR/const-match-pat-lifetime-err.rs:37:12
-   |
-LL | fn match_covariant_ref<'a>() {
-   |                        -- lifetime `'a` defined here
-...
-LL |     let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/inline-const/const-match-pat-lifetime.rs b/tests/ui/inline-const/const-match-pat-lifetime.rs
deleted file mode 100644
index 7f1011ea240..00000000000
--- a/tests/ui/inline-const/const-match-pat-lifetime.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-//@ run-pass
-
-#![feature(inline_const_pat)]
-
-use std::marker::PhantomData;
-
-// rust-lang/rust#78174: ICE: "cannot convert ReErased to a region vid"
-fn issue_78174() {
-    match "foo" {
-        const { concat!("fo", "o") } => (),
-        _ => unreachable!(),
-    }
-}
-
-#[derive(PartialEq, Eq)]
-pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
-
-impl<'a, T: ?Sized> InvariantRef<'a, T> {
-    pub const fn new(r: &'a T) -> Self {
-        InvariantRef(r, PhantomData)
-    }
-}
-
-fn match_invariant_ref<'a>() {
-    match const { InvariantRef::<'a, _>::new(&()) } {
-        const { InvariantRef::<'a, ()>::new(&()) } => {
-        }
-    }
-}
-
-fn main() {
-    issue_78174();
-    match_invariant_ref();
-}
diff --git a/tests/ui/inline-const/const-match-pat-range.rs b/tests/ui/inline-const/const-match-pat-range.rs
deleted file mode 100644
index 7202c0c0452..00000000000
--- a/tests/ui/inline-const/const-match-pat-range.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-//@ build-pass
-
-#![feature(inline_const_pat)]
-
-fn main() {
-    const N: u32 = 10;
-    let x: u32 = 3;
-
-    match x {
-        1 ..= const { N + 1 } => {},
-        _ => {},
-    }
-
-    match x {
-        const { N - 1 } ..= 10 => {},
-        _ => {},
-    }
-
-    match x {
-        const { N - 1 } ..= const { N + 1 } => {},
-        _ => {},
-    }
-
-    match x {
-        .. const { N + 1 } => {},
-        _ => {},
-    }
-
-    match x {
-        const { N - 1 } .. => {},
-        _ => {},
-    }
-
-    match x {
-        ..= const { N + 1 } => {},
-        _ => {}
-    }
-}
diff --git a/tests/ui/inline-const/const-match-pat.rs b/tests/ui/inline-const/const-match-pat.rs
deleted file mode 100644
index 1580ef25812..00000000000
--- a/tests/ui/inline-const/const-match-pat.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ run-pass
-
-#![feature(inline_const_pat)]
-const MMIO_BIT1: u8 = 4;
-const MMIO_BIT2: u8 = 5;
-
-fn main() {
-    let s = match read_mmio() {
-        0 => "FOO",
-        const { 1 << MMIO_BIT1 } => "BAR",
-        const { 1 << MMIO_BIT2 } => "BAZ",
-        _ => unreachable!(),
-    };
-
-    assert_eq!("BAZ", s);
-}
-
-fn read_mmio() -> i32 {
-    1 << 5
-}
diff --git a/tests/ui/inline-const/in-pat-recovery.rs b/tests/ui/inline-const/in-pat-recovery.rs
new file mode 100644
index 00000000000..0d912af0981
--- /dev/null
+++ b/tests/ui/inline-const/in-pat-recovery.rs
@@ -0,0 +1,11 @@
+// While `feature(inline_const_pat)` has been removed from the
+// compiler, we should still make sure that the resulting error
+// message is acceptable.
+fn main() {
+    match 1 {
+        const { 1 + 7 } => {}
+        //~^ `inline_const_pat` has been removed
+        2 => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/inline-const/in-pat-recovery.stderr b/tests/ui/inline-const/in-pat-recovery.stderr
new file mode 100644
index 00000000000..e1f2e681e77
--- /dev/null
+++ b/tests/ui/inline-const/in-pat-recovery.stderr
@@ -0,0 +1,10 @@
+error: `inline_const_pat` has been removed
+  --> $DIR/in-pat-recovery.rs:6:15
+   |
+LL |         const { 1 + 7 } => {}
+   |               ^^^^^^^^^
+   |
+   = help: use a named `const`-item or an `if`-guard instead
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/inline-const/pat-match-fndef.rs b/tests/ui/inline-const/pat-match-fndef.rs
deleted file mode 100644
index 013a4a67561..00000000000
--- a/tests/ui/inline-const/pat-match-fndef.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![feature(inline_const_pat)]
-
-fn uwu() {}
-
-fn main() {
-    let x = [];
-    match x[123] {
-        const { uwu } => {}
-        //~^ ERROR `fn() {uwu}` cannot be used in patterns
-        _ => {}
-    }
-}
diff --git a/tests/ui/inline-const/pat-match-fndef.stderr b/tests/ui/inline-const/pat-match-fndef.stderr
deleted file mode 100644
index 220437a0491..00000000000
--- a/tests/ui/inline-const/pat-match-fndef.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fn item `fn() {uwu}` cannot be used in patterns
-  --> $DIR/pat-match-fndef.rs:8:9
-   |
-LL |         const { uwu } => {}
-   |         ^^^^^^^^^^^^^ fn item can't be used in patterns
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/inline-const/pat-unsafe-err.rs b/tests/ui/inline-const/pat-unsafe-err.rs
deleted file mode 100644
index b906def7029..00000000000
--- a/tests/ui/inline-const/pat-unsafe-err.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-#![feature(inline_const_pat)]
-
-const unsafe fn require_unsafe() -> usize {
-    1
-}
-
-fn main() {
-    match () {
-        const {
-            require_unsafe();
-            //~^ ERROR [E0133]
-        } => (),
-    }
-
-    match 1 {
-        const {
-            require_unsafe()
-            //~^ ERROR [E0133]
-        }..=4 => (),
-        _ => (),
-    }
-}
diff --git a/tests/ui/inline-const/pat-unsafe-err.stderr b/tests/ui/inline-const/pat-unsafe-err.stderr
deleted file mode 100644
index 786c7f31ccc..00000000000
--- a/tests/ui/inline-const/pat-unsafe-err.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
-  --> $DIR/pat-unsafe-err.rs:10:13
-   |
-LL |             require_unsafe();
-   |             ^^^^^^^^^^^^^^^^ call to unsafe function
-   |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
-
-error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
-  --> $DIR/pat-unsafe-err.rs:17:13
-   |
-LL |             require_unsafe()
-   |             ^^^^^^^^^^^^^^^^ call to unsafe function
-   |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/inline-const/pat-unsafe.rs b/tests/ui/inline-const/pat-unsafe.rs
deleted file mode 100644
index 4b05f3a1cdd..00000000000
--- a/tests/ui/inline-const/pat-unsafe.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-//@ check-pass
-
-#![warn(unused_unsafe)]
-#![feature(inline_const_pat)]
-
-const unsafe fn require_unsafe() -> usize {
-    1
-}
-
-fn main() {
-    unsafe {
-        match () {
-            const {
-                require_unsafe();
-                unsafe {}
-                //~^ WARNING unnecessary `unsafe` block
-            } => (),
-        }
-
-        match 1 {
-            const {
-                unsafe {}
-                //~^ WARNING unnecessary `unsafe` block
-                require_unsafe()
-            }..=4 => (),
-            _ => (),
-        }
-    }
-}
diff --git a/tests/ui/inline-const/pat-unsafe.stderr b/tests/ui/inline-const/pat-unsafe.stderr
deleted file mode 100644
index 59460271ac0..00000000000
--- a/tests/ui/inline-const/pat-unsafe.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-warning: unnecessary `unsafe` block
-  --> $DIR/pat-unsafe.rs:15:17
-   |
-LL |                 unsafe {}
-   |                 ^^^^^^ unnecessary `unsafe` block
-   |
-note: the lint level is defined here
-  --> $DIR/pat-unsafe.rs:3:9
-   |
-LL | #![warn(unused_unsafe)]
-   |         ^^^^^^^^^^^^^
-
-warning: unnecessary `unsafe` block
-  --> $DIR/pat-unsafe.rs:22:17
-   |
-LL |                 unsafe {}
-   |                 ^^^^^^ unnecessary `unsafe` block
-
-warning: 2 warnings emitted
-
diff --git a/tests/ui/instrument-coverage/mcdc-condition-limit.rs b/tests/ui/instrument-coverage/mcdc-condition-limit.rs
index 118ae482fc6..74707ba2e67 100644
--- a/tests/ui/instrument-coverage/mcdc-condition-limit.rs
+++ b/tests/ui/instrument-coverage/mcdc-condition-limit.rs
@@ -1,5 +1,4 @@
 //@ edition: 2021
-//@ min-llvm-version: 19
 //@ revisions: good
 //@ check-pass
 //@ compile-flags: -Cinstrument-coverage -Zcoverage-options=mcdc -Zno-profiler-runtime
diff --git a/tests/ui/instrument-xray/flags-always-never-1.rs b/tests/ui/instrument-xray/flags-always-never-1.rs
index 91032662e6b..97f03fca102 100644
--- a/tests/ui/instrument-xray/flags-always-never-1.rs
+++ b/tests/ui/instrument-xray/flags-always-never-1.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-xray
 //@ compile-flags: -Z instrument-xray=always,never
-//@ error-pattern: incorrect value `always,never` for unstable option `instrument-xray`
 
 fn main() {}
+
+//~? ERROR incorrect value `always,never` for unstable option `instrument-xray`
diff --git a/tests/ui/instrument-xray/flags-dupe-always.rs b/tests/ui/instrument-xray/flags-dupe-always.rs
index 41e4f267b47..e3a5b3b1c3e 100644
--- a/tests/ui/instrument-xray/flags-dupe-always.rs
+++ b/tests/ui/instrument-xray/flags-dupe-always.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-xray
 //@ compile-flags: -Z instrument-xray=always,always
-//@ error-pattern: incorrect value `always,always` for unstable option `instrument-xray`
 
 fn main() {}
+
+//~? ERROR incorrect value `always,always` for unstable option `instrument-xray`
diff --git a/tests/ui/instrument-xray/flags-dupe-ignore-loops.rs b/tests/ui/instrument-xray/flags-dupe-ignore-loops.rs
index ba5ea28d40b..648bd144632 100644
--- a/tests/ui/instrument-xray/flags-dupe-ignore-loops.rs
+++ b/tests/ui/instrument-xray/flags-dupe-ignore-loops.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-xray
 //@ compile-flags: -Z instrument-xray=ignore-loops,ignore-loops
-//@ error-pattern: incorrect value `ignore-loops,ignore-loops` for unstable option `instrument-xray`
 
 fn main() {}
+
+//~? ERROR incorrect value `ignore-loops,ignore-loops` for unstable option `instrument-xray`
diff --git a/tests/ui/instrument-xray/target-not-supported.rs b/tests/ui/instrument-xray/target-not-supported.rs
index cdae26f993d..2045913b186 100644
--- a/tests/ui/instrument-xray/target-not-supported.rs
+++ b/tests/ui/instrument-xray/target-not-supported.rs
@@ -2,8 +2,9 @@
 //
 //@ needs-llvm-components: x86
 //@ compile-flags: -Z instrument-xray --target x86_64-apple-darwin
-//@ error-pattern: error: XRay instrumentation is not supported for this target
 
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//~? ERROR XRay instrumentation is not supported for this target
diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr
index e7a45c2c88d..26253e078cb 100644
--- a/tests/ui/integral-indexing.stderr
+++ b/tests/ui/integral-indexing.stderr
@@ -5,8 +5,9 @@ LL |     v[3u8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<u8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i8`
@@ -16,8 +17,9 @@ LL |     v[3i8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<i8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `u32`
@@ -27,8 +29,9 @@ LL |     v[3u32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<u32>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i32`
@@ -38,8 +41,9 @@ LL |     v[3i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<i32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u8`
@@ -49,8 +53,9 @@ LL |     s.as_bytes()[3u8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<u8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i8`
@@ -60,8 +65,9 @@ LL |     s.as_bytes()[3i8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<i8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u32`
@@ -71,8 +77,9 @@ LL |     s.as_bytes()[3u32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<u32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i32`
@@ -82,8 +89,9 @@ LL |     s.as_bytes()[3i32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<i32>`
 
 error: aborting due to 8 previous errors
diff --git a/tests/ui/internal/internal-unstable-noallow.rs b/tests/ui/internal/internal-unstable-noallow.rs
index 57ddb93d880..507eeebddc0 100644
--- a/tests/ui/internal/internal-unstable-noallow.rs
+++ b/tests/ui/internal/internal-unstable-noallow.rs
@@ -4,20 +4,18 @@
 // the // ~ form.
 
 //@ aux-build:internal_unstable.rs
-//@ error-pattern:use of unstable library feature `function`
-//@ error-pattern:use of unstable library feature `struct_field`
-//@ error-pattern:use of unstable library feature `method`
-//@ error-pattern:use of unstable library feature `struct2_field`
 
 #[macro_use]
 extern crate internal_unstable;
 
 fn main() {
-    call_unstable_noallow!();
+    call_unstable_noallow!(); //~ ERROR use of unstable library feature `function`
 
-    construct_unstable_noallow!(0);
+    construct_unstable_noallow!(0); //~ ERROR use of unstable library feature `struct_field`
 
     |x: internal_unstable::Foo| { call_method_noallow!(x) };
+    //~^ ERROR use of unstable library feature `method`
 
     |x: internal_unstable::Bar| { access_field_noallow!(x) };
+    //~^ ERROR use of unstable library feature `struct2_field`
 }
diff --git a/tests/ui/internal/internal-unstable-noallow.stderr b/tests/ui/internal/internal-unstable-noallow.stderr
index 22f42abbd11..2cc55022ef3 100644
--- a/tests/ui/internal/internal-unstable-noallow.stderr
+++ b/tests/ui/internal/internal-unstable-noallow.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature `function`
-  --> $DIR/internal-unstable-noallow.rs:16:5
+  --> $DIR/internal-unstable-noallow.rs:12:5
    |
 LL |     call_unstable_noallow!();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     call_unstable_noallow!();
    = note: this error originates in the macro `call_unstable_noallow` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: use of unstable library feature `struct_field`
-  --> $DIR/internal-unstable-noallow.rs:18:5
+  --> $DIR/internal-unstable-noallow.rs:14:5
    |
 LL |     construct_unstable_noallow!(0);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |     construct_unstable_noallow!(0);
    = note: this error originates in the macro `construct_unstable_noallow` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: use of unstable library feature `method`
-  --> $DIR/internal-unstable-noallow.rs:20:35
+  --> $DIR/internal-unstable-noallow.rs:16:35
    |
 LL |     |x: internal_unstable::Foo| { call_method_noallow!(x) };
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^
@@ -29,7 +29,7 @@ LL |     |x: internal_unstable::Foo| { call_method_noallow!(x) };
    = note: this error originates in the macro `call_method_noallow` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: use of unstable library feature `struct2_field`
-  --> $DIR/internal-unstable-noallow.rs:22:35
+  --> $DIR/internal-unstable-noallow.rs:19:35
    |
 LL |     |x: internal_unstable::Bar| { access_field_noallow!(x) };
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/invalid-compile-flags/crate-type-flag.rs
index 01014307149..8ccce97f7bf 100644
--- a/tests/ui/invalid-compile-flags/crate-type-flag.rs
+++ b/tests/ui/invalid-compile-flags/crate-type-flag.rs
@@ -45,16 +45,17 @@
 // `proc-macro` is accepted, but `proc_macro` is not.
 //@ revisions: proc_underscore_macro
 //@[proc_underscore_macro] compile-flags: --crate-type=proc_macro
-//@[proc_underscore_macro] error-pattern: unknown crate type: `proc_macro`
 
 // Empty `--crate-type` not accepted.
 //@ revisions: empty_crate_type
 //@[empty_crate_type] compile-flags: --crate-type=
-//@[empty_crate_type] error-pattern: unknown crate type: ``
 
 // Random unknown crate type. Also check that we can handle non-ASCII.
 //@ revisions: unknown
 //@[unknown] compile-flags: --crate-type=🤡
-//@[unknown] error-pattern: unknown crate type: `🤡`
 
 fn main() {}
+
+//[proc_underscore_macro]~? ERROR unknown crate type: `proc_macro`
+//[empty_crate_type]~? ERROR unknown crate type: ``
+//[unknown]~? ERROR unknown crate type: `🤡`
diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs b/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs
index 6a4ecb9d839..c7973c686da 100644
--- a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs
+++ b/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs
@@ -13,8 +13,9 @@
 //@[aarch64] check-fail
 //@[aarch64] needs-llvm-components: aarch64
 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
-//@[aarch64] error-pattern: `-Zfunction-return` (except `keep`) is only supported on x86 and x86_64
 
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//[aarch64]~? ERROR `-Zfunction-return` (except `keep`) is only supported on x86 and x86_64
diff --git a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs b/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs
index f4be36e08f0..fa3958c1f98 100644
--- a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs
+++ b/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs
@@ -14,8 +14,9 @@
 
 //@[large] check-fail
 //@[large] compile-flags: -Ccode-model=large
-//@[large] error-pattern: `-Zfunction-return=thunk-extern` is only supported on non-large code models
 
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//[large]~? ERROR `-Zfunction-return=thunk-extern` is only supported on non-large code models
diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr
index aa8a2ae42db..8abaee5056b 100644
--- a/tests/ui/invalid-compile-flags/print-without-arg.stderr
+++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr
@@ -1,5 +1,5 @@
 error: Argument to option 'print' missing
        Usage:
-           --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
+           --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                                Compiler information to print on stdout
 
diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/invalid-compile-flags/print.stderr
index f9cfb1616ce..e3374eb1e6e 100644
--- a/tests/ui/invalid-compile-flags/print.stderr
+++ b/tests/ui/invalid-compile-flags/print.stderr
@@ -1,5 +1,5 @@
 error: unknown print request: `yyyy`
   |
-  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
   = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
 
diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs b/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs
index b5e34bece32..436442ee729 100644
--- a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs
+++ b/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs
@@ -9,13 +9,14 @@
 //@[x86_64] check-fail
 //@[x86_64] needs-llvm-components: x86
 //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
-//@[x86_64] error-pattern: `-Zreg-struct-return` is only supported on x86
 
 //@[aarch64] check-fail
 //@[aarch64] needs-llvm-components: aarch64
 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
-//@[aarch64] error-pattern: `-Zreg-struct-return` is only supported on x86
 
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//[x86_64]~? ERROR `-Zreg-struct-return` is only supported on x86
+//[aarch64]~? ERROR `-Zreg-struct-return` is only supported on x86
diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs
index b548d678520..a66dfe85977 100644
--- a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs
+++ b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs
@@ -17,8 +17,9 @@
 
 //@[regparm4] check-fail
 //@[regparm4] compile-flags: -Zregparm=4
-//@[regparm4] error-pattern: `-Zregparm=4` is unsupported (valid values 0-3)
 
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//[regparm4]~? ERROR `-Zregparm=4` is unsupported (valid values 0-3)
diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs b/tests/ui/invalid-compile-flags/regparm/requires-x86.rs
index ce6e437fb47..32c4b5af357 100644
--- a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs
+++ b/tests/ui/invalid-compile-flags/regparm/requires-x86.rs
@@ -9,13 +9,14 @@
 //@[x86_64] check-fail
 //@[x86_64] needs-llvm-components: x86
 //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
-//@[x86_64] error-pattern: `-Zregparm=N` is only supported on x86
 
 //@[aarch64] check-fail
 //@[aarch64] needs-llvm-components: aarch64
 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
-//@[aarch64] error-pattern: `-Zregparm=N` is only supported on x86
 
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//[x86_64]~? ERROR `-Zregparm=N` is only supported on x86
+//[aarch64]~? ERROR `-Zregparm=N` is only supported on x86
diff --git a/tests/ui/invalid/issue-114435-layout-type-err.rs b/tests/ui/invalid/issue-114435-layout-type-err.rs
index 2a86839e416..07f310478d3 100644
--- a/tests/ui/invalid/issue-114435-layout-type-err.rs
+++ b/tests/ui/invalid/issue-114435-layout-type-err.rs
@@ -1,6 +1,5 @@
 //@ check-fail
 //@ compile-flags: --crate-type lib -Cdebuginfo=2
-//@ error-pattern: recursion limit
 
 #![recursion_limit = "10"]
 macro_rules! link {
@@ -41,3 +40,5 @@ link!(J, K);
 link!(K, Bottom);
 
 fn main() {}
+
+//~? ERROR reached the recursion limit finding the struct tail for `Bottom`
diff --git a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs
index 7cae77eb67f..5a5d0086aa9 100644
--- a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs
+++ b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs
@@ -16,8 +16,6 @@
 // rely on the checking of the normalized stderr output as our actual
 // "verification" of the diagnostic).
 
-//@ error-pattern: error
-
 // On Mac OS X, we get an error like the below
 //@ normalize-stderr: "failed to write bytecode to ./does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying ./does-not-exist/"
 
@@ -29,3 +27,5 @@
 //@ ignore-arm - the file-system issues do not replicate here, at least on armhf-gnu
 
 #![crate_type = "lib"]
+
+//~? ERROR /does-not-exist/
diff --git a/tests/ui/issues/issue-37131.rs b/tests/ui/issues/issue-37131.rs
index 3ea14672e23..16681ac21d1 100644
--- a/tests/ui/issues/issue-37131.rs
+++ b/tests/ui/issues/issue-37131.rs
@@ -1,3 +1,4 @@
+//~ ERROR can't find crate for `std`
 // Tests that compiling for a target which is not installed will result in a helpful
 // error message.
 
diff --git a/tests/ui/lang-items/lang-item-missing.rs b/tests/ui/lang-items/lang-item-missing.rs
index 5b832a5bb8f..75e203d04f2 100644
--- a/tests/ui/lang-items/lang-item-missing.rs
+++ b/tests/ui/lang-items/lang-item-missing.rs
@@ -1,13 +1,11 @@
 // Test that a missing lang item (in this case `sized`) does not cause an ICE,
 // see #17392.
 
-//@ error-pattern: requires `sized` lang_item
-
 #![feature(lang_items, no_core)]
 #![no_core]
 #![no_main]
 
 #[no_mangle]
-extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
+extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { //~ ERROR requires `sized` lang_item
     loop {}
 }
diff --git a/tests/ui/lang-items/lang-item-missing.stderr b/tests/ui/lang-items/lang-item-missing.stderr
index 63bca95adf7..85e9eaafe72 100644
--- a/tests/ui/lang-items/lang-item-missing.stderr
+++ b/tests/ui/lang-items/lang-item-missing.stderr
@@ -1,5 +1,5 @@
 error: requires `sized` lang_item
-  --> $DIR/lang-item-missing.rs:11:60
+  --> $DIR/lang-item-missing.rs:9:60
    |
 LL | extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
    |                                                            ^^^
diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs
index 9b634ee8ee3..f92a00e602c 100644
--- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs
+++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs
@@ -1,5 +1,3 @@
-//@ error-pattern: requires `copy` lang_item
-
 #![feature(lang_items, no_core)]
 #![no_core]
 #![no_main]
@@ -11,5 +9,5 @@ struct S;
 
 #[no_mangle]
 extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
-    argc
+    argc //~ ERROR requires `copy` lang_item
 }
diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr
index 3dc7716ecd2..9b25b1db292 100644
--- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr
+++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr
@@ -1,5 +1,5 @@
 error: requires `copy` lang_item
-  --> $DIR/missing-copy-lang-item-issue-19660.rs:14:5
+  --> $DIR/missing-copy-lang-item-issue-19660.rs:12:5
    |
 LL |     argc
    |     ^^^^
diff --git a/tests/ui/layout/reprc-power-alignment.rs b/tests/ui/layout/reprc-power-alignment.rs
index f6c1df55988..f144094d43f 100644
--- a/tests/ui/layout/reprc-power-alignment.rs
+++ b/tests/ui/layout/reprc-power-alignment.rs
@@ -148,5 +148,29 @@ pub struct I {
     d: f32,
     e: f64,
 }
-
+#[repr(C)]
+pub struct J {
+    a: u8,
+    b: I,
+}
+// The lint also ignores diagnosing #[repr(align(n))].
+#[repr(C, align(8))]
+pub struct K {
+    a: u8,
+    b: u8,
+    c: f64,
+    d: f32,
+    e: f64,
+}
+#[repr(C)]
+pub struct L {
+    a: u8,
+    b: K,
+}
+#[repr(C, align(8))]
+pub struct M {
+    a: u8,
+    b: K,
+    c: L,
+}
 fn main() { }
diff --git a/tests/ui/layout/size-of-val-raw-too-big.rs b/tests/ui/layout/size-of-val-raw-too-big.rs
index dfca6d6eb76..566b01255fa 100644
--- a/tests/ui/layout/size-of-val-raw-too-big.rs
+++ b/tests/ui/layout/size-of-val-raw-too-big.rs
@@ -1,7 +1,8 @@
+//~ ERROR values of the type `Example` are too big for the target architecture
 //@ build-fail
 //@ compile-flags: --crate-type lib
 //@ only-32bit Layout computation rejects this layout for different reasons on 64-bit.
-//@ error-pattern: too big for the target architecture
+
 #![feature(core_intrinsics)]
 #![allow(internal_features)]
 
diff --git a/tests/ui/layout/unknown-when-no-type-parameter.rs b/tests/ui/layout/unknown-when-no-type-parameter.rs
index 94c32cf262f..500b7938eeb 100644
--- a/tests/ui/layout/unknown-when-no-type-parameter.rs
+++ b/tests/ui/layout/unknown-when-no-type-parameter.rs
@@ -1,6 +1,5 @@
 #![feature(trivial_bounds)]
 
-//@ error-pattern: error[E0080]: evaluation of constant value failed
 //@ error-pattern: the type `<() as Project>::Assoc` has an unknown layout
 
 trait Project {
@@ -8,7 +7,7 @@ trait Project {
 }
 
 fn foo() where (): Project {
-    [(); size_of::<<() as Project>::Assoc>()];
+    [(); size_of::<<() as Project>::Assoc>()]; //~ ERROR evaluation of constant value failed
 }
 
 fn main() {}
diff --git a/tests/ui/layout/unknown-when-no-type-parameter.stderr b/tests/ui/layout/unknown-when-no-type-parameter.stderr
index 9e414d224bb..a2dbb191ee2 100644
--- a/tests/ui/layout/unknown-when-no-type-parameter.stderr
+++ b/tests/ui/layout/unknown-when-no-type-parameter.stderr
@@ -1,5 +1,5 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/unknown-when-no-type-parameter.rs:11:10
+  --> $DIR/unknown-when-no-type-parameter.rs:10:10
    |
 LL |     [(); size_of::<<() as Project>::Assoc>()];
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `<() as Project>::Assoc` has an unknown layout
diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs
index 5407902daba..85deab4bc4c 100644
--- a/tests/ui/limits/issue-17913.rs
+++ b/tests/ui/limits/issue-17913.rs
@@ -1,6 +1,5 @@
 //@ build-fail
 //@ normalize-stderr: "\[&usize; \d+\]" -> "[&usize; usize::MAX]"
-//@ error-pattern: too big for the target architecture
 
 #[cfg(target_pointer_width = "64")]
 fn main() {
@@ -15,3 +14,5 @@ fn main() {
     let a: Box<_> = Box::new([&n; 0xFFFFFFFF_usize]);
     println!("{}", a[0xFFFFFF_usize]);
 }
+
+//~? ERROR are too big for the target architecture
diff --git a/tests/ui/limits/issue-55878.rs b/tests/ui/limits/issue-55878.rs
index db4a2724452..614ff328bf5 100644
--- a/tests/ui/limits/issue-55878.rs
+++ b/tests/ui/limits/issue-55878.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-//@ error-pattern: are too big for the target architecture
 fn main() {
     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
+    //~^ ERROR evaluation of constant value failed
 }
diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr
index d705b3daf79..9b3922d7933 100644
--- a/tests/ui/limits/issue-55878.stderr
+++ b/tests/ui/limits/issue-55878.stderr
@@ -1,5 +1,5 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/issue-55878.rs:5:26
+  --> $DIR/issue-55878.rs:4:26
    |
 LL |     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; usize::MAX]` are too big for the target architecture
diff --git a/tests/ui/link-native-libs/empty-kind-1.rs b/tests/ui/link-native-libs/empty-kind-1.rs
index d9b8d8a7f7d..04e7e3c2c7b 100644
--- a/tests/ui/link-native-libs/empty-kind-1.rs
+++ b/tests/ui/link-native-libs/empty-kind-1.rs
@@ -1,6 +1,7 @@
 // Unspecified kind should fail with an error
 
 //@ compile-flags: -l =mylib
-//@ error-pattern: unknown library kind ``, expected one of: static, dylib, framework, link-arg
 
 fn main() {}
+
+//~? ERROR unknown library kind ``
diff --git a/tests/ui/link-native-libs/empty-kind-2.rs b/tests/ui/link-native-libs/empty-kind-2.rs
index 16cb3b917e4..1436c086dfd 100644
--- a/tests/ui/link-native-libs/empty-kind-2.rs
+++ b/tests/ui/link-native-libs/empty-kind-2.rs
@@ -1,6 +1,7 @@
 // Unspecified kind should fail with an error
 
 //@ compile-flags: -l :+bundle=mylib
-//@ error-pattern: unknown library kind ``, expected one of: static, dylib, framework, link-arg
 
 fn main() {}
+
+//~? ERROR unknown library kind ``
diff --git a/tests/ui/link-native-libs/link-arg-error.rs b/tests/ui/link-native-libs/link-arg-error.rs
index 4defb108178..9d9dcc27ccb 100644
--- a/tests/ui/link-native-libs/link-arg-error.rs
+++ b/tests/ui/link-native-libs/link-arg-error.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: -l link-arg:+bundle=arg -Z unstable-options
-//@ error-pattern: linking modifier `bundle` is only compatible with `static` linking kind
 
 fn main() {}
+
+//~? ERROR linking modifier `bundle` is only compatible with `static` linking kind
diff --git a/tests/ui/link-native-libs/manual-link-bad-form.rs b/tests/ui/link-native-libs/manual-link-bad-form.rs
index 0f5723adec9..71e80c60dec 100644
--- a/tests/ui/link-native-libs/manual-link-bad-form.rs
+++ b/tests/ui/link-native-libs/manual-link-bad-form.rs
@@ -1,5 +1,6 @@
 //@ compile-flags:-l static=
-//@ error-pattern: library name must not be empty
 
 fn main() {
 }
+
+//~? ERROR library name must not be empty
diff --git a/tests/ui/link-native-libs/manual-link-bad-kind.rs b/tests/ui/link-native-libs/manual-link-bad-kind.rs
index d070faa6574..8b5f478e80a 100644
--- a/tests/ui/link-native-libs/manual-link-bad-kind.rs
+++ b/tests/ui/link-native-libs/manual-link-bad-kind.rs
@@ -1,5 +1,6 @@
 //@ compile-flags:-l bar=foo
-//@ error-pattern: unknown library kind `bar`, expected one of: static, dylib, framework, link-arg
 
 fn main() {
 }
+
+//~? ERROR unknown library kind `bar`
diff --git a/tests/ui/link-native-libs/manual-link-bad-search-path.rs b/tests/ui/link-native-libs/manual-link-bad-search-path.rs
index c9ced4734fc..cc4a5ef2267 100644
--- a/tests/ui/link-native-libs/manual-link-bad-search-path.rs
+++ b/tests/ui/link-native-libs/manual-link-bad-search-path.rs
@@ -1,5 +1,6 @@
 //@ compile-flags:-L native=
-//@ error-pattern: empty search path given via `-L`
 
 fn main() {
 }
+
+//~? ERROR empty search path given via `-L`
diff --git a/tests/ui/link-native-libs/manual-link-framework.rs b/tests/ui/link-native-libs/manual-link-framework.rs
index 43cdda0a4e6..b3c3d6a7c3c 100644
--- a/tests/ui/link-native-libs/manual-link-framework.rs
+++ b/tests/ui/link-native-libs/manual-link-framework.rs
@@ -1,5 +1,6 @@
 //@ ignore-apple
 //@ compile-flags:-l framework=foo
-//@ error-pattern: library kind `framework` is only supported on Apple targets
 
 fn main() {}
+
+//~? ERROR library kind `framework` is only supported on Apple targets
diff --git a/tests/ui/link-native-libs/manual-link-unsupported-kind.rs b/tests/ui/link-native-libs/manual-link-unsupported-kind.rs
index b5b9e3e6577..3dfe9bdebc5 100644
--- a/tests/ui/link-native-libs/manual-link-unsupported-kind.rs
+++ b/tests/ui/link-native-libs/manual-link-unsupported-kind.rs
@@ -1,5 +1,6 @@
 //@ compile-flags:-l raw-dylib=foo
-//@ error-pattern: unknown library kind `raw-dylib`, expected one of: static, dylib, framework, link-arg
 
 fn main() {
 }
+
+//~? ERROR unknown library kind `raw-dylib`
diff --git a/tests/ui/link-native-libs/modifiers-override-3.rs b/tests/ui/link-native-libs/modifiers-override-3.rs
index d05735ad616..3d269dbd812 100644
--- a/tests/ui/link-native-libs/modifiers-override-3.rs
+++ b/tests/ui/link-native-libs/modifiers-override-3.rs
@@ -2,6 +2,7 @@
 // overrides another command line library with modifiers.
 
 //@ compile-flags:-lstatic:+whole-archive=foo -lstatic:+whole-archive=foo
-//@ error-pattern: overriding linking modifiers from command line is not supported
 
 fn main() {}
+
+//~? ERROR overriding linking modifiers from command line is not supported
diff --git a/tests/ui/link-native-libs/suggest-libname-only-1.rs b/tests/ui/link-native-libs/suggest-libname-only-1.rs
index 328181fb5cb..4ccfa086bde 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-1.rs
+++ b/tests/ui/link-native-libs/suggest-libname-only-1.rs
@@ -1,9 +1,10 @@
 //@ build-fail
 //@ compile-flags: --crate-type rlib
-//@ error-pattern: could not find native static library `libfoo.a`
 //@ error-pattern: only provide the library name `foo`, not the full filename
 
 #[link(name = "libfoo.a", kind = "static")]
-extern { }
+extern { } //~ WARN extern declarations without an explicit ABI are deprecated
 
 pub fn main() { }
+
+//~? ERROR could not find native static library `libfoo.a`
diff --git a/tests/ui/link-native-libs/suggest-libname-only-1.stderr b/tests/ui/link-native-libs/suggest-libname-only-1.stderr
index 47f7d92c9f9..85a3599e8db 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-1.stderr
+++ b/tests/ui/link-native-libs/suggest-libname-only-1.stderr
@@ -1,5 +1,5 @@
 warning: extern declarations without an explicit ABI are deprecated
-  --> $DIR/suggest-libname-only-1.rs:7:1
+  --> $DIR/suggest-libname-only-1.rs:6:1
    |
 LL | extern { }
    | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
diff --git a/tests/ui/link-native-libs/suggest-libname-only-2.rs b/tests/ui/link-native-libs/suggest-libname-only-2.rs
index 7ed106e4ab4..c35b4a674b7 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-2.rs
+++ b/tests/ui/link-native-libs/suggest-libname-only-2.rs
@@ -1,9 +1,10 @@
 //@ build-fail
 //@ compile-flags: --crate-type rlib
-//@ error-pattern: could not find native static library `bar.lib`
 //@ error-pattern: only provide the library name `bar`, not the full filename
 
 #[link(name = "bar.lib", kind = "static")]
-extern { }
+extern { } //~ WARN extern declarations without an explicit ABI are deprecated
 
 pub fn main() { }
+
+//~? ERROR could not find native static library `bar.lib`
diff --git a/tests/ui/link-native-libs/suggest-libname-only-2.stderr b/tests/ui/link-native-libs/suggest-libname-only-2.stderr
index a2d8f4c8191..d5c88931ad5 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-2.stderr
+++ b/tests/ui/link-native-libs/suggest-libname-only-2.stderr
@@ -1,5 +1,5 @@
 warning: extern declarations without an explicit ABI are deprecated
-  --> $DIR/suggest-libname-only-2.rs:7:1
+  --> $DIR/suggest-libname-only-2.rs:6:1
    |
 LL | extern { }
    | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
diff --git a/tests/ui/linkage-attr/incompatible-flavor.rs b/tests/ui/linkage-attr/incompatible-flavor.rs
index acf720bc97a..7f583f47e2f 100644
--- a/tests/ui/linkage-attr/incompatible-flavor.rs
+++ b/tests/ui/linkage-attr/incompatible-flavor.rs
@@ -1,6 +1,7 @@
 //@ compile-flags: --target=x86_64-unknown-linux-gnu -C linker-flavor=msvc --crate-type=rlib
-//@ error-pattern: linker flavor `msvc` is incompatible with the current target
 //@ needs-llvm-components:
 
 #![feature(no_core)]
 #![no_core]
+
+//~? ERROR linker flavor `msvc` is incompatible with the current target
diff --git a/tests/ui/linkage-attr/issue-10755.rs b/tests/ui/linkage-attr/issue-10755.rs
index 58d5b5ead57..509f484adf8 100644
--- a/tests/ui/linkage-attr/issue-10755.rs
+++ b/tests/ui/linkage-attr/issue-10755.rs
@@ -1,10 +1,11 @@
 //@ build-fail
 //@ dont-check-compiler-stderr
 //@ compile-flags: -C linker=llllll
-//@ error-pattern: `llllll`
 
 // Before, the error-pattern checked for "not found". On WSL with appendWindowsPath=true, running
 // in invalid command returns a PermissionDenied instead.
 
 fn main() {
 }
+
+//~? ERROR `llllll`
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs b/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs
index f4715ff2d3d..030b95198f5 100644
--- a/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs
+++ b/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs
@@ -35,3 +35,5 @@ fn main() {
   meooooooooooooooow();
   woooooooooooooooooof();
 }
+
+//[without]~? ERROR linking with `
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs b/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs
index fe9c7884e54..20de4afcee0 100644
--- a/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs
+++ b/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs
@@ -26,3 +26,5 @@ unsafe extern "C" {
 fn main() {
   meooooooooooooooow();
 }
+
+//[without]~? ERROR linking with `
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs b/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs
index 72cba18d841..302ec0edeaa 100644
--- a/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs
+++ b/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs
@@ -27,3 +27,5 @@ unsafe extern "C" {
 fn main() {
   meooooooooooooooow();
 }
+
+//[without]~? ERROR linking with `
diff --git a/tests/ui/linkage-attr/unstable-flavor.rs b/tests/ui/linkage-attr/unstable-flavor.rs
index 82d9dff3874..6aa9efb58d1 100644
--- a/tests/ui/linkage-attr/unstable-flavor.rs
+++ b/tests/ui/linkage-attr/unstable-flavor.rs
@@ -4,11 +4,12 @@
 //
 //@ revisions: bpf ptx
 //@ [bpf] compile-flags: --target=bpfel-unknown-none -C linker-flavor=bpf --crate-type=rlib
-//@ [bpf] error-pattern: linker flavor `bpf` is unstable, the `-Z unstable-options` flag
 //@ [bpf] needs-llvm-components:
 //@ [ptx] compile-flags: --target=nvptx64-nvidia-cuda -C linker-flavor=ptx --crate-type=rlib
-//@ [ptx] error-pattern: linker flavor `ptx` is unstable, the `-Z unstable-options` flag
 //@ [ptx] needs-llvm-components:
 
 #![feature(no_core)]
 #![no_core]
+
+//[bpf]~? ERROR the linker flavor `bpf` is unstable
+//[ptx]~? ERROR the linker flavor `ptx` is unstable
diff --git a/tests/ui/linkage-attr/link-self-contained-consistency.many.stderr b/tests/ui/linking/link-self-contained-consistency.many.stderr
index a5fc96b4e0b..a5fc96b4e0b 100644
--- a/tests/ui/linkage-attr/link-self-contained-consistency.many.stderr
+++ b/tests/ui/linking/link-self-contained-consistency.many.stderr
diff --git a/tests/ui/linkage-attr/link-self-contained-consistency.one.stderr b/tests/ui/linking/link-self-contained-consistency.one.stderr
index 5982b7a618e..5982b7a618e 100644
--- a/tests/ui/linkage-attr/link-self-contained-consistency.one.stderr
+++ b/tests/ui/linking/link-self-contained-consistency.one.stderr
diff --git a/tests/ui/linkage-attr/link-self-contained-consistency.rs b/tests/ui/linking/link-self-contained-consistency.rs
index 08227433891..08227433891 100644
--- a/tests/ui/linkage-attr/link-self-contained-consistency.rs
+++ b/tests/ui/linking/link-self-contained-consistency.rs
diff --git a/tests/ui/lint/bad-lint-cap.rs b/tests/ui/lint/bad-lint-cap.rs
index aab3f723796..c219cb1b665 100644
--- a/tests/ui/lint/bad-lint-cap.rs
+++ b/tests/ui/lint/bad-lint-cap.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: --cap-lints test
-//@ error-pattern: unknown lint level: `test`
 
 fn main() {}
+
+//~? ERROR unknown lint level: `test`
diff --git a/tests/ui/lint/cli-unknown-force-warn.rs b/tests/ui/lint/cli-unknown-force-warn.rs
index 007f8dd8732..330d5570e21 100644
--- a/tests/ui/lint/cli-unknown-force-warn.rs
+++ b/tests/ui/lint/cli-unknown-force-warn.rs
@@ -4,8 +4,11 @@
 //@ check-pass
 //@ compile-flags: --force-warn foo-qux
 
-//@ error-pattern: unknown lint: `foo_qux`
 //@ error-pattern: requested on the command line with `--force-warn foo_qux`
 //@ error-pattern: `#[warn(unknown_lints)]` on by default
 
 fn main() {}
+
+//~? WARN unknown lint: `foo_qux`
+//~? WARN unknown lint: `foo_qux`
+//~? WARN unknown lint: `foo_qux`
diff --git a/tests/ui/lint/command-line-register-unknown-lint-tool.rs b/tests/ui/lint/command-line-register-unknown-lint-tool.rs
index b4e9a067fe2..a517f4c7ea6 100644
--- a/tests/ui/lint/command-line-register-unknown-lint-tool.rs
+++ b/tests/ui/lint/command-line-register-unknown-lint-tool.rs
@@ -1,4 +1,7 @@
 //@ compile-flags: -A unknown_tool::foo
-//@ error-pattern: unknown lint tool: `unknown_tool`
 
 fn main() {}
+
+//~? ERROR unknown lint tool: `unknown_tool`
+//~? ERROR unknown lint tool: `unknown_tool`
+//~? ERROR unknown lint tool: `unknown_tool`
diff --git a/tests/ui/lint/dead-code/anon-const-in-pat.rs b/tests/ui/lint/dead-code/anon-const-in-pat.rs
deleted file mode 100644
index e2d8c90edcc..00000000000
--- a/tests/ui/lint/dead-code/anon-const-in-pat.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-//@ check-pass
-#![feature(inline_const_pat)]
-#![deny(dead_code)]
-
-const fn one() -> i32 {
-    1
-}
-
-const fn two() -> i32 {
-    2
-}
-
-const fn three() -> i32 {
-    3
-}
-
-fn inline_const() {
-    // rust-lang/rust#78171: dead_code lint triggers even though function is used in const pattern
-    match 1 {
-        const { one() } => {}
-        _ => {}
-    }
-}
-
-fn inline_const_range() {
-    match 1 {
-        1 ..= const { two() } => {}
-        _ => {}
-    }
-}
-
-struct S<const C: i32>;
-
-fn const_generic_arg() {
-    match S::<3> {
-        S::<{three()}> => {}
-    }
-}
-
-fn main() {
-    inline_const();
-    inline_const_range();
-    const_generic_arg();
-}
diff --git a/tests/ui/lint/force-warn/warnings-lint-group.rs b/tests/ui/lint/force-warn/warnings-lint-group.rs
index 944070527a1..28de42639d3 100644
--- a/tests/ui/lint/force-warn/warnings-lint-group.rs
+++ b/tests/ui/lint/force-warn/warnings-lint-group.rs
@@ -1,5 +1,8 @@
 // --force-warn warnings is an error
 //@ compile-flags: --force-warn warnings
-//@ error-pattern: `warnings` lint group is not supported
 
 fn main() {}
+
+//~? ERROR `warnings` lint group is not supported with ´--force-warn´
+//~? ERROR `warnings` lint group is not supported with ´--force-warn´
+//~? ERROR `warnings` lint group is not supported with ´--force-warn´
diff --git a/tests/ui/lint/inline-exported.rs b/tests/ui/lint/inline-exported.rs
new file mode 100644
index 00000000000..69e322ef513
--- /dev/null
+++ b/tests/ui/lint/inline-exported.rs
@@ -0,0 +1,30 @@
+//! Ensure the unused_attributes lint fires for externally exported functions with `#[inline]`,
+//! because `#[inline]` is ignored for such functions.
+
+#![crate_type = "lib"]
+
+#![feature(linkage)]
+#![feature(naked_functions)]
+#![deny(unused_attributes)]
+
+#[inline]
+//~^ ERROR: `#[inline]` is ignored on externally exported functions
+#[no_mangle]
+fn no_mangle() {}
+
+#[inline]
+//~^ ERROR: `#[inline]` is ignored on externally exported functions
+#[export_name = "export_name"]
+fn export_name() {}
+
+#[inline]
+//~^ ERROR: `#[inline]` is ignored on externally exported functions
+#[linkage = "external"]
+fn external_linkage() {}
+
+#[inline]
+fn normal() {}
+
+#[inline]
+#[linkage = "internal"] // not exported
+fn internal_linkage() {}
diff --git a/tests/ui/lint/inline-exported.stderr b/tests/ui/lint/inline-exported.stderr
new file mode 100644
index 00000000000..dcf63cc4090
--- /dev/null
+++ b/tests/ui/lint/inline-exported.stderr
@@ -0,0 +1,31 @@
+error: `#[inline]` is ignored on externally exported functions
+  --> $DIR/inline-exported.rs:10:1
+   |
+LL | #[inline]
+   | ^^^^^^^^^
+   |
+   = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
+note: the lint level is defined here
+  --> $DIR/inline-exported.rs:8:9
+   |
+LL | #![deny(unused_attributes)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: `#[inline]` is ignored on externally exported functions
+  --> $DIR/inline-exported.rs:15:1
+   |
+LL | #[inline]
+   | ^^^^^^^^^
+   |
+   = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
+
+error: `#[inline]` is ignored on externally exported functions
+  --> $DIR/inline-exported.rs:20:1
+   |
+LL | #[inline]
+   | ^^^^^^^^^
+   |
+   = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/invalid_null_args.rs b/tests/ui/lint/invalid_null_args.rs
new file mode 100644
index 00000000000..7948f0d86d0
--- /dev/null
+++ b/tests/ui/lint/invalid_null_args.rs
@@ -0,0 +1,136 @@
+// check-fail
+// run-rustfix
+
+use std::ptr;
+use std::mem;
+
+unsafe fn null_ptr() {
+    ptr::write(
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+        ptr::null_mut() as *mut u32,
+        mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+    );
+
+    let null_ptr = ptr::null_mut();
+    ptr::write(
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+        null_ptr as *mut u32,
+        mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+    );
+
+    let _: &[usize] = std::slice::from_raw_parts(ptr::null(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _: &[usize] = std::slice::from_raw_parts(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _: &[usize] = std::slice::from_raw_parts(0 as *mut _, 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _: &[usize] = std::slice::from_raw_parts(mem::transmute(0usize), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _: &[usize] = std::slice::from_raw_parts_mut(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::copy::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::copy::<usize>(ptr::NonNull::dangling().as_ptr(), ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::copy_nonoverlapping::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::copy_nonoverlapping::<usize>(
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+        ptr::NonNull::dangling().as_ptr(),
+        ptr::null_mut(),
+        0
+    );
+
+    #[derive(Copy, Clone)]
+    struct A(usize);
+    let mut v = A(200);
+
+    let _a: A = ptr::read(ptr::null());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _a: A = ptr::read(ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _a: A = ptr::read_unaligned(ptr::null());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _a: A = ptr::read_unaligned(ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _a: A = ptr::read_volatile(ptr::null());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _a: A = ptr::read_volatile(ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _a: A = ptr::replace(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::swap::<A>(ptr::null_mut(), &mut v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::swap::<A>(&mut v, ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write_unaligned(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write_volatile(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    // with indirections
+    let const_ptr = null_ptr as *const u8;
+    let _a: u8 = ptr::read(const_ptr);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+}
+
+unsafe fn zst() {
+    struct Zst; // zero-sized type
+
+    std::slice::from_raw_parts::<()>(ptr::null(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    std::slice::from_raw_parts::<Zst>(ptr::null(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::read::<()>(ptr::null());
+    ptr::read::<Zst>(ptr::null());
+
+    ptr::write(ptr::null_mut(), ());
+    ptr::write(ptr::null_mut(), Zst);
+
+    ptr::copy(ptr::null::<()>(), ptr::null_mut::<()>(), 1);
+    ptr::copy(ptr::null::<Zst>(), ptr::null_mut::<Zst>(), 1);
+}
+
+unsafe fn not_invalid() {
+    // Simplified false-positive from std quicksort implementation
+
+    let mut a = ptr::null_mut();
+    let mut b = ();
+
+    loop {
+        if false {
+            break;
+        }
+
+        a = &raw mut b;
+    }
+
+    ptr::write(a, ());
+}
+
+fn main() {}
diff --git a/tests/ui/lint/invalid_null_args.stderr b/tests/ui/lint/invalid_null_args.stderr
new file mode 100644
index 00000000000..f95bc2afa82
--- /dev/null
+++ b/tests/ui/lint/invalid_null_args.stderr
@@ -0,0 +1,330 @@
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:8:5
+   |
+LL | /     ptr::write(
+LL | |
+LL | |         ptr::null_mut() as *mut u32,
+   | |         --------------- null pointer originates from here
+LL | |         mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+LL | |     );
+   | |_____^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+   = note: `#[deny(invalid_null_arguments)]` on by default
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:15:5
+   |
+LL | /     ptr::write(
+LL | |
+LL | |         null_ptr as *mut u32,
+LL | |         mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+LL | |     );
+   | |_____^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+note: null pointer originates from here
+  --> $DIR/invalid_null_args.rs:14:20
+   |
+LL |     let null_ptr = ptr::null_mut();
+   |                    ^^^^^^^^^^^^^^^
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:21:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(ptr::null(), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                                  |
+   |                                                  null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:23:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(ptr::null_mut(), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                                  |
+   |                                                  null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:25:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(0 as *mut _, 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^
+   |                                                  |
+   |                                                  null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:27:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(mem::transmute(0usize), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^
+   |                                                                 |
+   |                                                                 null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:30:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts_mut(ptr::null_mut(), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                                      |
+   |                                                      null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:33:5
+   |
+LL |     ptr::copy::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                        |
+   |                        null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:35:5
+   |
+LL |     ptr::copy::<usize>(ptr::NonNull::dangling().as_ptr(), ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                                           |
+   |                                                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:38:5
+   |
+LL |     ptr::copy_nonoverlapping::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                       |
+   |                                       null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:40:5
+   |
+LL | /     ptr::copy_nonoverlapping::<usize>(
+LL | |
+LL | |         ptr::NonNull::dangling().as_ptr(),
+LL | |         ptr::null_mut(),
+   | |         --------------- null pointer originates from here
+LL | |         0
+LL | |     );
+   | |_____^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:51:17
+   |
+LL |     let _a: A = ptr::read(ptr::null());
+   |                 ^^^^^^^^^^-----------^
+   |                           |
+   |                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:53:17
+   |
+LL |     let _a: A = ptr::read(ptr::null_mut());
+   |                 ^^^^^^^^^^---------------^
+   |                           |
+   |                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:56:17
+   |
+LL |     let _a: A = ptr::read_unaligned(ptr::null());
+   |                 ^^^^^^^^^^^^^^^^^^^^-----------^
+   |                                     |
+   |                                     null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:58:17
+   |
+LL |     let _a: A = ptr::read_unaligned(ptr::null_mut());
+   |                 ^^^^^^^^^^^^^^^^^^^^---------------^
+   |                                     |
+   |                                     null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:61:17
+   |
+LL |     let _a: A = ptr::read_volatile(ptr::null());
+   |                 ^^^^^^^^^^^^^^^^^^^-----------^
+   |                                    |
+   |                                    null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:63:17
+   |
+LL |     let _a: A = ptr::read_volatile(ptr::null_mut());
+   |                 ^^^^^^^^^^^^^^^^^^^---------------^
+   |                                    |
+   |                                    null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:66:17
+   |
+LL |     let _a: A = ptr::replace(ptr::null_mut(), v);
+   |                 ^^^^^^^^^^^^^---------------^^^^
+   |                              |
+   |                              null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:69:5
+   |
+LL |     ptr::swap::<A>(ptr::null_mut(), &mut v);
+   |     ^^^^^^^^^^^^^^^---------------^^^^^^^^^
+   |                    |
+   |                    null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:71:5
+   |
+LL |     ptr::swap::<A>(&mut v, ptr::null_mut());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:74:5
+   |
+LL |     ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^^^^^
+   |                                   |
+   |                                   null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:76:5
+   |
+LL |     ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                           |
+   |                                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:79:5
+   |
+LL |     ptr::write(ptr::null_mut(), v);
+   |     ^^^^^^^^^^^---------------^^^^
+   |                |
+   |                null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:82:5
+   |
+LL |     ptr::write_unaligned(ptr::null_mut(), v);
+   |     ^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                          |
+   |                          null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:85:5
+   |
+LL |     ptr::write_volatile(ptr::null_mut(), v);
+   |     ^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                         |
+   |                         null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:88:5
+   |
+LL |     ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^
+   |                               |
+   |                               null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:93:18
+   |
+LL |     let _a: u8 = ptr::read(const_ptr);
+   |                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+note: null pointer originates from here
+  --> $DIR/invalid_null_args.rs:14:20
+   |
+LL |     let null_ptr = ptr::null_mut();
+   |                    ^^^^^^^^^^^^^^^
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:100:5
+   |
+LL |     std::slice::from_raw_parts::<()>(ptr::null(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                      |
+   |                                      null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:102:5
+   |
+LL |     std::slice::from_raw_parts::<Zst>(ptr::null(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                       |
+   |                                       null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:104:5
+   |
+LL |     std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                          |
+   |                                          null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:106:5
+   |
+LL |     std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                           |
+   |                                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: aborting due to 31 previous errors
+
diff --git a/tests/ui/lint/issue-104897.rs b/tests/ui/lint/issue-104897.rs
index 3cfe94bbd22..99bc1cf3a42 100644
--- a/tests/ui/lint/issue-104897.rs
+++ b/tests/ui/lint/issue-104897.rs
@@ -1,5 +1,2 @@
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: this file contains an unclosed delimiter
-
+//~v ERROR this file contains an unclosed delimiter
 fn f(){(print!(á
diff --git a/tests/ui/lint/issue-104897.stderr b/tests/ui/lint/issue-104897.stderr
index 584902ee4c0..ebc794bfb73 100644
--- a/tests/ui/lint/issue-104897.stderr
+++ b/tests/ui/lint/issue-104897.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-104897.rs:5:18
+  --> $DIR/issue-104897.rs:2:18
    |
 LL | fn f(){(print!(á
    |       --      - ^
diff --git a/tests/ui/lint/lint-pre-expansion-extern-module.rs b/tests/ui/lint/lint-pre-expansion-extern-module.rs
index b76879ccbb8..f1ab0cf3b74 100644
--- a/tests/ui/lint/lint-pre-expansion-extern-module.rs
+++ b/tests/ui/lint/lint-pre-expansion-extern-module.rs
@@ -1,7 +1,9 @@
 //@ check-pass
 //@ compile-flags: -W rust-2018-compatibility
-//@ error-pattern: `try` is a keyword in the 2018 edition
 
 fn main() {}
 
 mod lint_pre_expansion_extern_module_aux;
+
+//~? WARN `try` is a keyword in the 2018 edition
+//~? WARN this is accepted in the current edition
diff --git a/tests/ui/lint/lint-removed-cmdline-deny.rs b/tests/ui/lint/lint-removed-cmdline-deny.rs
index e56a95d292a..6616781d5cb 100644
--- a/tests/ui/lint/lint-removed-cmdline-deny.rs
+++ b/tests/ui/lint/lint-removed-cmdline-deny.rs
@@ -3,11 +3,14 @@
 
 //@ compile-flags:-D renamed-and-removed-lints -D raw_pointer_derive
 
-//@ error-pattern:lint `raw_pointer_derive` has been removed
 //@ error-pattern:requested on the command line with `-D raw_pointer_derive`
 //@ error-pattern:requested on the command line with `-D renamed-and-removed-lints`
 
 #![warn(unused)]
 
 #[deny(warnings)]
-fn main() { let unused = (); }
+fn main() { let unused = (); } //~ ERROR unused variable: `unused`
+
+//~? ERROR lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+//~? ERROR lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+//~? ERROR lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
diff --git a/tests/ui/lint/lint-removed-cmdline-deny.stderr b/tests/ui/lint/lint-removed-cmdline-deny.stderr
index 3321afa7fcd..27a3504a16a 100644
--- a/tests/ui/lint/lint-removed-cmdline-deny.stderr
+++ b/tests/ui/lint/lint-removed-cmdline-deny.stderr
@@ -14,13 +14,13 @@ error: lint `raw_pointer_derive` has been removed: using derive with raw pointer
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: unused variable: `unused`
-  --> $DIR/lint-removed-cmdline-deny.rs:13:17
+  --> $DIR/lint-removed-cmdline-deny.rs:12:17
    |
 LL | fn main() { let unused = (); }
    |                 ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
    |
 note: the lint level is defined here
-  --> $DIR/lint-removed-cmdline-deny.rs:12:8
+  --> $DIR/lint-removed-cmdline-deny.rs:11:8
    |
 LL | #[deny(warnings)]
    |        ^^^^^^^^
diff --git a/tests/ui/lint/lint-removed-cmdline.rs b/tests/ui/lint/lint-removed-cmdline.rs
index 3c9d3eb8e7b..4dde3dbc381 100644
--- a/tests/ui/lint/lint-removed-cmdline.rs
+++ b/tests/ui/lint/lint-removed-cmdline.rs
@@ -3,11 +3,14 @@
 
 //@ compile-flags:-D raw_pointer_derive
 
-//@ error-pattern:lint `raw_pointer_derive` has been removed
 //@ error-pattern:`#[warn(renamed_and_removed_lints)]` on by default
 //@ error-pattern:requested on the command line with `-D raw_pointer_derive`
 
 #![warn(unused)]
 
 #[deny(warnings)]
-fn main() { let unused = (); }
+fn main() { let unused = (); } //~ ERROR unused variable: `unused`
+
+//~? WARN lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+//~? WARN lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+//~? WARN lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
diff --git a/tests/ui/lint/lint-removed-cmdline.stderr b/tests/ui/lint/lint-removed-cmdline.stderr
index fd63433c308..7994f9bcfd9 100644
--- a/tests/ui/lint/lint-removed-cmdline.stderr
+++ b/tests/ui/lint/lint-removed-cmdline.stderr
@@ -14,13 +14,13 @@ warning: lint `raw_pointer_derive` has been removed: using derive with raw point
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: unused variable: `unused`
-  --> $DIR/lint-removed-cmdline.rs:13:17
+  --> $DIR/lint-removed-cmdline.rs:12:17
    |
 LL | fn main() { let unused = (); }
    |                 ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
    |
 note: the lint level is defined here
-  --> $DIR/lint-removed-cmdline.rs:12:8
+  --> $DIR/lint-removed-cmdline.rs:11:8
    |
 LL | #[deny(warnings)]
    |        ^^^^^^^^
diff --git a/tests/ui/lint/lint-renamed-cmdline-deny.rs b/tests/ui/lint/lint-renamed-cmdline-deny.rs
index 13500d006f8..0ea4ce40817 100644
--- a/tests/ui/lint/lint-renamed-cmdline-deny.rs
+++ b/tests/ui/lint/lint-renamed-cmdline-deny.rs
@@ -1,10 +1,12 @@
 //@ compile-flags:-D renamed-and-removed-lints -D bare_trait_object
 
-//@ error-pattern:lint `bare_trait_object` has been renamed to `bare_trait_objects`
 //@ error-pattern:use the new name `bare_trait_objects`
 //@ error-pattern:requested on the command line with `-D bare_trait_object`
 //@ error-pattern:requested on the command line with `-D renamed-and-removed-lints`
-//@ error-pattern:unused
 
 #[deny(unused)]
-fn main() { let unused = (); }
+fn main() { let unused = (); } //~ ERROR unused variable: `unused`
+
+//~? ERROR lint `bare_trait_object` has been renamed to `bare_trait_objects`
+//~? ERROR lint `bare_trait_object` has been renamed to `bare_trait_objects`
+//~? ERROR lint `bare_trait_object` has been renamed to `bare_trait_objects`
diff --git a/tests/ui/lint/lint-renamed-cmdline-deny.stderr b/tests/ui/lint/lint-renamed-cmdline-deny.stderr
index 0e182a4e5de..a49cdc84f9e 100644
--- a/tests/ui/lint/lint-renamed-cmdline-deny.stderr
+++ b/tests/ui/lint/lint-renamed-cmdline-deny.stderr
@@ -17,13 +17,13 @@ error: lint `bare_trait_object` has been renamed to `bare_trait_objects`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: unused variable: `unused`
-  --> $DIR/lint-renamed-cmdline-deny.rs:10:17
+  --> $DIR/lint-renamed-cmdline-deny.rs:8:17
    |
 LL | fn main() { let unused = (); }
    |                 ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
    |
 note: the lint level is defined here
-  --> $DIR/lint-renamed-cmdline-deny.rs:9:8
+  --> $DIR/lint-renamed-cmdline-deny.rs:7:8
    |
 LL | #[deny(unused)]
    |        ^^^^^^
diff --git a/tests/ui/lint/lint-renamed-cmdline.rs b/tests/ui/lint/lint-renamed-cmdline.rs
index 7adea98a609..45df7b6d640 100644
--- a/tests/ui/lint/lint-renamed-cmdline.rs
+++ b/tests/ui/lint/lint-renamed-cmdline.rs
@@ -1,9 +1,11 @@
 //@ compile-flags:-D bare_trait_object
 
-//@ error-pattern:lint `bare_trait_object` has been renamed to `bare_trait_objects`
 //@ error-pattern:requested on the command line with `-D bare_trait_object`
 //@ error-pattern:`#[warn(renamed_and_removed_lints)]` on by default
-//@ error-pattern:unused
 
 #[deny(unused)]
-fn main() { let unused = (); }
+fn main() { let unused = (); } //~ ERROR unused variable: `unused`
+
+//~? WARN lint `bare_trait_object` has been renamed to `bare_trait_objects`
+//~? WARN lint `bare_trait_object` has been renamed to `bare_trait_objects`
+//~? WARN lint `bare_trait_object` has been renamed to `bare_trait_objects`
diff --git a/tests/ui/lint/lint-renamed-cmdline.stderr b/tests/ui/lint/lint-renamed-cmdline.stderr
index d6bb72f34dc..901e7a642d1 100644
--- a/tests/ui/lint/lint-renamed-cmdline.stderr
+++ b/tests/ui/lint/lint-renamed-cmdline.stderr
@@ -17,13 +17,13 @@ warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: unused variable: `unused`
-  --> $DIR/lint-renamed-cmdline.rs:9:17
+  --> $DIR/lint-renamed-cmdline.rs:7:17
    |
 LL | fn main() { let unused = (); }
    |                 ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
    |
 note: the lint level is defined here
-  --> $DIR/lint-renamed-cmdline.rs:8:8
+  --> $DIR/lint-renamed-cmdline.rs:6:8
    |
 LL | #[deny(unused)]
    |        ^^^^^^
diff --git a/tests/ui/lint/lint-stability2.rs b/tests/ui/lint/lint-stability2.rs
index 254ec8f9bee..056ff5a3e0a 100644
--- a/tests/ui/lint/lint-stability2.rs
+++ b/tests/ui/lint/lint-stability2.rs
@@ -1,5 +1,4 @@
 //@ aux-build:lint_stability.rs
-//@ error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 
@@ -9,5 +8,5 @@ extern crate lint_stability;
 use lint_stability::*;
 
 fn main() {
-    macro_test!();
+    macro_test!(); //~ ERROR use of deprecated function `lint_stability::deprecated`: text
 }
diff --git a/tests/ui/lint/lint-stability2.stderr b/tests/ui/lint/lint-stability2.stderr
index 3df0c428167..fa1bce716fc 100644
--- a/tests/ui/lint/lint-stability2.stderr
+++ b/tests/ui/lint/lint-stability2.stderr
@@ -1,11 +1,11 @@
 error: use of deprecated function `lint_stability::deprecated`: text
-  --> $DIR/lint-stability2.rs:12:5
+  --> $DIR/lint-stability2.rs:11:5
    |
 LL |     macro_test!();
    |     ^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/lint-stability2.rs:4:9
+  --> $DIR/lint-stability2.rs:3:9
    |
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
diff --git a/tests/ui/lint/lint-stability3.rs b/tests/ui/lint/lint-stability3.rs
index 3c5652ae030..1ca346f746a 100644
--- a/tests/ui/lint/lint-stability3.rs
+++ b/tests/ui/lint/lint-stability3.rs
@@ -1,5 +1,4 @@
 //@ aux-build:lint_stability.rs
-//@ error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 #![allow(warnings)]
@@ -11,4 +10,5 @@ use lint_stability::*;
 
 fn main() {
     macro_test_arg_nested!(deprecated_text);
+    //~^ ERROR use of deprecated function `lint_stability::deprecated_text`: text
 }
diff --git a/tests/ui/lint/lint-stability3.stderr b/tests/ui/lint/lint-stability3.stderr
index 3a2af452ce2..85f14c6fc17 100644
--- a/tests/ui/lint/lint-stability3.stderr
+++ b/tests/ui/lint/lint-stability3.stderr
@@ -1,11 +1,11 @@
 error: use of deprecated function `lint_stability::deprecated_text`: text
-  --> $DIR/lint-stability3.rs:13:28
+  --> $DIR/lint-stability3.rs:12:28
    |
 LL |     macro_test_arg_nested!(deprecated_text);
    |                            ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/lint-stability3.rs:4:9
+  --> $DIR/lint-stability3.rs:3:9
    |
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
diff --git a/tests/ui/lint/lint-unknown-lint-cmdline-deny.rs b/tests/ui/lint/lint-unknown-lint-cmdline-deny.rs
index c92c3999ce9..e2f7c73eacf 100644
--- a/tests/ui/lint/lint-unknown-lint-cmdline-deny.rs
+++ b/tests/ui/lint/lint-unknown-lint-cmdline-deny.rs
@@ -1,9 +1,15 @@
 //@ compile-flags:-D unknown-lints -D bogus -D dead_cod
 
-//@ error-pattern:unknown lint: `bogus`
 //@ error-pattern:requested on the command line with `-D bogus`
 //@ error-pattern:requested on the command line with `-D dead_cod`
 //@ error-pattern:requested on the command line with `-D unknown-lints`
 //@ error-pattern:did you mean: `dead_code`
 
 fn main() { }
+
+//~? ERROR unknown lint: `bogus`
+//~? ERROR unknown lint: `dead_cod`
+//~? ERROR unknown lint: `bogus`
+//~? ERROR unknown lint: `dead_cod`
+//~? ERROR unknown lint: `bogus`
+//~? ERROR unknown lint: `dead_cod`
diff --git a/tests/ui/lint/lint-unknown-lint-cmdline.rs b/tests/ui/lint/lint-unknown-lint-cmdline.rs
index 202c617235f..931e945a1a3 100644
--- a/tests/ui/lint/lint-unknown-lint-cmdline.rs
+++ b/tests/ui/lint/lint-unknown-lint-cmdline.rs
@@ -1,11 +1,16 @@
 //@ check-pass
 //@ compile-flags:-D bogus -D dead_cod
 
-//@ error-pattern:unknown lint: `bogus`
 //@ error-pattern:requested on the command line with `-D bogus`
 //@ error-pattern:`#[warn(unknown_lints)]` on by default
-//@ error-pattern:unknown lint: `dead_cod`
 //@ error-pattern:requested on the command line with `-D dead_cod`
 //@ error-pattern:did you mean: `dead_code`
 
 fn main() { }
+
+//~? WARN unknown lint: `bogus`
+//~? WARN unknown lint: `dead_cod`
+//~? WARN unknown lint: `bogus`
+//~? WARN unknown lint: `dead_cod`
+//~? WARN unknown lint: `bogus`
+//~? WARN unknown lint: `dead_cod`
diff --git a/tests/ui/lint/unused_parens_multibyte_recovery.rs b/tests/ui/lint/unused_parens_multibyte_recovery.rs
index 630b25d192a..8f53c7ad262 100644
--- a/tests/ui/lint/unused_parens_multibyte_recovery.rs
+++ b/tests/ui/lint/unused_parens_multibyte_recovery.rs
@@ -1,10 +1,7 @@
 // ignore-tidy-trailing-newlines
-//
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: this file contains an unclosed delimiter
-//
+
 // Verify that unused parens lint does not try to create a span
 // which points in the middle of a multibyte character.
 
+//~v ERROR this file contains an unclosed delimiter
 fn f(){(print!(á
\ No newline at end of file
diff --git a/tests/ui/lint/unused_parens_multibyte_recovery.stderr b/tests/ui/lint/unused_parens_multibyte_recovery.stderr
index ef4089f31f4..770fd6f084e 100644
--- a/tests/ui/lint/unused_parens_multibyte_recovery.stderr
+++ b/tests/ui/lint/unused_parens_multibyte_recovery.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/unused_parens_multibyte_recovery.rs:10:17
+  --> $DIR/unused_parens_multibyte_recovery.rs:7:17
    |
 LL | fn f(){(print!(á
    |       --      - ^
diff --git a/tests/ui/lto/issue-11154.rs b/tests/ui/lto/issue-11154.rs
index 914b0b73e47..7770aeccd6a 100644
--- a/tests/ui/lto/issue-11154.rs
+++ b/tests/ui/lto/issue-11154.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 //@ compile-flags: -C lto -C prefer-dynamic
 
-//@ error-pattern: cannot prefer dynamic linking
-
 fn main() {}
+
+//~? ERROR cannot prefer dynamic linking when performing LTO
diff --git a/tests/ui/lto/lto-duplicate-symbols.rs b/tests/ui/lto/lto-duplicate-symbols.rs
index 27bdde418f8..a62ab2e2217 100644
--- a/tests/ui/lto/lto-duplicate-symbols.rs
+++ b/tests/ui/lto/lto-duplicate-symbols.rs
@@ -1,7 +1,6 @@
 //@ build-fail
 //@ aux-build:lto-duplicate-symbols1.rs
 //@ aux-build:lto-duplicate-symbols2.rs
-//@ error-pattern:Linking globals named 'foo': symbol multiply defined!
 //@ compile-flags: -C lto
 //@ no-prefer-dynamic
 //@ normalize-stderr: "lto-duplicate-symbols2\.lto_duplicate_symbols2\.[0-9a-zA-Z]+-cgu" -> "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu"
@@ -9,3 +8,6 @@ extern crate lto_duplicate_symbols1;
 extern crate lto_duplicate_symbols2;
 
 fn main() {}
+
+//~? WARN Linking globals named 'foo': symbol multiply defined
+//~? ERROR failed to load bitcode of module "lto-duplicate-symbols2.lto_duplicate_symbols2
diff --git a/tests/ui/macros/failed-to-reparse-issue-137874.rs b/tests/ui/macros/failed-to-reparse-issue-137874.rs
new file mode 100644
index 00000000000..3e55ac376fe
--- /dev/null
+++ b/tests/ui/macros/failed-to-reparse-issue-137874.rs
@@ -0,0 +1,12 @@
+// This originally crashed because `Recovery::Forbidden` wasn't being applied
+// when fragments pasted by declarative macros were reparsed.
+
+macro_rules! m {
+    ($p:pat) => {
+        if let $p = 0 {}
+    }
+}
+
+fn main() {
+    m!(0X0); //~ ERROR invalid base prefix for number literal
+}
diff --git a/tests/ui/macros/failed-to-reparse-issue-137874.stderr b/tests/ui/macros/failed-to-reparse-issue-137874.stderr
new file mode 100644
index 00000000000..5bbb8b7f9e2
--- /dev/null
+++ b/tests/ui/macros/failed-to-reparse-issue-137874.stderr
@@ -0,0 +1,10 @@
+error: invalid base prefix for number literal
+  --> $DIR/failed-to-reparse-issue-137874.rs:11:8
+   |
+LL |     m!(0X0);
+   |        ^^^ help: try making the prefix lowercase (notice the capitalization): `0x0`
+   |
+   = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/macros/nonterminal-matching.rs b/tests/ui/macros/nonterminal-matching.rs
index b0a7f3e4650..a03ede20c54 100644
--- a/tests/ui/macros/nonterminal-matching.rs
+++ b/tests/ui/macros/nonterminal-matching.rs
@@ -29,8 +29,8 @@ macro_rules! foo {
     (ident $x:ident) => { bar!(ident $x); };
     (lifetime $x:lifetime) => { bar!(lifetime $x); };
     (tt $x:tt) => { bar!(tt $x); };
-    (expr $x:expr) => { bar!(expr $x); }; //~ ERROR: no rules expected expression `3`
-    (literal $x:literal) => { bar!(literal $x); }; //~ ERROR: no rules expected literal `4`
+    (expr $x:expr) => { bar!(expr $x); }; //~ ERROR: no rules expected `expr` metavariable
+    (literal $x:literal) => { bar!(literal $x); }; //~ ERROR: no rules expected `literal` metavariable
     (path $x:path) => { bar!(path $x); }; //~ ERROR: no rules expected `path` metavariable
     (stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected `stmt` metavariable
 }
diff --git a/tests/ui/macros/nonterminal-matching.stderr b/tests/ui/macros/nonterminal-matching.stderr
index 2d9252fbfc1..d0156141566 100644
--- a/tests/ui/macros/nonterminal-matching.stderr
+++ b/tests/ui/macros/nonterminal-matching.stderr
@@ -23,7 +23,7 @@ LL | complex_nonterminal!(enum E {});
    = help: try using `:tt` instead in the macro definition
    = note: this error originates in the macro `complex_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: no rules expected expression `3`
+error: no rules expected `expr` metavariable
   --> $DIR/nonterminal-matching.rs:32:35
    |
 LL |     (expr $x:expr) => { bar!(expr $x); };
@@ -45,7 +45,7 @@ LL |     (expr 3) => {};
    = help: try using `:tt` instead in the macro definition
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: no rules expected literal `4`
+error: no rules expected `literal` metavariable
   --> $DIR/nonterminal-matching.rs:33:44
    |
 LL |     (literal $x:literal) => { bar!(literal $x); };
diff --git a/tests/ui/macros/not-utf8.rs b/tests/ui/macros/not-utf8.rs
index ad8ac39d230..0993c068860 100644
--- a/tests/ui/macros/not-utf8.rs
+++ b/tests/ui/macros/not-utf8.rs
@@ -1,7 +1,7 @@
-//@ error-pattern: did not contain valid UTF-8
 //@ reference: input.encoding.utf8
 //@ reference: input.encoding.invalid
 
 fn foo() {
     include!("not-utf8.bin");
+    //~^ ERROR couldn't read `$DIR/not-utf8.bin`: stream did not contain valid UTF-8
 }
diff --git a/tests/ui/macros/not-utf8.stderr b/tests/ui/macros/not-utf8.stderr
index d466d5087d4..c310e70935e 100644
--- a/tests/ui/macros/not-utf8.stderr
+++ b/tests/ui/macros/not-utf8.stderr
@@ -1,5 +1,5 @@
 error: couldn't read `$DIR/not-utf8.bin`: stream did not contain valid UTF-8
-  --> $DIR/not-utf8.rs:6:5
+  --> $DIR/not-utf8.rs:5:5
    |
 LL |     include!("not-utf8.bin");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/macros/unreachable-arg.edition_2021.stderr b/tests/ui/macros/unreachable-arg.edition_2021.stderr
index ddaa2b9c1ef..fa776070789 100644
--- a/tests/ui/macros/unreachable-arg.edition_2021.stderr
+++ b/tests/ui/macros/unreachable-arg.edition_2021.stderr
@@ -1,5 +1,5 @@
 error: format argument must be a string literal
-  --> $DIR/unreachable-arg.rs:15:18
+  --> $DIR/unreachable-arg.rs:14:18
    |
 LL |     unreachable!(a);
    |                  ^
diff --git a/tests/ui/macros/unreachable-arg.rs b/tests/ui/macros/unreachable-arg.rs
index 702bd053ab0..d18272c8072 100644
--- a/tests/ui/macros/unreachable-arg.rs
+++ b/tests/ui/macros/unreachable-arg.rs
@@ -6,11 +6,10 @@
 //@ [edition_2015]run-fail
 //@ [edition_2021]check-fail
 //@ [edition_2015]error-pattern:internal error: entered unreachable code: hello
-//@ [edition_2021]error-pattern:format argument must be a string literal
 
 #![allow(non_fmt_panics)]
 
 fn main() {
     let a = "hello";
-    unreachable!(a);
+    unreachable!(a); //[edition_2021]~ ERROR format argument must be a string literal
 }
diff --git a/tests/ui/macros/unreachable-format-args.edition_2015.stderr b/tests/ui/macros/unreachable-format-args.edition_2015.stderr
index 9104848a58b..e2286b72e64 100644
--- a/tests/ui/macros/unreachable-format-args.edition_2015.stderr
+++ b/tests/ui/macros/unreachable-format-args.edition_2015.stderr
@@ -1,5 +1,5 @@
 error: there is no argument named `x`
-  --> $DIR/unreachable-format-args.rs:13:5
+  --> $DIR/unreachable-format-args.rs:12:5
    |
 LL |     unreachable!("x is {x} and y is {y}", y = 0);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/macros/unreachable-format-args.rs b/tests/ui/macros/unreachable-format-args.rs
index 856fc992685..79a851348ff 100644
--- a/tests/ui/macros/unreachable-format-args.rs
+++ b/tests/ui/macros/unreachable-format-args.rs
@@ -5,10 +5,10 @@
 //@ [edition_2021]edition:2021
 //@ [edition_2015]check-fail
 //@ [edition_2021]run-fail
-//@ [edition_2015]error-pattern:there is no argument named `x`
 //@ [edition_2021]error-pattern:internal error: entered unreachable code: x is 5 and y is 0
 
 fn main() {
     let x = 5;
     unreachable!("x is {x} and y is {y}", y = 0);
+    //[edition_2015]~^ ERROR there is no argument named `x`
 }
diff --git a/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.rs b/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.rs
index da56fe03184..94e6900bf40 100644
--- a/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.rs
+++ b/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.rs
@@ -1,7 +1,4 @@
 // check that we don't generate a span that points beyond EOF
 
-//@ error-pattern: unclosed delimiter
-//@ error-pattern: unclosed delimiter
-//@ error-pattern: unclosed delimiter
-
+//~v ERROR this file contains an unclosed delimiter
 fn a(){{{
diff --git a/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.stderr b/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.stderr
index d9748843fd7..9a86c267340 100644
--- a/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.stderr
+++ b/tests/ui/malformed/issue-107423-unused-delim-only-one-no-pair.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-107423-unused-delim-only-one-no-pair.rs:7:11
+  --> $DIR/issue-107423-unused-delim-only-one-no-pair.rs:4:11
    |
 LL | fn a(){{{
    |       ---^
diff --git a/tests/ui/match/issue-112438.rs b/tests/ui/match/issue-112438.rs
deleted file mode 100644
index b2febe29210..00000000000
--- a/tests/ui/match/issue-112438.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-pass
-#![feature(inline_const_pat)]
-#![allow(dead_code)]
-fn foo<const V: usize>() {
-    match 0 {
-        const { 1 << 5 } | _ => {}
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/match/validate-range-endpoints.rs b/tests/ui/match/validate-range-endpoints.rs
index 46d4239886d..678cedf016b 100644
--- a/tests/ui/match/validate-range-endpoints.rs
+++ b/tests/ui/match/validate-range-endpoints.rs
@@ -1,4 +1,3 @@
-#![feature(inline_const_pat)]
 #![allow(overlapping_range_endpoints)]
 
 fn main() {
@@ -17,8 +16,6 @@ fn main() {
         // There isn't really a way to detect these
         1..=TOO_BIG => {}
         //~^ ERROR lower range bound must be less than or equal to upper
-        1..=const { 256 } => {}
-        //~^ ERROR lower range bound must be less than or equal to upper
         _ => {}
     }
 
diff --git a/tests/ui/match/validate-range-endpoints.stderr b/tests/ui/match/validate-range-endpoints.stderr
index 2d0538804a3..6a8a81a1cc6 100644
--- a/tests/ui/match/validate-range-endpoints.stderr
+++ b/tests/ui/match/validate-range-endpoints.stderr
@@ -1,59 +1,53 @@
 error: literal out of range for `u8`
-  --> $DIR/validate-range-endpoints.rs:7:12
+  --> $DIR/validate-range-endpoints.rs:6:12
    |
 LL |         1..257 => {}
    |            ^^^ this value does not fit into the type `u8` whose range is `0..=255`
 
 error: literal out of range for `u8`
-  --> $DIR/validate-range-endpoints.rs:9:13
+  --> $DIR/validate-range-endpoints.rs:8:13
    |
 LL |         1..=256 => {}
    |             ^^^ this value does not fit into the type `u8` whose range is `0..=255`
 
 error[E0030]: lower range bound must be less than or equal to upper
-  --> $DIR/validate-range-endpoints.rs:18:9
+  --> $DIR/validate-range-endpoints.rs:17:9
    |
 LL |         1..=TOO_BIG => {}
    |         ^^^^^^^^^^^ lower bound larger than upper bound
 
-error[E0030]: lower range bound must be less than or equal to upper
-  --> $DIR/validate-range-endpoints.rs:20:9
-   |
-LL |         1..=const { 256 } => {}
-   |         ^^^^^^^^^^^^^^^^^ lower bound larger than upper bound
-
 error: literal out of range for `u64`
-  --> $DIR/validate-range-endpoints.rs:26:32
+  --> $DIR/validate-range-endpoints.rs:23:32
    |
 LL |         10000000000000000000..=99999999999999999999 => {}
    |                                ^^^^^^^^^^^^^^^^^^^^ this value does not fit into the type `u64` whose range is `0..=18446744073709551615`
 
 error: literal out of range for `i8`
-  --> $DIR/validate-range-endpoints.rs:32:12
+  --> $DIR/validate-range-endpoints.rs:29:12
    |
 LL |         0..129 => {}
    |            ^^^ this value does not fit into the type `i8` whose range is `-128..=127`
 
 error: literal out of range for `i8`
-  --> $DIR/validate-range-endpoints.rs:34:13
+  --> $DIR/validate-range-endpoints.rs:31:13
    |
 LL |         0..=128 => {}
    |             ^^^ this value does not fit into the type `i8` whose range is `-128..=127`
 
 error: literal out of range for `i8`
-  --> $DIR/validate-range-endpoints.rs:36:9
+  --> $DIR/validate-range-endpoints.rs:33:9
    |
 LL |         -129..0 => {}
    |         ^^^^ this value does not fit into the type `i8` whose range is `-128..=127`
 
 error: literal out of range for `i8`
-  --> $DIR/validate-range-endpoints.rs:38:9
+  --> $DIR/validate-range-endpoints.rs:35:9
    |
 LL |         -10000..=-20 => {}
    |         ^^^^^^ this value does not fit into the type `i8` whose range is `-128..=127`
 
 error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered
-  --> $DIR/validate-range-endpoints.rs:49:11
+  --> $DIR/validate-range-endpoints.rs:46:11
    |
 LL |     match 0i8 {
    |           ^^^ patterns `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered
@@ -66,7 +60,7 @@ LL +         i8::MIN..=-17_i8 | 1_i8..=i8::MAX => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` not covered
-  --> $DIR/validate-range-endpoints.rs:53:11
+  --> $DIR/validate-range-endpoints.rs:50:11
    |
 LL |     match 0i8 {
    |           ^^^ pattern `i8::MIN..=-17_i8` not covered
@@ -78,7 +72,7 @@ LL ~         -10000.. => {},
 LL +         i8::MIN..=-17_i8 => todo!()
    |
 
-error: aborting due to 11 previous errors
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0004, E0030.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/minus-string.rs b/tests/ui/minus-string.rs
index 8d9b8d8bbf4..b83347b937e 100644
--- a/tests/ui/minus-string.rs
+++ b/tests/ui/minus-string.rs
@@ -1,3 +1 @@
-//@ error-pattern:cannot apply unary operator `-` to type `String`
-
-fn main() { -"foo".to_string(); }
+fn main() { -"foo".to_string(); } //~ ERROR cannot apply unary operator `-` to type `String`
diff --git a/tests/ui/minus-string.stderr b/tests/ui/minus-string.stderr
index cf63ec24416..153965c810e 100644
--- a/tests/ui/minus-string.stderr
+++ b/tests/ui/minus-string.stderr
@@ -1,5 +1,5 @@
 error[E0600]: cannot apply unary operator `-` to type `String`
-  --> $DIR/minus-string.rs:3:13
+  --> $DIR/minus-string.rs:1:13
    |
 LL | fn main() { -"foo".to_string(); }
    |             ^^^^^^^^^^^^^^^^^^ cannot apply unary operator `-`
diff --git a/tests/ui/mir/enable_passes_validation.rs b/tests/ui/mir/enable_passes_validation.rs
index 405ada77183..b97ddfba37f 100644
--- a/tests/ui/mir/enable_passes_validation.rs
+++ b/tests/ui/mir/enable_passes_validation.rs
@@ -1,24 +1,25 @@
 //@ revisions: empty unprefixed all_unknown all_known mixed
 
 //@[empty] compile-flags: -Zmir-enable-passes=
-//@[empty] error-pattern error: incorrect value `` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
 
 //@[unprefixed] compile-flags: -Zmir-enable-passes=CheckAlignment
-//@[unprefixed] error-pattern error: incorrect value `CheckAlignment` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
 
 //@[all_unknown] check-pass
 //@[all_unknown] compile-flags: -Zmir-enable-passes=+ThisPass,-DoesNotExist
-//@[all_unknown] error-pattern: warning: MIR pass `ThisPass` is unknown and will be ignored
-//@[all_unknown] error-pattern: warning: MIR pass `DoesNotExist` is unknown and will be ignored
 
 //@[all_known] check-pass
 //@[all_known] compile-flags: -Zmir-enable-passes=+CheckAlignment,+LowerIntrinsics
 
 //@[mixed] check-pass
 //@[mixed] compile-flags: -Zmir-enable-passes=+ThisPassDoesNotExist,+CheckAlignment
-//@[mixed] error-pattern: warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
 
 fn main() {}
 
 //[empty]~? ERROR incorrect value `` for unstable option `mir-enable-passes`
 //[unprefixed]~? ERROR incorrect value `CheckAlignment` for unstable option `mir-enable-passes`
+//[mixed]~? WARN MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
+//[mixed]~? WARN MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
+//[all_unknown]~? MIR pass `ThisPass` is unknown and will be ignored
+//[all_unknown]~? MIR pass `DoesNotExist` is unknown and will be ignored
+//[all_unknown]~? MIR pass `ThisPass` is unknown and will be ignored
+//[all_unknown]~? MIR pass `DoesNotExist` is unknown and will be ignored
diff --git a/tests/ui/mir/issue-75053.rs b/tests/ui/mir/issue-75053.rs
index 9b247fa5434..4bc481b82e5 100644
--- a/tests/ui/mir/issue-75053.rs
+++ b/tests/ui/mir/issue-75053.rs
@@ -1,6 +1,7 @@
+//@ check-pass
 //@ compile-flags: -Z mir-opt-level=3
 
-#![feature(type_alias_impl_trait, rustc_attrs)]
+#![feature(type_alias_impl_trait)]
 
 use std::marker::PhantomData;
 
@@ -43,8 +44,6 @@ impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> {
     }
 }
 
-#[rustc_error]
 fn main() {
-    //~^ ERROR
     let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
 }
diff --git a/tests/ui/mir/issue-75053.stderr b/tests/ui/mir/issue-75053.stderr
deleted file mode 100644
index 91032bc3797..00000000000
--- a/tests/ui/mir/issue-75053.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-75053.rs:47:1
-   |
-LL | fn main() {
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/mir/lint/assignment-overlap.rs b/tests/ui/mir/lint/assignment-overlap.rs
index 6396cccd4e8..950279b1555 100644
--- a/tests/ui/mir/lint/assignment-overlap.rs
+++ b/tests/ui/mir/lint/assignment-overlap.rs
@@ -12,7 +12,7 @@ pub fn main() {
     mir! {
         let a: [u8; 1024];
         {
-            a = a;
+            a = a; //~ ERROR broken MIR
             Return()
         }
     }
diff --git a/tests/ui/mir/lint/call-overlap.rs b/tests/ui/mir/lint/call-overlap.rs
index def78ea1e3b..3c42e04e3ec 100644
--- a/tests/ui/mir/lint/call-overlap.rs
+++ b/tests/ui/mir/lint/call-overlap.rs
@@ -12,7 +12,7 @@ pub fn main() {
     mir! {
         let a: [u8; 1024];
         {
-            Call(a = f(Move(a)), ReturnTo(bb1), UnwindUnreachable())
+            Call(a = f(Move(a)), ReturnTo(bb1), UnwindUnreachable()) //~ ERROR broken MIR
         }
         bb1 = {
             Return()
diff --git a/tests/ui/mir/lint/no-storage.rs b/tests/ui/mir/lint/no-storage.rs
index a6af8646f6e..68c1a2d2aab 100644
--- a/tests/ui/mir/lint/no-storage.rs
+++ b/tests/ui/mir/lint/no-storage.rs
@@ -21,7 +21,7 @@ pub fn f(a: bool) {
             Goto(bb3)
         }
         bb3 = {
-            b = ();
+            b = (); //~ ERROR broken MIR
             RET = b;
             StorageDead(b);
             Return()
diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs
index 3e0cc4ee061..19d046b619c 100644
--- a/tests/ui/mir/lint/storage-live.rs
+++ b/tests/ui/mir/lint/storage-live.rs
@@ -20,7 +20,7 @@ fn multiple_storage() {
         let a: usize;
         {
             StorageLive(a);
-            StorageLive(a);
+            StorageLive(a); //~ ERROR broken MIR
             Return()
         }
     }
diff --git a/tests/ui/mir/lint/storage-return.rs b/tests/ui/mir/lint/storage-return.rs
index d51aee9518f..3bbd0045d9d 100644
--- a/tests/ui/mir/lint/storage-return.rs
+++ b/tests/ui/mir/lint/storage-return.rs
@@ -13,7 +13,7 @@ fn main() {
         {
             StorageLive(a);
             RET = a;
-            Return()
+            Return() //~ ERROR broken MIR
         }
     }
 }
diff --git a/tests/ui/mir/validate/noncleanup-cleanup.rs b/tests/ui/mir/validate/noncleanup-cleanup.rs
index b46bb46952b..3010a3804ce 100644
--- a/tests/ui/mir/validate/noncleanup-cleanup.rs
+++ b/tests/ui/mir/validate/noncleanup-cleanup.rs
@@ -2,16 +2,16 @@
 //
 //@ failure-status: 101
 //@ dont-check-compiler-stderr
-//@ error-pattern: cleanuppad mismatch
+
 #![feature(custom_mir, core_intrinsics)]
 extern crate core;
 use core::intrinsics::mir::*;
 
 #[custom_mir(dialect = "built")]
-pub fn main() {
+pub fn main() { //~ WARN function cannot return without recursing
     mir! {
         {
-            Call(RET = main(), ReturnTo(block), UnwindCleanup(block))
+            Call(RET = main(), ReturnTo(block), UnwindCleanup(block)) //~ ERROR cleanuppad mismatch
         }
         block = {
             Return()
diff --git a/tests/ui/mir/validate/noncleanup-resume.rs b/tests/ui/mir/validate/noncleanup-resume.rs
index b2a0e92e068..a80e99e2967 100644
--- a/tests/ui/mir/validate/noncleanup-resume.rs
+++ b/tests/ui/mir/validate/noncleanup-resume.rs
@@ -2,7 +2,7 @@
 //
 //@ failure-status: 101
 //@ dont-check-compiler-stderr
-//@ error-pattern: resume on non-cleanup block
+
 #![feature(custom_mir, core_intrinsics)]
 extern crate core;
 use core::intrinsics::mir::*;
@@ -11,7 +11,7 @@ use core::intrinsics::mir::*;
 pub fn main() {
     mir! {
         {
-            UnwindResume()
+            UnwindResume() //~ ERROR resume on non-cleanup block
         }
     }
 }
diff --git a/tests/ui/mir/validate/noncleanup-terminate.rs b/tests/ui/mir/validate/noncleanup-terminate.rs
index 24cf75e7d8e..859c5e71c0e 100644
--- a/tests/ui/mir/validate/noncleanup-terminate.rs
+++ b/tests/ui/mir/validate/noncleanup-terminate.rs
@@ -2,7 +2,7 @@
 //
 //@ failure-status: 101
 //@ dont-check-compiler-stderr
-//@ error-pattern: terminate on non-cleanup block
+
 #![feature(custom_mir, core_intrinsics)]
 extern crate core;
 use core::intrinsics::mir::*;
@@ -11,7 +11,7 @@ use core::intrinsics::mir::*;
 pub fn main() {
     mir! {
         {
-            UnwindTerminate(ReasonAbi)
+            UnwindTerminate(ReasonAbi) //~ ERROR terminate on non-cleanup block
         }
     }
 }
diff --git a/tests/ui/missing/missing-main.rs b/tests/ui/missing/missing-main.rs
index 3cafca09afb..2b8995fb8ff 100644
--- a/tests/ui/missing/missing-main.rs
+++ b/tests/ui/missing/missing-main.rs
@@ -1,2 +1 @@
-//@ error-pattern: `main` function not found
-fn mian() { }
+fn mian() { } //~ ERROR `main` function not found in crate `missing_main`
diff --git a/tests/ui/missing/missing-main.stderr b/tests/ui/missing/missing-main.stderr
index 2139981eac0..51a299d6a85 100644
--- a/tests/ui/missing/missing-main.stderr
+++ b/tests/ui/missing/missing-main.stderr
@@ -1,5 +1,5 @@
 error[E0601]: `main` function not found in crate `missing_main`
-  --> $DIR/missing-main.rs:2:14
+  --> $DIR/missing-main.rs:1:14
    |
 LL | fn mian() { }
    |              ^ consider adding a `main` function to `$DIR/missing-main.rs`
diff --git a/tests/ui/missing/missing-return.rs b/tests/ui/missing/missing-return.rs
index defd8a3bb78..5d9839a969c 100644
--- a/tests/ui/missing/missing-return.rs
+++ b/tests/ui/missing/missing-return.rs
@@ -1,5 +1,5 @@
 //@ error-pattern: return
 
-fn f() -> isize { }
+fn f() -> isize { } //~ ERROR mismatched types
 
 fn main() { f(); }
diff --git a/tests/ui/nested-ty-params.rs b/tests/ui/nested-ty-params.rs
index b7cedf97c91..866e6230f9e 100644
--- a/tests/ui/nested-ty-params.rs
+++ b/tests/ui/nested-ty-params.rs
@@ -1,6 +1,8 @@
 //@ error-pattern:can't use generic parameters from outer item
 fn hd<U>(v: Vec<U> ) -> U {
     fn hd1(w: [U]) -> U { return w[0]; }
+    //~^ ERROR can't use generic parameters from outer item
+    //~| ERROR can't use generic parameters from outer item
 
     return hd1(v);
 }
diff --git a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
index 87bbd50a15c..6fd41a761e9 100644
--- a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -4,14 +4,14 @@ error[E0700]: hidden type for `Opaque(DefId(0:11 ~ impl_trait_captures[aeb9]::fo
 LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
    |                  --     ------------ opaque type defined here
    |                  |
-   |                  hidden type `&ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here
+   |                  hidden type `&ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), LateNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here
 LL |     x
    |     ^
    |
-help: add a `use<...>` bound to explicitly capture `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_))`
+help: add a `use<...>` bound to explicitly capture `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), LateNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_))`
    |
-LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + use<'a, ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)), T> {
-   |                                      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + use<'a, ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), LateNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)), T> {
+   |                                      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/no-capture-arc.rs b/tests/ui/no-capture-arc.rs
index aafb170c7e1..9c957a4e01b 100644
--- a/tests/ui/no-capture-arc.rs
+++ b/tests/ui/no-capture-arc.rs
@@ -1,5 +1,3 @@
-//@ error-pattern: borrow of moved value
-
 use std::sync::Arc;
 use std::thread;
 
@@ -11,7 +9,7 @@ fn main() {
         assert_eq!((*arc_v)[3], 4);
     });
 
-    assert_eq!((*arc_v)[2], 3);
+    assert_eq!((*arc_v)[2], 3); //~ ERROR borrow of moved value: `arc_v`
 
     println!("{:?}", *arc_v);
 }
diff --git a/tests/ui/no-capture-arc.stderr b/tests/ui/no-capture-arc.stderr
index 4a51ddb67a3..9c1f5c65066 100644
--- a/tests/ui/no-capture-arc.stderr
+++ b/tests/ui/no-capture-arc.stderr
@@ -1,5 +1,5 @@
 error[E0382]: borrow of moved value: `arc_v`
-  --> $DIR/no-capture-arc.rs:14:18
+  --> $DIR/no-capture-arc.rs:12:18
    |
 LL |     let arc_v = Arc::new(v);
    |         ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
diff --git a/tests/ui/no_std/no-std-no-start-binary.rs b/tests/ui/no_std/no-std-no-start-binary.rs
index 5c8a0e6c0b8..df68b99346a 100644
--- a/tests/ui/no_std/no-std-no-start-binary.rs
+++ b/tests/ui/no_std/no-std-no-start-binary.rs
@@ -11,3 +11,5 @@ fn handler(_info: &core::panic::PanicInfo<'_>) -> ! {
 }
 
 fn main() {}
+
+//~? ERROR using `fn main` requires the standard library
diff --git a/tests/ui/no_std/no-std-unwind-binary.rs b/tests/ui/no_std/no-std-unwind-binary.rs
index 74c80d75c3e..cb1dc4427ae 100644
--- a/tests/ui/no_std/no-std-unwind-binary.rs
+++ b/tests/ui/no_std/no-std-unwind-binary.rs
@@ -1,4 +1,3 @@
-//@ error-pattern:unwinding panics are not supported without std
 //@ needs-unwind
 //@ compile-flags: -Cpanic=unwind
 
@@ -13,3 +12,5 @@ fn handler(_info: &core::panic::PanicInfo<'_>) -> ! {
 }
 
 fn main() {}
+
+//~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/occurs-check-2.rs b/tests/ui/occurs-check-2.rs
index 1ec460a8735..9289a8e870a 100644
--- a/tests/ui/occurs-check-2.rs
+++ b/tests/ui/occurs-check-2.rs
@@ -4,6 +4,6 @@ fn main() {
     let g;
 
     g = f;
-    f = Box::new(g);
     //~^ ERROR overflow assigning `Box<_>` to `_`
+    f = Box::new(g);
 }
diff --git a/tests/ui/occurs-check-2.stderr b/tests/ui/occurs-check-2.stderr
index 54307a6c547..5f296967f30 100644
--- a/tests/ui/occurs-check-2.stderr
+++ b/tests/ui/occurs-check-2.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Box<_>` to `_`
-  --> $DIR/occurs-check-2.rs:7:9
+  --> $DIR/occurs-check-2.rs:6:9
    |
-LL |     f = Box::new(g);
-   |         ^^^^^^^^^^^
+LL |     g = f;
+   |         ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/occurs-check-3.stderr b/tests/ui/occurs-check-3.stderr
index 77b67ec1a62..eb05c94957c 100644
--- a/tests/ui/occurs-check-3.stderr
+++ b/tests/ui/occurs-check-3.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Clam<_>` to `_`
-  --> $DIR/occurs-check-3.rs:6:9
+  --> $DIR/occurs-check-3.rs:6:17
    |
 LL |     c = Clam::A(c);
-   |         ^^^^^^^^^^
+   |                 ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/occurs-check.stderr b/tests/ui/occurs-check.stderr
index 30468d68cbd..ea7c541abc1 100644
--- a/tests/ui/occurs-check.stderr
+++ b/tests/ui/occurs-check.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Box<_>` to `_`
-  --> $DIR/occurs-check.rs:3:9
+  --> $DIR/occurs-check.rs:3:18
    |
 LL |     f = Box::new(f);
-   |         ^^^^^^^^^^^
+   |                  ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr
index 0a9ebe3f088..e011826bc8f 100644
--- a/tests/ui/on-unimplemented/slice-index.stderr
+++ b/tests/ui/on-unimplemented/slice-index.stderr
@@ -5,8 +5,9 @@ LL |     x[1i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[i32]` to implement `Index<i32>`
 
 error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
@@ -17,6 +18,7 @@ LL |     x[..1i32];
    |
    = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>`
    = help: the following other types implement trait `SliceIndex<T>`:
+             `RangeTo<usize>` implements `SliceIndex<ByteStr>`
              `RangeTo<usize>` implements `SliceIndex<[T]>`
              `RangeTo<usize>` implements `SliceIndex<str>`
    = note: required for `[i32]` to implement `Index<RangeTo<i32>>`
diff --git a/tests/ui/packed/packed-struct-generic-transmute.rs b/tests/ui/packed/packed-struct-generic-transmute.rs
index ed655a1d483..17e72bebc7d 100644
--- a/tests/ui/packed/packed-struct-generic-transmute.rs
+++ b/tests/ui/packed/packed-struct-generic-transmute.rs
@@ -22,6 +22,7 @@ fn main() {
     let foo = Foo { bar: [1u8, 2, 3, 4, 5], baz: 10i32 };
     unsafe {
         let oof: Oof<[u8; 5], i32> = mem::transmute(foo);
+        //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
         println!("{:?} {:?}", &oof.rab[..], oof.zab);
     }
 }
diff --git a/tests/ui/packed/packed-struct-transmute.rs b/tests/ui/packed/packed-struct-transmute.rs
index 98feeea8871..5ad6524ff81 100644
--- a/tests/ui/packed/packed-struct-transmute.rs
+++ b/tests/ui/packed/packed-struct-transmute.rs
@@ -24,6 +24,7 @@ fn main() {
     let foo = Foo { bar: 1, baz: 10 };
     unsafe {
         let oof: Oof = mem::transmute(foo);
+        //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
         println!("{:?}", oof);
     }
 }
diff --git a/tests/ui/panic-handler/panic-handler-missing.rs b/tests/ui/panic-handler/panic-handler-missing.rs
index 09fbd9a69cf..ab617f93a99 100644
--- a/tests/ui/panic-handler/panic-handler-missing.rs
+++ b/tests/ui/panic-handler/panic-handler-missing.rs
@@ -1,5 +1,4 @@
 //@ dont-check-compiler-stderr
-//@ error-pattern: `#[panic_handler]` function required, but not found
 
 #![feature(lang_items)]
 #![no_main]
@@ -7,3 +6,5 @@
 
 #[lang = "eh_personality"]
 fn eh() {}
+
+//~? ERROR `#[panic_handler]` function required, but not found
diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs
index 4eb05b5365f..f6a4b60461c 100644
--- a/tests/ui/panic-handler/panic-handler-std.rs
+++ b/tests/ui/panic-handler/panic-handler-std.rs
@@ -1,12 +1,11 @@
 //@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib"
-//@ error-pattern: found duplicate lang item `panic_impl`
 
 extern crate core;
 
 use core::panic::PanicInfo;
 
 #[panic_handler]
-fn panic(info: PanicInfo) -> ! {
+fn panic(info: PanicInfo) -> ! { //~ ERROR found duplicate lang item `panic_impl`
     loop {}
 }
 
diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr
index caae16118ef..48c216ce27e 100644
--- a/tests/ui/panic-handler/panic-handler-std.stderr
+++ b/tests/ui/panic-handler/panic-handler-std.stderr
@@ -1,5 +1,5 @@
 error[E0152]: found duplicate lang item `panic_impl`
-  --> $DIR/panic-handler-std.rs:9:1
+  --> $DIR/panic-handler-std.rs:8:1
    |
 LL | / fn panic(info: PanicInfo) -> ! {
 LL | |     loop {}
diff --git a/tests/ui/panic-handler/weak-lang-item.rs b/tests/ui/panic-handler/weak-lang-item.rs
index 605e1bdd94b..cc5ccb75104 100644
--- a/tests/ui/panic-handler/weak-lang-item.rs
+++ b/tests/ui/panic-handler/weak-lang-item.rs
@@ -1,12 +1,13 @@
 //@ aux-build:weak-lang-items.rs
-//@ error-pattern: `#[panic_handler]` function required, but not found
-//@ error-pattern: unwinding panics are not supported without std
 //@ needs-unwind since it affects the error output
 //@ ignore-emscripten missing eh_catch_typeinfo lang item
 
 #![no_std]
 
-extern crate core;
+extern crate core; //~ ERROR the name `core` is defined multiple times
 extern crate weak_lang_items;
 
 fn main() {}
+
+//~? ERROR `#[panic_handler]` function required, but not found
+//~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/panic-handler/weak-lang-item.stderr b/tests/ui/panic-handler/weak-lang-item.stderr
index 5dcb37df689..5acd3e31870 100644
--- a/tests/ui/panic-handler/weak-lang-item.stderr
+++ b/tests/ui/panic-handler/weak-lang-item.stderr
@@ -1,5 +1,5 @@
 error[E0259]: the name `core` is defined multiple times
-  --> $DIR/weak-lang-item.rs:9:1
+  --> $DIR/weak-lang-item.rs:7:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ `core` reimported here
diff --git a/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs b/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs
index 2939835b0f4..8b782413f6a 100644
--- a/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs
+++ b/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs
@@ -4,7 +4,6 @@
 //@ ignore-musl - no dylibs here
 //@ ignore-emscripten
 //@ ignore-sgx no dynamic lib support
-//@ error-pattern:`panic_unwind` is not compiled with this crate's panic strategy
 
 // This is a test where the local crate, compiled with `panic=abort`, links to
 // the standard library **dynamically** which is already linked against
@@ -16,3 +15,5 @@
 
 fn main() {
 }
+
+//~? ERROR the linked panic runtime `panic_unwind` is not compiled with this crate's panic strategy `abort`
diff --git a/tests/ui/panic-runtime/bad-panic-flag1.rs b/tests/ui/panic-runtime/bad-panic-flag1.rs
index 82b7c2f723b..117935847cb 100644
--- a/tests/ui/panic-runtime/bad-panic-flag1.rs
+++ b/tests/ui/panic-runtime/bad-panic-flag1.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-C panic=foo
-//@ error-pattern:either `unwind` or `abort` was expected
 
 fn main() {}
+
+//~? ERROR incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected
diff --git a/tests/ui/panic-runtime/bad-panic-flag2.rs b/tests/ui/panic-runtime/bad-panic-flag2.rs
index 3875325deae..b5d0442a033 100644
--- a/tests/ui/panic-runtime/bad-panic-flag2.rs
+++ b/tests/ui/panic-runtime/bad-panic-flag2.rs
@@ -1,4 +1,5 @@
 //@ compile-flags:-C panic
-//@ error-pattern:requires either `unwind` or `abort`
 
 fn main() {}
+
+//~? ERROR codegen option `panic` requires either `unwind` or `abort`
diff --git a/tests/ui/panic-runtime/need-abort-got-unwind.rs b/tests/ui/panic-runtime/need-abort-got-unwind.rs
index 74b7edd968f..afd08426395 100644
--- a/tests/ui/panic-runtime/need-abort-got-unwind.rs
+++ b/tests/ui/panic-runtime/need-abort-got-unwind.rs
@@ -1,8 +1,9 @@
 //@ build-fail
 //@ needs-unwind
-//@ error-pattern:is incompatible with this crate's strategy of `unwind`
 //@ aux-build:needs-abort.rs
 
 extern crate needs_abort;
 
 fn main() {}
+
+//~? ERROR the crate `needs_abort` requires panic strategy `abort` which is incompatible with this crate's strategy of `unwind`
diff --git a/tests/ui/panic-runtime/need-unwind-got-abort.rs b/tests/ui/panic-runtime/need-unwind-got-abort.rs
index 6bc41509b6b..bc65e9ab3d9 100644
--- a/tests/ui/panic-runtime/need-unwind-got-abort.rs
+++ b/tests/ui/panic-runtime/need-unwind-got-abort.rs
@@ -1,5 +1,4 @@
 //@ build-fail
-//@ error-pattern:is incompatible with this crate's strategy of `abort`
 //@ aux-build:needs-unwind.rs
 //@ compile-flags:-C panic=abort
 //@ no-prefer-dynamic
@@ -7,3 +6,5 @@
 extern crate needs_unwind;
 
 fn main() {}
+
+//~? ERROR the crate `needs_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/runtime-depend-on-needs-runtime.rs b/tests/ui/panic-runtime/runtime-depend-on-needs-runtime.rs
index d0a82bd8507..eb00c071702 100644
--- a/tests/ui/panic-runtime/runtime-depend-on-needs-runtime.rs
+++ b/tests/ui/panic-runtime/runtime-depend-on-needs-runtime.rs
@@ -1,8 +1,9 @@
 //@ dont-check-compiler-stderr
 //@ aux-build:needs-panic-runtime.rs
 //@ aux-build:depends.rs
-//@ error-pattern:cannot depend on a crate that needs a panic runtime
 
 extern crate depends;
 
 fn main() {}
+
+//~? ERROR the crate `depends` cannot depend on a crate that needs a panic runtime, but it depends on `needs_panic_runtime`
diff --git a/tests/ui/panic-runtime/transitive-link-a-bunch.rs b/tests/ui/panic-runtime/transitive-link-a-bunch.rs
index 15557d35bc5..2a0b9e3fa63 100644
--- a/tests/ui/panic-runtime/transitive-link-a-bunch.rs
+++ b/tests/ui/panic-runtime/transitive-link-a-bunch.rs
@@ -5,7 +5,6 @@
 //@ aux-build:wants-panic-runtime-unwind.rs
 //@ aux-build:wants-panic-runtime-abort.rs
 //@ aux-build:panic-runtime-lang-items.rs
-//@ error-pattern: is not compiled with this crate's panic strategy `unwind`
 
 #![no_std]
 #![no_main]
@@ -13,3 +12,7 @@
 extern crate wants_panic_runtime_unwind;
 extern crate wants_panic_runtime_abort;
 extern crate panic_runtime_lang_items;
+
+//~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_abort
+//~? ERROR the linked panic runtime `panic_runtime_abort` is not compiled with this crate's panic strategy `unwind`
+//~? ERROR the crate `wants_panic_runtime_abort` requires panic strategy `abort` which is incompatible with this crate's strategy of `unwind`
diff --git a/tests/ui/panic-runtime/two-panic-runtimes.rs b/tests/ui/panic-runtime/two-panic-runtimes.rs
index 3608dca2124..15c08cbe30d 100644
--- a/tests/ui/panic-runtime/two-panic-runtimes.rs
+++ b/tests/ui/panic-runtime/two-panic-runtimes.rs
@@ -1,6 +1,8 @@
+// ignore-tidy-linelength
 //@ build-fail
+//@ compile-flags: --error-format=human
+//@ error-pattern: cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
 //@ dont-check-compiler-stderr
-//@ error-pattern:cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
 //@ aux-build:panic-runtime-unwind.rs
 //@ aux-build:panic-runtime-unwind2.rs
 //@ aux-build:panic-runtime-lang-items.rs
@@ -13,3 +15,8 @@ extern crate panic_runtime_unwind2;
 extern crate panic_runtime_lang_items;
 
 fn main() {}
+
+// FIXME: The second and third errors are target-dependent.
+//FIXME~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
+//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind2` is not compiled with this crate's panic strategy `abort`
+//FIXME~? ERROR the crate `panic_runtime_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/unwind-tables-target-required.rs b/tests/ui/panic-runtime/unwind-tables-target-required.rs
index 5c6ec19c16d..ff8df284f6b 100644
--- a/tests/ui/panic-runtime/unwind-tables-target-required.rs
+++ b/tests/ui/panic-runtime/unwind-tables-target-required.rs
@@ -5,7 +5,8 @@
 //@ compile-flags: -C force-unwind-tables=no
 //
 //@ dont-check-compiler-stderr
-//@ error-pattern: target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`
 
 pub fn main() {
 }
+
+//~? ERROR target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`
diff --git a/tests/ui/panic-runtime/want-abort-got-unwind.rs b/tests/ui/panic-runtime/want-abort-got-unwind.rs
index ad9fa52f3d4..ed61c2613df 100644
--- a/tests/ui/panic-runtime/want-abort-got-unwind.rs
+++ b/tests/ui/panic-runtime/want-abort-got-unwind.rs
@@ -1,9 +1,16 @@
+// ignore-tidy-linelength
 //@ build-fail
+//@ compile-flags: --error-format=human
+//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
 //@ dont-check-compiler-stderr
-//@ error-pattern:is not compiled with this crate's panic strategy `abort`
 //@ aux-build:panic-runtime-unwind.rs
 //@ compile-flags:-C panic=abort
 
 extern crate panic_runtime_unwind;
 
 fn main() {}
+
+// FIXME: The first and third errors are target-dependent.
+//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
+//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
+//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/want-abort-got-unwind2.rs b/tests/ui/panic-runtime/want-abort-got-unwind2.rs
index d63161db55c..504fd779e09 100644
--- a/tests/ui/panic-runtime/want-abort-got-unwind2.rs
+++ b/tests/ui/panic-runtime/want-abort-got-unwind2.rs
@@ -1,6 +1,8 @@
+// ignore-tidy-linelength
 //@ build-fail
+//@ compile-flags: --error-format=human
+//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
 //@ dont-check-compiler-stderr
-//@ error-pattern:is not compiled with this crate's panic strategy `abort`
 //@ aux-build:panic-runtime-unwind.rs
 //@ aux-build:wants-panic-runtime-unwind.rs
 //@ compile-flags:-C panic=abort
@@ -8,3 +10,8 @@
 extern crate wants_panic_runtime_unwind;
 
 fn main() {}
+
+// FIXME: The first and third errors are target-dependent.
+//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
+//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
+//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/want-unwind-got-abort.rs b/tests/ui/panic-runtime/want-unwind-got-abort.rs
index 93342a09182..497d1eafda5 100644
--- a/tests/ui/panic-runtime/want-unwind-got-abort.rs
+++ b/tests/ui/panic-runtime/want-unwind-got-abort.rs
@@ -1,6 +1,5 @@
 //@ build-fail
 //@ needs-unwind
-//@ error-pattern:is not compiled with this crate's panic strategy `unwind`
 //@ aux-build:panic-runtime-abort.rs
 //@ aux-build:panic-runtime-lang-items.rs
 
@@ -9,3 +8,5 @@
 
 extern crate panic_runtime_abort;
 extern crate panic_runtime_lang_items;
+
+//~? ERROR the linked panic runtime `panic_runtime_abort` is not compiled with this crate's panic strategy `unwind`
diff --git a/tests/ui/panic-runtime/want-unwind-got-abort2.rs b/tests/ui/panic-runtime/want-unwind-got-abort2.rs
index ee3f221d09c..2609545336c 100644
--- a/tests/ui/panic-runtime/want-unwind-got-abort2.rs
+++ b/tests/ui/panic-runtime/want-unwind-got-abort2.rs
@@ -1,6 +1,5 @@
 //@ build-fail
 //@ needs-unwind
-//@ error-pattern:is incompatible with this crate's strategy of `unwind`
 //@ aux-build:panic-runtime-abort.rs
 //@ aux-build:wants-panic-runtime-abort.rs
 //@ aux-build:panic-runtime-lang-items.rs
@@ -10,3 +9,6 @@
 
 extern crate wants_panic_runtime_abort;
 extern crate panic_runtime_lang_items;
+
+//~? ERROR the linked panic runtime `panic_runtime_abort` is not compiled with this crate's panic strategy `unwind`
+//~? ERROR the crate `wants_panic_runtime_abort` requires panic strategy `abort` which is incompatible with this crate's strategy of `unwind`
diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs
index 9933f548758..cf8b0cea849 100644
--- a/tests/ui/panics/default-backtrace-ice.rs
+++ b/tests/ui/panics/default-backtrace-ice.rs
@@ -20,4 +20,4 @@
 // Ignored on msvc because the `__rust_{begin,end}_short_backtrace` symbols
 // aren't reliable.
 
-fn main() { missing_ident; }
+fn main() { missing_ident; } //~ ERROR cannot find value `missing_ident` in this scope
diff --git a/tests/ui/parser/attribute/attr-dangling-in-fn.rs b/tests/ui/parser/attribute/attr-dangling-in-fn.rs
index d59f90aed5d..b1436b8d89d 100644
--- a/tests/ui/parser/attribute/attr-dangling-in-fn.rs
+++ b/tests/ui/parser/attribute/attr-dangling-in-fn.rs
@@ -1,7 +1,5 @@
-//@ error-pattern:expected statement
-
 fn f() {
-  #[foo = "bar"]
+  #[foo = "bar"] //~ ERROR expected statement after outer attribute
 }
 
 fn main() {
diff --git a/tests/ui/parser/attribute/attr-dangling-in-fn.stderr b/tests/ui/parser/attribute/attr-dangling-in-fn.stderr
index c7b948ea8f7..3e9413f5357 100644
--- a/tests/ui/parser/attribute/attr-dangling-in-fn.stderr
+++ b/tests/ui/parser/attribute/attr-dangling-in-fn.stderr
@@ -1,5 +1,5 @@
 error: expected statement after outer attribute
-  --> $DIR/attr-dangling-in-fn.rs:4:3
+  --> $DIR/attr-dangling-in-fn.rs:2:3
    |
 LL |   #[foo = "bar"]
    |   ^^^^^^^^^^^^^^
diff --git a/tests/ui/parser/attribute/attr-dangling-in-mod.rs b/tests/ui/parser/attribute/attr-dangling-in-mod.rs
index 001ac1135f6..17bc7e547d9 100644
--- a/tests/ui/parser/attribute/attr-dangling-in-mod.rs
+++ b/tests/ui/parser/attribute/attr-dangling-in-mod.rs
@@ -1,6 +1,4 @@
-//@ error-pattern:expected item
-
 fn main() {
 }
 
-#[foo = "bar"]
+#[foo = "bar"] //~ ERROR expected item after attributes
diff --git a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr
index 882400c1d6f..22cc092109d 100644
--- a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr
+++ b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr
@@ -1,5 +1,5 @@
 error: expected item after attributes
-  --> $DIR/attr-dangling-in-mod.rs:6:1
+  --> $DIR/attr-dangling-in-mod.rs:4:1
    |
 LL | #[foo = "bar"]
    | ^^^^^^^^^^^^^^
diff --git a/tests/ui/parser/circular_modules_main.rs b/tests/ui/parser/circular_modules_main.rs
index d5cdff34a26..c130c6792b8 100644
--- a/tests/ui/parser/circular_modules_main.rs
+++ b/tests/ui/parser/circular_modules_main.rs
@@ -1,5 +1,3 @@
-//@ error-pattern: circular modules
-
 #[path = "circular_modules_hello.rs"]
 mod circular_modules_hello;
 
@@ -10,3 +8,5 @@ pub fn hi_str() -> String {
 fn main() {
     circular_modules_hello::say_hello();
 }
+
+//~? ERROR circular modules: $DIR/circular_modules_main.rs -> $DIR/circular_modules_hello.rs -> $DIR/circular_modules_main.rs
diff --git a/tests/ui/parser/class-implements-bad-trait.rs b/tests/ui/parser/class-implements-bad-trait.rs
index 152fe09b51c..e30c1bc3a7f 100644
--- a/tests/ui/parser/class-implements-bad-trait.rs
+++ b/tests/ui/parser/class-implements-bad-trait.rs
@@ -1,5 +1,4 @@
-//@ error-pattern:nonexistent
-class cat : nonexistent {
+class cat : nonexistent { //~ ERROR expected one of `!` or `::`, found `cat`
   let meows: usize;
   new(in_x : usize) { self.meows = in_x; }
 }
diff --git a/tests/ui/parser/class-implements-bad-trait.stderr b/tests/ui/parser/class-implements-bad-trait.stderr
index 5290e3594d5..5cdb85a8cff 100644
--- a/tests/ui/parser/class-implements-bad-trait.stderr
+++ b/tests/ui/parser/class-implements-bad-trait.stderr
@@ -1,5 +1,5 @@
 error: expected one of `!` or `::`, found `cat`
-  --> $DIR/class-implements-bad-trait.rs:2:7
+  --> $DIR/class-implements-bad-trait.rs:1:7
    |
 LL | class cat : nonexistent {
    |       ^^^ expected one of `!` or `::`
diff --git a/tests/ui/parser/closure-return-syntax.rs b/tests/ui/parser/closure-return-syntax.rs
index c6a08abeff4..6865d8c5393 100644
--- a/tests/ui/parser/closure-return-syntax.rs
+++ b/tests/ui/parser/closure-return-syntax.rs
@@ -1,7 +1,21 @@
 // Test that we cannot parse a closure with an explicit return type
 // unless it uses braces.
 
-fn main() {
+fn needs_braces_1() {
     let x = || -> i32 22;
     //~^ ERROR expected `{`, found `22`
 }
+
+// Check other delimiters too.
+
+fn needs_braces_2() {
+        let x = || -> (i32, i32) (1, 2);
+        //~^ ERROR expected `{`, found `(`
+}
+
+fn needs_braces_3() {
+        let c = || -> [i32; 2] [1, 2];
+        //~^ ERROR expected `{`, found `[`
+}
+
+fn main() {}
diff --git a/tests/ui/parser/closure-return-syntax.stderr b/tests/ui/parser/closure-return-syntax.stderr
index aacc31ed871..763f19ccc64 100644
--- a/tests/ui/parser/closure-return-syntax.stderr
+++ b/tests/ui/parser/closure-return-syntax.stderr
@@ -2,12 +2,40 @@ error: expected `{`, found `22`
   --> $DIR/closure-return-syntax.rs:5:23
    |
 LL |     let x = || -> i32 22;
-   |                       ^^ expected `{`
+   |                   --- ^^
+   |                   |
+   |                   explicit return type requires closure body to be enclosed in braces
    |
-help: you might have meant to write this as part of a block
+help: wrap the expression in curly braces
    |
 LL |     let x = || -> i32 { 22 };
    |                       +    +
 
-error: aborting due to 1 previous error
+error: expected `{`, found `(`
+  --> $DIR/closure-return-syntax.rs:12:34
+   |
+LL |         let x = || -> (i32, i32) (1, 2);
+   |                       ---------- ^
+   |                       |
+   |                       explicit return type requires closure body to be enclosed in braces
+   |
+help: wrap the expression in curly braces
+   |
+LL |         let x = || -> (i32, i32) { (1, 2) };
+   |                                  +        +
+
+error: expected `{`, found `[`
+  --> $DIR/closure-return-syntax.rs:17:32
+   |
+LL |         let c = || -> [i32; 2] [1, 2];
+   |                       -------- ^
+   |                       |
+   |                       explicit return type requires closure body to be enclosed in braces
+   |
+help: wrap the expression in curly braces
+   |
+LL |         let c = || -> [i32; 2] { [1, 2] };
+   |                                +        +
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/extern-abi-from-mac-literal-frag.rs b/tests/ui/parser/extern-abi-from-mac-literal-frag.rs
index a4e9134218c..12b6c98705c 100644
--- a/tests/ui/parser/extern-abi-from-mac-literal-frag.rs
+++ b/tests/ui/parser/extern-abi-from-mac-literal-frag.rs
@@ -12,6 +12,8 @@ macro_rules! abi_from_lit_frag {
             fn _import();
         }
 
+        unsafe extern $abi {}
+
         extern $abi fn _export() {}
 
         type _PTR = extern $abi fn();
@@ -24,6 +26,8 @@ macro_rules! abi_from_expr_frag {
             fn _import();
         }
 
+        unsafe extern $abi {}
+
         extern $abi fn _export() {}
 
         type _PTR = extern $abi fn();
diff --git a/tests/ui/parser/float-field-interpolated.rs b/tests/ui/parser/float-field-interpolated.rs
index 990f2926dc8..bf7163039c4 100644
--- a/tests/ui/parser/float-field-interpolated.rs
+++ b/tests/ui/parser/float-field-interpolated.rs
@@ -5,10 +5,10 @@ macro_rules! generate_field_accesses {
         let s = S(0, (0, 0));
 
         s.$a; // OK
-        { s.$b; } //~ ERROR unexpected token: `1.1`
-                  //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found literal `1.1`
-        { s.$c; } //~ ERROR unexpected token: `1.1`
-                  //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found expression `1.1`
+        { s.$b; } //~ ERROR unexpected token: `literal` metavariable
+                  //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `literal` metavariable
+        { s.$c; } //~ ERROR unexpected token: `expr` metavariable
+                  //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `expr` metavariable
     };
 }
 
diff --git a/tests/ui/parser/float-field-interpolated.stderr b/tests/ui/parser/float-field-interpolated.stderr
index 2a1a4926cb3..e2b7e3a7dbe 100644
--- a/tests/ui/parser/float-field-interpolated.stderr
+++ b/tests/ui/parser/float-field-interpolated.stderr
@@ -1,4 +1,4 @@
-error: unexpected token: `1.1`
+error: unexpected token: `literal` metavariable
   --> $DIR/float-field-interpolated.rs:8:13
    |
 LL |         { s.$b; }
@@ -9,7 +9,7 @@ LL |     generate_field_accesses!(1.1, 1.1, 1.1);
    |
    = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: expected one of `.`, `;`, `?`, `}`, or an operator, found literal `1.1`
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `literal` metavariable
   --> $DIR/float-field-interpolated.rs:8:13
    |
 LL |         { s.$b; }
@@ -20,7 +20,7 @@ LL |     generate_field_accesses!(1.1, 1.1, 1.1);
    |
    = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: unexpected token: `1.1`
+error: unexpected token: `expr` metavariable
   --> $DIR/float-field-interpolated.rs:10:13
    |
 LL |         { s.$c; }
@@ -31,7 +31,7 @@ LL |     generate_field_accesses!(1.1, 1.1, 1.1);
    |
    = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: expected one of `.`, `;`, `?`, `}`, or an operator, found expression `1.1`
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `expr` metavariable
   --> $DIR/float-field-interpolated.rs:10:13
    |
 LL |         { s.$c; }
diff --git a/tests/ui/parser/import-from-path.rs b/tests/ui/parser/import-from-path.rs
index 54349d4971e..0d38c7224c5 100644
--- a/tests/ui/parser/import-from-path.rs
+++ b/tests/ui/parser/import-from-path.rs
@@ -1,2 +1 @@
-//@ error-pattern:expected
-use foo::{bar}::baz
+use foo::{bar}::baz //~ ERROR expected `;`, found `::`
diff --git a/tests/ui/parser/import-from-path.stderr b/tests/ui/parser/import-from-path.stderr
index b63e48d6679..f70c3b2e870 100644
--- a/tests/ui/parser/import-from-path.stderr
+++ b/tests/ui/parser/import-from-path.stderr
@@ -1,5 +1,5 @@
 error: expected `;`, found `::`
-  --> $DIR/import-from-path.rs:2:15
+  --> $DIR/import-from-path.rs:1:15
    |
 LL | use foo::{bar}::baz
    |               ^^ expected `;`
diff --git a/tests/ui/parser/import-from-rename.rs b/tests/ui/parser/import-from-rename.rs
index f6a4bb55553..4929b270e45 100644
--- a/tests/ui/parser/import-from-rename.rs
+++ b/tests/ui/parser/import-from-rename.rs
@@ -1,6 +1,4 @@
-//@ error-pattern:expected
-
-use foo::{bar} as baz;
+use foo::{bar} as baz; //~ ERROR expected `;`, found keyword `as`
 
 mod foo {
     pub fn bar() {}
diff --git a/tests/ui/parser/import-from-rename.stderr b/tests/ui/parser/import-from-rename.stderr
index 2f267a8d026..3289f1bdbe7 100644
--- a/tests/ui/parser/import-from-rename.stderr
+++ b/tests/ui/parser/import-from-rename.stderr
@@ -1,5 +1,5 @@
 error: expected `;`, found keyword `as`
-  --> $DIR/import-from-rename.rs:3:16
+  --> $DIR/import-from-rename.rs:1:16
    |
 LL | use foo::{bar} as baz;
    |                ^^ expected `;`
diff --git a/tests/ui/parser/import-glob-path.rs b/tests/ui/parser/import-glob-path.rs
index cb854de0cff..3f1c98fcade 100644
--- a/tests/ui/parser/import-glob-path.rs
+++ b/tests/ui/parser/import-glob-path.rs
@@ -1,2 +1 @@
-//@ error-pattern:expected
-use foo::*::bar
+use foo::*::bar //~ ERROR expected `;`, found `::`
diff --git a/tests/ui/parser/import-glob-path.stderr b/tests/ui/parser/import-glob-path.stderr
index 3bde32d1ea4..04f8a6e96fa 100644
--- a/tests/ui/parser/import-glob-path.stderr
+++ b/tests/ui/parser/import-glob-path.stderr
@@ -1,5 +1,5 @@
 error: expected `;`, found `::`
-  --> $DIR/import-glob-path.rs:2:11
+  --> $DIR/import-glob-path.rs:1:11
    |
 LL | use foo::*::bar
    |           ^^ expected `;`
diff --git a/tests/ui/parser/import-glob-rename.rs b/tests/ui/parser/import-glob-rename.rs
index 899818b15b6..5027a75f881 100644
--- a/tests/ui/parser/import-glob-rename.rs
+++ b/tests/ui/parser/import-glob-rename.rs
@@ -1,6 +1,4 @@
-//@ error-pattern:expected
-
-use foo::* as baz;
+use foo::* as baz; //~ ERROR expected `;`, found keyword `as`
 
 mod foo {
     pub fn bar() {}
diff --git a/tests/ui/parser/import-glob-rename.stderr b/tests/ui/parser/import-glob-rename.stderr
index 24e6c3f0006..2a5f2b66404 100644
--- a/tests/ui/parser/import-glob-rename.stderr
+++ b/tests/ui/parser/import-glob-rename.stderr
@@ -1,5 +1,5 @@
 error: expected `;`, found keyword `as`
-  --> $DIR/import-glob-rename.rs:3:12
+  --> $DIR/import-glob-rename.rs:1:12
    |
 LL | use foo::* as baz;
    |            ^^ expected `;`
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs
index ff28548b795..9c164813de2 100644
--- a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs
@@ -1,6 +1,7 @@
-//@ error-pattern: circular modules
 // Regression test for #97589: a doc-comment on a circular module bypassed cycle detection
 
 #![crate_type = "lib"]
 
 pub mod recursive;
+
+//~? ERROR circular modules: $DIR/recursive.rs -> $DIR/recursive.rs
diff --git a/tests/ui/parser/issues/issue-103451.rs b/tests/ui/parser/issues/issue-103451.rs
index 6b0928229e9..687dbc632d6 100644
--- a/tests/ui/parser/issues/issue-103451.rs
+++ b/tests/ui/parser/issues/issue-103451.rs
@@ -1,4 +1,4 @@
-//@ error-pattern: this file contains an unclosed delimiter
 struct R { }
+//~vv ERROR this file contains an unclosed delimiter
 struct S {
     x: [u8; R
diff --git a/tests/ui/parser/issues/issue-10636-2.rs b/tests/ui/parser/issues/issue-10636-2.rs
index 7200ea1f1dd..dcc03fec545 100644
--- a/tests/ui/parser/issues/issue-10636-2.rs
+++ b/tests/ui/parser/issues/issue-10636-2.rs
@@ -1,7 +1,7 @@
-//@ error-pattern: mismatched closing delimiter: `}`
 // FIXME(31528) we emit a bunch of silly errors here due to continuing past the
 // first one. This would be easy-ish to address by better recovery in tokenisation.
 
+//~vvvvv ERROR mismatched closing delimiter: `}`
 pub fn trace_option(option: Option<isize>) {
     option.map(|some| 42;
 
diff --git a/tests/ui/parser/issues/issue-21146.rs b/tests/ui/parser/issues/issue-21146.rs
index 81112808b21..95cae47939f 100644
--- a/tests/ui/parser/issues/issue-21146.rs
+++ b/tests/ui/parser/issues/issue-21146.rs
@@ -1,3 +1,4 @@
-//@ error-pattern: expected one of `!` or `::`, found `<eof>`
 include!("auxiliary/issue-21146-inc.rs");
 fn main() {}
+
+//~? ERROR expected one of `!` or `::`, found `<eof>`
diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr
index 2af57a52035..e96c004fb35 100644
--- a/tests/ui/parser/issues/issue-24375.stderr
+++ b/tests/ui/parser/issues/issue-24375.stderr
@@ -16,10 +16,6 @@ LL +     const VAL: /* Type */ = tmp[0];
 LL ~     match z {
 LL ~         VAL => {}
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { tmp[0] } => {}
-   |         +++++++        +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.rs b/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.rs
index 7952d29c260..0c0fbd7d592 100644
--- a/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.rs
+++ b/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.rs
@@ -1,5 +1,4 @@
 // Fixed in #66054.
 // ignore-tidy-trailing-newlines
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: aborting due to 1 previous error
+//~v ERROR this file contains an unclosed delimiter
 #[Ѕ
\ No newline at end of file
diff --git a/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr b/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr
index 14f5469f6af..28fd78d660d 100644
--- a/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr
+++ b/tests/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-58094-missing-right-square-bracket.rs:5:4
+  --> $DIR/issue-58094-missing-right-square-bracket.rs:4:4
    |
 LL | #[Ѕ
    |  - ^
diff --git a/tests/ui/parser/issues/issue-62524.rs b/tests/ui/parser/issues/issue-62524.rs
index a219f662cf7..a8c7d6eb9fd 100644
--- a/tests/ui/parser/issues/issue-62524.rs
+++ b/tests/ui/parser/issues/issue-62524.rs
@@ -1,6 +1,7 @@
 // ignore-tidy-trailing-newlines
-//@ error-pattern: aborting due to 1 previous error
+
 #![allow(uncommon_codepoints)]
 
+//~vv ERROR this file contains an unclosed delimiter
 y![
 Ϥ,
\ No newline at end of file
diff --git a/tests/ui/parser/issues/issue-62524.stderr b/tests/ui/parser/issues/issue-62524.stderr
index d83a49aedd6..c1ff6e7e715 100644
--- a/tests/ui/parser/issues/issue-62524.stderr
+++ b/tests/ui/parser/issues/issue-62524.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62524.rs:6:3
+  --> $DIR/issue-62524.rs:7:3
    |
 LL | y![
    |   - unclosed delimiter
diff --git a/tests/ui/parser/issues/issue-62554.rs b/tests/ui/parser/issues/issue-62554.rs
index 9f196e4b0d6..4a8a1684a41 100644
--- a/tests/ui/parser/issues/issue-62554.rs
+++ b/tests/ui/parser/issues/issue-62554.rs
@@ -1,5 +1,4 @@
-//@ error-pattern:this file contains an unclosed delimiter
-
 fn main() {}
 
+//~v ERROR this file contains an unclosed delimiter
 fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
diff --git a/tests/ui/parser/issues/issue-62554.stderr b/tests/ui/parser/issues/issue-62554.stderr
index d4aaef16181..50515c4c574 100644
--- a/tests/ui/parser/issues/issue-62554.stderr
+++ b/tests/ui/parser/issues/issue-62554.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62554.rs:5:89
+  --> $DIR/issue-62554.rs:4:89
    |
 LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
    |               -                       -         -                  -                  -^
diff --git a/tests/ui/parser/issues/issue-62894.rs b/tests/ui/parser/issues/issue-62894.rs
index 5b1627a2553..c49cbe4b934 100644
--- a/tests/ui/parser/issues/issue-62894.rs
+++ b/tests/ui/parser/issues/issue-62894.rs
@@ -1,6 +1,6 @@
 // Regression test for #62894, shouldn't crash.
-//@ error-pattern: this file contains an unclosed delimiter
 
+//~vvv ERROR this file contains an unclosed delimiter
 fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
 
 fn main() {}
diff --git a/tests/ui/parser/issues/issue-62973.rs b/tests/ui/parser/issues/issue-62973.rs
index 5c666d802fe..a091e4eec1d 100644
--- a/tests/ui/parser/issues/issue-62973.rs
+++ b/tests/ui/parser/issues/issue-62973.rs
@@ -1,8 +1,10 @@
 // ignore-tidy-trailing-newlines
-//@ error-pattern: aborting due to 3 previous errors
 
 fn main() {}
 
+//~vvv ERROR mismatched closing delimiter: `)`
+//~vv ERROR mismatched closing delimiter: `)`
+//~vvv ERROR this file contains an unclosed delimiter
 fn p() { match s { v, E { [) {) }
 
 
diff --git a/tests/ui/parser/issues/issue-62973.stderr b/tests/ui/parser/issues/issue-62973.stderr
index 493183988e1..ea3e2bebee4 100644
--- a/tests/ui/parser/issues/issue-62973.stderr
+++ b/tests/ui/parser/issues/issue-62973.stderr
@@ -1,5 +1,5 @@
 error: mismatched closing delimiter: `)`
-  --> $DIR/issue-62973.rs:6:27
+  --> $DIR/issue-62973.rs:8:27
    |
 LL | fn p() { match s { v, E { [) {) }
    |                           ^^ mismatched closing delimiter
@@ -7,7 +7,7 @@ LL | fn p() { match s { v, E { [) {) }
    |                           unclosed delimiter
 
 error: mismatched closing delimiter: `)`
-  --> $DIR/issue-62973.rs:6:30
+  --> $DIR/issue-62973.rs:8:30
    |
 LL | fn p() { match s { v, E { [) {) }
    |                              ^^ mismatched closing delimiter
@@ -15,7 +15,7 @@ LL | fn p() { match s { v, E { [) {) }
    |                              unclosed delimiter
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62973.rs:8:2
+  --> $DIR/issue-62973.rs:10:2
    |
 LL | fn p() { match s { v, E { [) {) }
    |        -         -         -  - missing open `(` for this delimiter
diff --git a/tests/ui/parser/issues/issue-63116.rs b/tests/ui/parser/issues/issue-63116.rs
index 3be9606b4ed..48abe639e8d 100644
--- a/tests/ui/parser/issues/issue-63116.rs
+++ b/tests/ui/parser/issues/issue-63116.rs
@@ -1,3 +1,4 @@
 // fixed by #66361
-//@ error-pattern: aborting due to 2 previous errors
+//~vv ERROR mismatched closing delimiter: `]`
+//~v ERROR this file contains an unclosed delimiter
 impl W <s(f;Y(;]
diff --git a/tests/ui/parser/issues/issue-63116.stderr b/tests/ui/parser/issues/issue-63116.stderr
index e0f7dd176ce..e5bad84d112 100644
--- a/tests/ui/parser/issues/issue-63116.stderr
+++ b/tests/ui/parser/issues/issue-63116.stderr
@@ -1,5 +1,5 @@
 error: mismatched closing delimiter: `]`
-  --> $DIR/issue-63116.rs:3:14
+  --> $DIR/issue-63116.rs:4:14
    |
 LL | impl W <s(f;Y(;]
    |              ^ ^ mismatched closing delimiter
@@ -7,7 +7,7 @@ LL | impl W <s(f;Y(;]
    |              unclosed delimiter
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-63116.rs:3:18
+  --> $DIR/issue-63116.rs:4:18
    |
 LL | impl W <s(f;Y(;]
    |          -     -^
diff --git a/tests/ui/parser/issues/issue-63135.rs b/tests/ui/parser/issues/issue-63135.rs
index 112dd4c83dd..63eca5b87ef 100644
--- a/tests/ui/parser/issues/issue-63135.rs
+++ b/tests/ui/parser/issues/issue-63135.rs
@@ -1,3 +1,2 @@
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: aborting due to 1 previous error
+//~v ERROR this file contains an unclosed delimiter
 fn i(n{...,f #
diff --git a/tests/ui/parser/issues/issue-63135.stderr b/tests/ui/parser/issues/issue-63135.stderr
index d6275901a53..061ec170388 100644
--- a/tests/ui/parser/issues/issue-63135.stderr
+++ b/tests/ui/parser/issues/issue-63135.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-63135.rs:3:16
+  --> $DIR/issue-63135.rs:2:16
    |
 LL | fn i(n{...,f #
    |     - -       ^
diff --git a/tests/ui/parser/issues/issue-66473.rs b/tests/ui/parser/issues/issue-66473.rs
index baa00f95e12..d0786add1af 100644
--- a/tests/ui/parser/issues/issue-66473.rs
+++ b/tests/ui/parser/issues/issue-66473.rs
Binary files differdiff --git a/tests/ui/parser/issues/issue-66473.stderr b/tests/ui/parser/issues/issue-66473.stderr
index ba38c4fa1b7..65b2d5a34ee 100644
--- a/tests/ui/parser/issues/issue-66473.stderr
+++ b/tests/ui/parser/issues/issue-66473.stderr
@@ -1,11 +1,11 @@
 error: unknown start of token: \u{348}
-  --> $DIR/issue-66473.rs:4:2
+  --> $DIR/issue-66473.rs:1:2
    |
 LL | #͈␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀
    |  ^
 
 error: unknown start of token: \u{0}
-  --> $DIR/issue-66473.rs:4:3
+  --> $DIR/issue-66473.rs:1:3
    |
 LL | #͈␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀
    |  ^^^^^^^^^^^^^^^^^^
@@ -14,19 +14,19 @@ LL | #͈␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀
    = note: character appears 17 more times
 
 error: unknown start of token: \u{1d}
-  --> $DIR/issue-66473.rs:5:2
+  --> $DIR/issue-66473.rs:4:2
    |
 LL | ␋␝6␝␀␀
    |  ^
 
 error: unknown start of token: \u{1d}
-  --> $DIR/issue-66473.rs:5:4
+  --> $DIR/issue-66473.rs:4:4
    |
 LL | ␋␝6␝␀␀
    |    ^
 
 error: unknown start of token: \u{0}
-  --> $DIR/issue-66473.rs:5:5
+  --> $DIR/issue-66473.rs:4:5
    |
 LL | ␋␝6␝␀␀
    |     ^^
@@ -35,10 +35,11 @@ LL | ␋␝6␝␀␀
    = note: character appears once more
 
 error: expected one of `!` or `[`, found `6`
-  --> $DIR/issue-66473.rs:5:3
+  --> $DIR/issue-66473.rs:4:3
    |
 LL | #͈␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀
    |  - expected one of `!` or `[`
+...
 LL | ␋␝6␝␀␀
    |   ^ unexpected token
 
diff --git a/tests/ui/parser/issues/issue-68629.rs b/tests/ui/parser/issues/issue-68629.rs
index d353d1f56ce..d1ea4ca8b03 100644
--- a/tests/ui/parser/issues/issue-68629.rs
+++ b/tests/ui/parser/issues/issue-68629.rs
Binary files differdiff --git a/tests/ui/parser/issues/issue-68629.stderr b/tests/ui/parser/issues/issue-68629.stderr
index f003f378179..373ad142778 100644
--- a/tests/ui/parser/issues/issue-68629.stderr
+++ b/tests/ui/parser/issues/issue-68629.stderr
@@ -1,17 +1,17 @@
 error: unknown start of token: \u{1c}
-  --> $DIR/issue-68629.rs:4:1
+  --> $DIR/issue-68629.rs:6:1
    |
 LL | ␜␟ts␀![{i
    | ^
 
 error: unknown start of token: \u{1f}
-  --> $DIR/issue-68629.rs:4:2
+  --> $DIR/issue-68629.rs:6:2
    |
 LL | ␜␟ts␀![{i
    |  ^
 
 error: unknown start of token: \u{0}
-  --> $DIR/issue-68629.rs:4:5
+  --> $DIR/issue-68629.rs:6:5
    |
 LL | ␜␟ts␀![{i
    |     ^
@@ -19,7 +19,7 @@ LL | ␜␟ts␀![{i
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/issue-68629.rs:5:1
+  --> $DIR/issue-68629.rs:7:1
    |
 LL | ␀␀  fn rݻoa>rݻm
    | ^^
@@ -28,7 +28,7 @@ LL | ␀␀  fn rݻoa>rݻm
    = note: character appears once more
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-68629.rs:5:17
+  --> $DIR/issue-68629.rs:7:17
    |
 LL | ␜␟ts␀![{i
    |       -- unclosed delimiter
diff --git a/tests/ui/parser/issues/issue-68730.rs b/tests/ui/parser/issues/issue-68730.rs
index f7f11cbc98b..9cf51b720eb 100644
--- a/tests/ui/parser/issues/issue-68730.rs
+++ b/tests/ui/parser/issues/issue-68730.rs
Binary files differdiff --git a/tests/ui/parser/issues/issue-68730.stderr b/tests/ui/parser/issues/issue-68730.stderr
index 838a6569bdc..1e01e02bdb7 100644
--- a/tests/ui/parser/issues/issue-68730.stderr
+++ b/tests/ui/parser/issues/issue-68730.stderr
@@ -1,5 +1,5 @@
 error: unknown start of token: \u{0}
-  --> $DIR/issue-68730.rs:5:5
+  --> $DIR/issue-68730.rs:8:5
    |
 LL | enum␀em␀˂˂
    |     ^
@@ -7,7 +7,7 @@ LL | enum␀em␀˂˂
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/issue-68730.rs:5:8
+  --> $DIR/issue-68730.rs:8:8
    |
 LL | enum␀em␀˂˂
    |        ^
@@ -15,7 +15,7 @@ LL | enum␀em␀˂˂
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{2c2}
-  --> $DIR/issue-68730.rs:5:9
+  --> $DIR/issue-68730.rs:8:9
    |
 LL | enum␀em␀˂˂
    |         ^^
@@ -28,7 +28,7 @@ LL + enum␀em␀<<
    |
 
 error: unknown start of token: \u{2c2}
-  --> $DIR/issue-68730.rs:5:10
+  --> $DIR/issue-68730.rs:8:10
    |
 LL | enum␀em␀˂˂
    |          ^
@@ -40,7 +40,7 @@ LL + enum␀em␀˂<
    |
 
 error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `<`
-  --> $DIR/issue-68730.rs:5:10
+  --> $DIR/issue-68730.rs:8:10
    |
 LL | enum␀em␀˂˂
    |          ^ expected one of `#`, `>`, `const`, identifier, or lifetime
diff --git a/tests/ui/parser/issues/issue-81804.rs b/tests/ui/parser/issues/issue-81804.rs
index 7c9e6e90582..57951ca5c4b 100644
--- a/tests/ui/parser/issues/issue-81804.rs
+++ b/tests/ui/parser/issues/issue-81804.rs
@@ -1,6 +1,5 @@
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: this file contains an unclosed delimiter
-
 fn main() {}
 
+//~vv ERROR mismatched closing delimiter: `}`
+//~v ERROR this file contains an unclosed delimiter
 fn p([=(}
diff --git a/tests/ui/parser/issues/issue-81804.stderr b/tests/ui/parser/issues/issue-81804.stderr
index 6caaaa792b1..f12c6a61ce5 100644
--- a/tests/ui/parser/issues/issue-81804.stderr
+++ b/tests/ui/parser/issues/issue-81804.stderr
@@ -1,5 +1,5 @@
 error: mismatched closing delimiter: `}`
-  --> $DIR/issue-81804.rs:6:8
+  --> $DIR/issue-81804.rs:5:8
    |
 LL | fn p([=(}
    |        ^^ mismatched closing delimiter
@@ -7,7 +7,7 @@ LL | fn p([=(}
    |        unclosed delimiter
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-81804.rs:6:11
+  --> $DIR/issue-81804.rs:5:11
    |
 LL | fn p([=(}
    |     --   ^
diff --git a/tests/ui/parser/issues/issue-81827.rs b/tests/ui/parser/issues/issue-81827.rs
index a2bd345fc05..7dfeec13022 100644
--- a/tests/ui/parser/issues/issue-81827.rs
+++ b/tests/ui/parser/issues/issue-81827.rs
@@ -1,10 +1,7 @@
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: mismatched closing delimiter: `]`
-
 #![crate_name="0"]
 
-
-
 fn main() {}
 
+//~vv ERROR mismatched closing delimiter: `]`
+//~v ERROR this file contains an unclosed delimiter
 fn r()->i{0|{#[cfg(r(0{]0
diff --git a/tests/ui/parser/issues/issue-81827.stderr b/tests/ui/parser/issues/issue-81827.stderr
index d12c74b4a34..986ed6b7e70 100644
--- a/tests/ui/parser/issues/issue-81827.stderr
+++ b/tests/ui/parser/issues/issue-81827.stderr
@@ -1,5 +1,5 @@
 error: mismatched closing delimiter: `]`
-  --> $DIR/issue-81827.rs:10:23
+  --> $DIR/issue-81827.rs:7:23
    |
 LL | fn r()->i{0|{#[cfg(r(0{]0
    |               -       ^^ mismatched closing delimiter
@@ -8,7 +8,7 @@ LL | fn r()->i{0|{#[cfg(r(0{]0
    |               closing delimiter possibly meant for this
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-81827.rs:10:27
+  --> $DIR/issue-81827.rs:7:27
    |
 LL | fn r()->i{0|{#[cfg(r(0{]0
    |          -  -          - ^
diff --git a/tests/ui/parser/issues/issue-84104.rs b/tests/ui/parser/issues/issue-84104.rs
index bced05e684a..6baf882701d 100644
--- a/tests/ui/parser/issues/issue-84104.rs
+++ b/tests/ui/parser/issues/issue-84104.rs
@@ -1,2 +1,2 @@
-//@ error-pattern: this file contains an unclosed delimiter
+//~v ERROR this file contains an unclosed delimiter
 #[i=i::<ښܖ<
diff --git a/tests/ui/parser/issues/issue-84148-2.rs b/tests/ui/parser/issues/issue-84148-2.rs
index 560475bd32c..452279021ab 100644
--- a/tests/ui/parser/issues/issue-84148-2.rs
+++ b/tests/ui/parser/issues/issue-84148-2.rs
@@ -1,2 +1,2 @@
-//@ error-pattern: this file contains an unclosed delimiter
+//~v ERROR this file contains an unclosed delimiter
 fn f(t:for<>t?
diff --git a/tests/ui/parser/issues/issue-88770.rs b/tests/ui/parser/issues/issue-88770.rs
index ecc50481f65..0dd18435ce3 100644
--- a/tests/ui/parser/issues/issue-88770.rs
+++ b/tests/ui/parser/issues/issue-88770.rs
@@ -1,7 +1,6 @@
 // Regression test for the ICE described in #88770.
 
-//@ error-pattern:this file contains an unclosed delimiter
-
+//~vvvv ERROR this file contains an unclosed delimiter
 fn m(){print!("",(c for&g
 u
 e
diff --git a/tests/ui/parser/issues/issue-88770.stderr b/tests/ui/parser/issues/issue-88770.stderr
index 5b54072d009..137cfea7e1d 100644
--- a/tests/ui/parser/issues/issue-88770.stderr
+++ b/tests/ui/parser/issues/issue-88770.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-88770.rs:8:3
+  --> $DIR/issue-88770.rs:7:3
    |
 LL | fn m(){print!("",(c for&g
    |       -      -   - unclosed delimiter
diff --git a/tests/ui/parser/macro/trait-non-item-macros.rs b/tests/ui/parser/macro/trait-non-item-macros.rs
index e93000193b6..b4140613cba 100644
--- a/tests/ui/parser/macro/trait-non-item-macros.rs
+++ b/tests/ui/parser/macro/trait-non-item-macros.rs
@@ -1,7 +1,7 @@
 macro_rules! bah {
     ($a:expr) => {
         $a
-    }; //~^ ERROR macro expansion ignores expression `2` and any tokens following
+    }; //~^ ERROR macro expansion ignores `expr` metavariable and any tokens following
 }
 
 trait Bar {
diff --git a/tests/ui/parser/macro/trait-non-item-macros.stderr b/tests/ui/parser/macro/trait-non-item-macros.stderr
index 1a828483778..62b42fa8b8d 100644
--- a/tests/ui/parser/macro/trait-non-item-macros.stderr
+++ b/tests/ui/parser/macro/trait-non-item-macros.stderr
@@ -1,4 +1,4 @@
-error: macro expansion ignores expression `2` and any tokens following
+error: macro expansion ignores `expr` metavariable and any tokens following
   --> $DIR/trait-non-item-macros.rs:3:9
    |
 LL |         $a
diff --git a/tests/ui/parser/mbe_missing_right_paren.rs b/tests/ui/parser/mbe_missing_right_paren.rs
index 9c57b0ebcfc..85191931664 100644
--- a/tests/ui/parser/mbe_missing_right_paren.rs
+++ b/tests/ui/parser/mbe_missing_right_paren.rs
@@ -1,3 +1,3 @@
 // ignore-tidy-trailing-newlines
-//@ error-pattern: this file contains an unclosed delimiter
+//~v ERROR this file contains an unclosed delimiter
 macro_rules! abc(ؼ
\ No newline at end of file
diff --git a/tests/ui/parser/missing_right_paren.rs b/tests/ui/parser/missing_right_paren.rs
index bbf4519a713..311a16c214c 100644
--- a/tests/ui/parser/missing_right_paren.rs
+++ b/tests/ui/parser/missing_right_paren.rs
@@ -1,4 +1,3 @@
 // ignore-tidy-trailing-newlines
-//@ error-pattern: this file contains an unclosed delimiter
-//@ error-pattern: aborting due to 1 previous error
+//~v ERROR this file contains an unclosed delimiter
 fn main((ؼ
\ No newline at end of file
diff --git a/tests/ui/parser/missing_right_paren.stderr b/tests/ui/parser/missing_right_paren.stderr
index 4815f04fbce..97ccb40a5a2 100644
--- a/tests/ui/parser/missing_right_paren.stderr
+++ b/tests/ui/parser/missing_right_paren.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/missing_right_paren.rs:4:11
+  --> $DIR/missing_right_paren.rs:3:11
    |
 LL | fn main((ؼ
    |        -- ^
diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr
index dcc1945d569..69bc5107cca 100644
--- a/tests/ui/parser/recover/recover-pat-exprs.stderr
+++ b/tests/ui/parser/recover/recover-pat-exprs.stderr
@@ -17,10 +17,6 @@ LL ~     match 0 {
 LL |         x => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.y } => (),
-   |         +++++++     +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:6:9
@@ -42,10 +38,6 @@ LL |         x => (),
 LL |         x.y => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.0 } => (),
-   |         +++++++     +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:7:9
@@ -68,10 +60,6 @@ LL |         x.y => (),
 LL |         x.0 => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x._0 } => (),
-   |         +++++++      +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:8:9
@@ -94,10 +82,6 @@ LL |         x => (),
 LL |         x._0 => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.0.1 } => (),
-   |         +++++++       +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:9:9
@@ -120,10 +104,6 @@ LL |         x => (),
 LL |         x.0.1 => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.4.y.17.__z } => (),
-   |         +++++++              +
 
 error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
   --> $DIR/recover-pat-exprs.rs:12:12
@@ -173,10 +153,6 @@ LL +     const VAL: /* Type */ = x[0];
 LL ~     match 0 {
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x[0] } => (),
-   |         +++++++      +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:24:9
@@ -197,10 +173,6 @@ LL ~     match 0 {
 LL |         x[0] => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x[..] } => (),
-   |         +++++++       +
 
 error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
   --> $DIR/recover-pat-exprs.rs:27:12
@@ -247,10 +219,6 @@ LL +     const VAL: /* Type */ = x.f();
 LL ~     match 0 {
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.f() } => (),
-   |         +++++++       +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:38:9
@@ -271,10 +239,6 @@ LL ~     match 0 {
 LL |         x.f() => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x._f() } => (),
-   |         +++++++        +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:39:9
@@ -296,10 +260,6 @@ LL |         x.f() => (),
 LL |         x._f() => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x? } => (),
-   |         +++++++    +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:40:9
@@ -322,10 +282,6 @@ LL |         x._f() => (),
 LL |         x? => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { ().f() } => (),
-   |         +++++++        +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:41:9
@@ -348,10 +304,6 @@ LL |         x.f() => (),
 LL |         ().f() => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { (0, x)?.f() } => (),
-   |         +++++++             +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:42:9
@@ -374,10 +326,6 @@ LL |         x.f() => (),
 LL |         (0, x)?.f() => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.f().g() } => (),
-   |         +++++++           +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:43:9
@@ -400,10 +348,6 @@ LL |         x.f() => (),
 LL |         x.f().g() => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { 0.f()?.g()?? } => (),
-   |         +++++++              +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:50:9
@@ -423,10 +367,6 @@ LL +     const VAL: /* Type */ = x as usize;
 LL ~     match 0 {
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x as usize } => (),
-   |         +++++++            +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:51:9
@@ -447,10 +387,6 @@ LL ~     match 0 {
 LL |         x as usize => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { 0 as usize } => (),
-   |         +++++++            +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:52:9
@@ -472,10 +408,6 @@ LL |         x as usize => (),
 LL |         0 as usize => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.f().0.4 as f32 } => (),
-   |         +++++++                  +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:59:9
@@ -495,10 +427,6 @@ LL +     const VAL: /* Type */ = 1 + 1;
 LL ~     match 0 {
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { 1 + 1 } => (),
-   |         +++++++       +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:60:9
@@ -519,10 +447,6 @@ LL ~     match 0 {
 LL |         1 + 1 => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { (1 + 2) * 3 } => (),
-   |         +++++++             +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:63:9
@@ -545,10 +469,6 @@ LL |         1 + 1 => (),
 LL |
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.0 > 2 } => (),
-   |         +++++++         +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:64:9
@@ -571,10 +491,6 @@ LL |         1 + 1 => (),
 LL |         x.0 > 2 => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { x.0 == 2 } => (),
-   |         +++++++          +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:69:13
@@ -594,10 +510,6 @@ LL +     const VAL: /* Type */ = y.0 > 2;
 LL ~     match (0, 0) {
 LL ~         (x, VAL) if x != 0 => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         (x, const { y.0 > 2 }) if x != 0 => (),
-   |             +++++++         +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:70:13
@@ -618,10 +530,6 @@ LL ~     match (0, 0) {
 LL |         (x, y.0 > 2) if x != 0 => (),
 LL ~         (x, VAL) if x != 0 || x != 1 => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         (x, const { y.0 > 2 }) if x != 0 || x != 1 => (),
-   |             +++++++         +
 
 error: left-hand side of `@` must be a binding
   --> $DIR/recover-pat-exprs.rs:83:9
@@ -658,10 +566,6 @@ LL +     const VAL: /* Type */ = u8::MAX.abs();
 LL ~     match u8::MAX {
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { u8::MAX.abs() } => (),
-   |         +++++++               +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:86:17
@@ -684,10 +588,6 @@ LL |         u8::MAX.abs() => (),
 LL |
 LL ~         z @ w @ VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         z @ w @ const { v.u() } => (),
-   |                 +++++++       +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:88:9
@@ -710,10 +610,6 @@ LL |         u8::MAX.abs() => (),
 LL |
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { y.ilog(3) } => (),
-   |         +++++++           +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:90:9
@@ -736,10 +632,6 @@ LL |         u8::MAX.abs() => (),
 LL |
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { n + 1 } => (),
-   |         +++++++       +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:92:10
@@ -762,10 +654,6 @@ LL |         u8::MAX.abs() => (),
 LL |
 LL ~         (VAL) => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         (const { "".f() + 14 * 8 }) => (),
-   |          +++++++                 +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:95:9
@@ -788,10 +676,6 @@ LL |         u8::MAX.abs() => (),
 LL |         0 | ((1) | 2) | 3 => (),
 LL ~         VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { f?() } => (),
-   |         +++++++      +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:101:9
diff --git a/tests/ui/parser/recover/recover-pat-issues.stderr b/tests/ui/parser/recover/recover-pat-issues.stderr
index 0c65b16dd95..ec7fcda3497 100644
--- a/tests/ui/parser/recover/recover-pat-issues.stderr
+++ b/tests/ui/parser/recover/recover-pat-issues.stderr
@@ -16,10 +16,6 @@ LL +     const VAL: /* Type */ = "hi".to_owned();
 LL ~     match foo {
 LL ~         Foo(VAL) => true,
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         Foo(const { "hi".to_owned() }) => true,
-   |             +++++++                 +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-issues.rs:14:20
@@ -39,10 +35,6 @@ LL +     const BAZ: /* Type */ = "hi".to_owned();
 LL ~     match bar {
 LL ~         Bar { baz: BAZ } => true,
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         Bar { baz: const { "hi".to_owned() } } => true,
-   |                    +++++++                 +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-issues.rs:25:11
@@ -62,10 +54,6 @@ LL +     const VAL: /* Type */ = "foo".to_string();
 LL ~     match foo.as_slice() {
 LL ~         &[VAL] => {}
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         &[const { "foo".to_string() }] => {}
-   |           +++++++                   +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-issues.rs:36:17
@@ -79,10 +67,6 @@ help: consider extracting the expression into a `const`
 LL +     const VAL: /* Type */ = MAGIC.0 as usize;
 LL ~     if let Some(VAL) = None::<usize> {}
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |     if let Some(const { MAGIC.0 as usize }) = None::<usize> {}
-   |                 +++++++                  +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-issues.rs:41:13
@@ -96,10 +80,6 @@ help: consider extracting the expression into a `const`
 LL +     const VAL: /* Type */ = -1.some(4);
 LL ~     if let (VAL) = (0, Some(4)) {}
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |     if let (const { -1.some(4) }) = (0, Some(4)) {}
-   |             +++++++            +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-issues.rs:44:13
@@ -113,10 +93,6 @@ help: consider extracting the expression into a `const`
 LL +     const VAL: /* Type */ = -1.Some(4);
 LL ~     if let (VAL) = (0, Some(4)) {}
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |     if let (const { -1.Some(4) }) = (0, Some(4)) {}
-   |             +++++++            +
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/parser/recover/recover-pat-lets.stderr b/tests/ui/parser/recover/recover-pat-lets.stderr
index 55252729d7b..ab79e4ebcae 100644
--- a/tests/ui/parser/recover/recover-pat-lets.stderr
+++ b/tests/ui/parser/recover/recover-pat-lets.stderr
@@ -34,10 +34,6 @@ help: consider extracting the expression into a `const`
 LL +     const VAL: /* Type */ = 1 + 1;
 LL ~     let Some(VAL) = x else {
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |     let Some(const { 1 + 1 }) = x else {
-   |              +++++++       +
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-lets.rs:17:17
@@ -51,10 +47,6 @@ help: consider extracting the expression into a `const`
 LL +     const VAL: /* Type */ = 1 + 1;
 LL ~     if let Some(VAL) = x {
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |     if let Some(const { 1 + 1 }) = x {
-   |                 +++++++       +
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/parser/recover/recover-pat-ranges.stderr b/tests/ui/parser/recover/recover-pat-ranges.stderr
index e8f323596d0..6c17182618b 100644
--- a/tests/ui/parser/recover/recover-pat-ranges.stderr
+++ b/tests/ui/parser/recover/recover-pat-ranges.stderr
@@ -98,10 +98,6 @@ LL |         0..=1 => (),
 LL |
 LL ~         ..=VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         ..=const { 1 + 2 } => (),
-   |            +++++++       +
 
 error: expected a pattern range bound, found an expression
   --> $DIR/recover-pat-ranges.rs:15:10
@@ -119,10 +115,6 @@ LL |         0..=1 => (),
 LL |
 LL ~         (VAL).. => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         (const { -4 + 0 }).. => (),
-   |          +++++++        +
 
 error: expected a pattern range bound, found an expression
   --> $DIR/recover-pat-ranges.rs:18:10
@@ -140,10 +132,6 @@ LL |         0..=1 => (),
 LL |
 LL ~         (VAL)...1 * 2 => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         (const { 1 + 4 })...1 * 2 => (),
-   |          +++++++       +
 
 error: expected a pattern range bound, found an expression
   --> $DIR/recover-pat-ranges.rs:18:19
@@ -161,10 +149,6 @@ LL |         0..=1 => (),
 LL |
 LL ~         (1 + 4)...VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         (1 + 4)...const { 1 * 2 } => (),
-   |                   +++++++       +
 
 error: expected a pattern range bound, found an expression
   --> $DIR/recover-pat-ranges.rs:24:9
@@ -182,10 +166,6 @@ LL |         0..=1 => (),
 LL |
 LL ~         VAL..="y".z() => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         const { 0.x() }..="y".z() => (),
-   |         +++++++       +
 
 error: expected a pattern range bound, found an expression
   --> $DIR/recover-pat-ranges.rs:24:17
@@ -203,10 +183,6 @@ LL |         0..=1 => (),
 LL |
 LL ~         0.x()..=VAL => (),
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         0.x()..=const { "y".z() } => (),
-   |                 +++++++         +
 
 warning: `...` range patterns are deprecated
   --> $DIR/recover-pat-ranges.rs:18:16
diff --git a/tests/ui/parser/recover/recover-pat-wildcards.stderr b/tests/ui/parser/recover/recover-pat-wildcards.stderr
index f939e513370..ebc1cbf7d59 100644
--- a/tests/ui/parser/recover/recover-pat-wildcards.stderr
+++ b/tests/ui/parser/recover/recover-pat-wildcards.stderr
@@ -84,10 +84,6 @@ LL +     const VAL: /* Type */ = 2 + _;
 LL ~     match 9 {
 LL ~         4..=(VAL) => ()
    |
-help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
-   |
-LL |         4..=(const { 2 + _ }) => ()
-   |              +++++++       +
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/parser/shebang/shebang-split.rs b/tests/ui/parser/shebang/shebang-split.rs
index 470bb669143..eb8f0f769c8 100644
--- a/tests/ui/parser/shebang/shebang-split.rs
+++ b/tests/ui/parser/shebang/shebang-split.rs
@@ -1,5 +1,4 @@
 // empty line
 # !/bin/env
-
+//~^ ERROR expected `[`, found `/`
 // checks that diagnostics for shebang lookalikes is not present
-//@ error-pattern: expected `[`\n\n
diff --git a/tests/ui/parser/unbalanced-doublequote.rs b/tests/ui/parser/unbalanced-doublequote.rs
index d9c936186ea..43e23a70271 100644
--- a/tests/ui/parser/unbalanced-doublequote.rs
+++ b/tests/ui/parser/unbalanced-doublequote.rs
@@ -1,6 +1,4 @@
-//@ error-pattern: unterminated double quote string
-
-
+//~vv ERROR unterminated double quote string
 fn main() {
     "
 }
diff --git a/tests/ui/parser/unbalanced-doublequote.stderr b/tests/ui/parser/unbalanced-doublequote.stderr
index d40b982da7c..60057eddbb4 100644
--- a/tests/ui/parser/unbalanced-doublequote.stderr
+++ b/tests/ui/parser/unbalanced-doublequote.stderr
@@ -1,5 +1,5 @@
 error[E0765]: unterminated double quote string
-  --> $DIR/unbalanced-doublequote.rs:5:5
+  --> $DIR/unbalanced-doublequote.rs:3:5
    |
 LL | /     "
 LL | | }
diff --git a/tests/ui/parser/use-unclosed-brace.rs b/tests/ui/parser/use-unclosed-brace.rs
index 6679651fe47..aa52fe92ac1 100644
--- a/tests/ui/parser/use-unclosed-brace.rs
+++ b/tests/ui/parser/use-unclosed-brace.rs
@@ -1,4 +1,3 @@
-//@ error-pattern: this file contains an unclosed delimiter
 use foo::{bar, baz;
 
 use std::fmt::Display;
@@ -7,4 +6,5 @@ mod bar { }
 
 mod baz { }
 
+//~v ERROR this file contains an unclosed delimiter
 fn main() {}
diff --git a/tests/ui/parser/utf16-be-without-bom.rs b/tests/ui/parser/utf16-be-without-bom.rs
index f5fe8dc5a8c..538728735f0 100644
--- a/tests/ui/parser/utf16-be-without-bom.rs
+++ b/tests/ui/parser/utf16-be-without-bom.rs
Binary files differdiff --git a/tests/ui/parser/utf16-be-without-bom.stderr b/tests/ui/parser/utf16-be-without-bom.stderr
index 0493bcbc77a..467e0ed7313 100644
--- a/tests/ui/parser/utf16-be-without-bom.stderr
+++ b/tests/ui/parser/utf16-be-without-bom.stderr
@@ -1,5 +1,5 @@
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:1
+  --> $DIR/utf16-be-without-bom.rs:6:1
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    | ^
@@ -7,7 +7,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:3
+  --> $DIR/utf16-be-without-bom.rs:6:3
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |   ^
@@ -15,7 +15,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:5
+  --> $DIR/utf16-be-without-bom.rs:6:5
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |     ^
@@ -23,7 +23,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:7
+  --> $DIR/utf16-be-without-bom.rs:6:7
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |       ^
@@ -31,7 +31,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:9
+  --> $DIR/utf16-be-without-bom.rs:6:9
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |         ^
@@ -39,7 +39,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:11
+  --> $DIR/utf16-be-without-bom.rs:6:11
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |           ^
@@ -47,7 +47,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:13
+  --> $DIR/utf16-be-without-bom.rs:6:13
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |             ^
@@ -55,7 +55,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:15
+  --> $DIR/utf16-be-without-bom.rs:6:15
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |               ^
@@ -63,7 +63,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:17
+  --> $DIR/utf16-be-without-bom.rs:6:17
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                 ^
@@ -71,7 +71,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:19
+  --> $DIR/utf16-be-without-bom.rs:6:19
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                   ^
@@ -79,7 +79,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:21
+  --> $DIR/utf16-be-without-bom.rs:6:21
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                     ^
@@ -87,7 +87,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:23
+  --> $DIR/utf16-be-without-bom.rs:6:23
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                       ^
@@ -95,7 +95,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-be-without-bom.rs:5:25
+  --> $DIR/utf16-be-without-bom.rs:6:25
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                         ^
@@ -103,7 +103,7 @@ LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: expected one of `!` or `::`, found `n`
-  --> $DIR/utf16-be-without-bom.rs:5:4
+  --> $DIR/utf16-be-without-bom.rs:6:4
    |
 LL | ␀f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |    ^ expected one of `!` or `::`
diff --git a/tests/ui/parser/utf16-le-without-bom.rs b/tests/ui/parser/utf16-le-without-bom.rs
index 8c781b27dc0..fc413663c9c 100644
--- a/tests/ui/parser/utf16-le-without-bom.rs
+++ b/tests/ui/parser/utf16-le-without-bom.rs
Binary files differdiff --git a/tests/ui/parser/utf16-le-without-bom.stderr b/tests/ui/parser/utf16-le-without-bom.stderr
index 4b195ed0da1..701379d4067 100644
--- a/tests/ui/parser/utf16-le-without-bom.stderr
+++ b/tests/ui/parser/utf16-le-without-bom.stderr
@@ -1,5 +1,5 @@
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:2
+  --> $DIR/utf16-le-without-bom.rs:6:2
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |  ^
@@ -7,7 +7,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:4
+  --> $DIR/utf16-le-without-bom.rs:6:4
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |    ^
@@ -15,7 +15,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:6
+  --> $DIR/utf16-le-without-bom.rs:6:6
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |      ^
@@ -23,7 +23,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:8
+  --> $DIR/utf16-le-without-bom.rs:6:8
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |        ^
@@ -31,7 +31,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:10
+  --> $DIR/utf16-le-without-bom.rs:6:10
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |          ^
@@ -39,7 +39,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:12
+  --> $DIR/utf16-le-without-bom.rs:6:12
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |            ^
@@ -47,7 +47,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:14
+  --> $DIR/utf16-le-without-bom.rs:6:14
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |              ^
@@ -55,7 +55,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:16
+  --> $DIR/utf16-le-without-bom.rs:6:16
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                ^
@@ -63,7 +63,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:18
+  --> $DIR/utf16-le-without-bom.rs:6:18
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                  ^
@@ -71,7 +71,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:20
+  --> $DIR/utf16-le-without-bom.rs:6:20
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                    ^
@@ -79,7 +79,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:22
+  --> $DIR/utf16-le-without-bom.rs:6:22
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                      ^
@@ -87,7 +87,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:5:24
+  --> $DIR/utf16-le-without-bom.rs:6:24
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |                        ^
@@ -95,7 +95,7 @@ LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: unknown start of token: \u{0}
-  --> $DIR/utf16-le-without-bom.rs:6:1
+  --> $DIR/utf16-le-without-bom.rs:7:1
    |
 LL | ␀
    | ^
@@ -103,7 +103,7 @@ LL | ␀
    = help: source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
 
 error: expected one of `!` or `::`, found `n`
-  --> $DIR/utf16-le-without-bom.rs:5:3
+  --> $DIR/utf16-le-without-bom.rs:6:3
    |
 LL | f␀n␀ ␀m␀a␀i␀n␀(␀)␀ ␀{␀}␀
    |   ^ expected one of `!` or `::`
diff --git a/tests/ui/pattern/non-structural-match-types.rs b/tests/ui/pattern/non-structural-match-types.rs
index dde44dfee9c..5869767c936 100644
--- a/tests/ui/pattern/non-structural-match-types.rs
+++ b/tests/ui/pattern/non-structural-match-types.rs
@@ -1,14 +1,29 @@
 //@ edition:2021
-
-#![allow(unreachable_code)]
 #![feature(const_async_blocks)]
-#![feature(inline_const_pat)]
 
-fn main() {
-    match loop {} {
-        const { || {} } => {} //~ ERROR cannot be used in patterns
+struct AnyOption<T>(T);
+impl<T> AnyOption<T> {
+    const NONE: Option<T> = None;
+}
+
+fn uwu() {}
+fn defines() {
+    match Some(uwu) {
+        AnyOption::<_>::NONE => {}
+        //~^ ERROR constant of non-structural type
+        _ => {}
     }
-    match loop {} {
-        const { async {} } => {} //~ ERROR cannot be used in patterns
+
+    match Some(|| {}) {
+        AnyOption::<_>::NONE => {}
+        //~^ ERROR constant of non-structural type
+        _ => {}
+    }
+
+    match Some(async {}) {
+        AnyOption::<_>::NONE => {}
+        //~^ ERROR constant of non-structural type
+        _ => {}
     }
 }
+fn main() {}
diff --git a/tests/ui/pattern/non-structural-match-types.stderr b/tests/ui/pattern/non-structural-match-types.stderr
index 3588751bf66..da675a9f3ff 100644
--- a/tests/ui/pattern/non-structural-match-types.stderr
+++ b/tests/ui/pattern/non-structural-match-types.stderr
@@ -1,14 +1,42 @@
-error: closure `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
-  --> $DIR/non-structural-match-types.rs:9:9
+error: constant of non-structural type `Option<fn() {uwu}>` in a pattern
+  --> $DIR/non-structural-match-types.rs:12:9
+   |
+LL | impl<T> AnyOption<T> {
+   | --------------------
+LL |     const NONE: Option<T> = None;
+   |     --------------------- constant defined here
+...
+LL |         AnyOption::<_>::NONE => {}
+   |         ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
    |
-LL |         const { || {} } => {}
-   |         ^^^^^^^^^^^^^^^ closure can't be used in patterns
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
-error: `async` block `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns
-  --> $DIR/non-structural-match-types.rs:12:9
+error: constant of non-structural type `Option<{closure@$DIR/non-structural-match-types.rs:17:16: 17:18}>` in a pattern
+  --> $DIR/non-structural-match-types.rs:18:9
+   |
+LL | impl<T> AnyOption<T> {
+   | --------------------
+LL |     const NONE: Option<T> = None;
+   |     --------------------- constant defined here
+...
+LL |         AnyOption::<_>::NONE => {}
+   |         ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
+   |
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+
+error: constant of non-structural type `Option<{async block@$DIR/non-structural-match-types.rs:23:16: 23:21}>` in a pattern
+  --> $DIR/non-structural-match-types.rs:24:9
+   |
+LL | impl<T> AnyOption<T> {
+   | --------------------
+LL |     const NONE: Option<T> = None;
+   |     --------------------- constant defined here
+...
+LL |         AnyOption::<_>::NONE => {}
+   |         ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
    |
-LL |         const { async {} } => {}
-   |         ^^^^^^^^^^^^^^^^^^ `async` block can't be used in patterns
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+   = note: `ResumeTy` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/pin-macro/pin_move.rs b/tests/ui/pin-macro/pin_move.rs
new file mode 100644
index 00000000000..0f6d34fad95
--- /dev/null
+++ b/tests/ui/pin-macro/pin_move.rs
@@ -0,0 +1,26 @@
+//@ edition:2024
+
+use core::marker::PhantomPinned;
+use core::pin::pin;
+
+fn a() {
+    struct NotCopy<T>(T);
+    #[allow(unused_mut)]
+    let mut pointee = NotCopy(PhantomPinned);
+    pin!(pointee);
+    let _moved = pointee;
+    //~^ ERROR use of moved value
+}
+
+fn b() {
+    struct NotCopy<T>(T);
+    let mut pointee = NotCopy(PhantomPinned);
+    pin!(*&mut pointee);
+    //~^ ERROR cannot move
+    let _moved = pointee;
+}
+
+fn main() {
+    a();
+    b();
+}
diff --git a/tests/ui/pin-macro/pin_move.stderr b/tests/ui/pin-macro/pin_move.stderr
new file mode 100644
index 00000000000..c9b8ad9b202
--- /dev/null
+++ b/tests/ui/pin-macro/pin_move.stderr
@@ -0,0 +1,38 @@
+error[E0382]: use of moved value: `pointee`
+  --> $DIR/pin_move.rs:11:18
+   |
+LL |     let mut pointee = NotCopy(PhantomPinned);
+   |         ----------- move occurs because `pointee` has type `a::NotCopy<PhantomPinned>`, which does not implement the `Copy` trait
+LL |     pin!(pointee);
+   |          ------- value moved here
+LL |     let _moved = pointee;
+   |                  ^^^^^^^ value used here after move
+   |
+note: if `a::NotCopy<PhantomPinned>` implemented `Clone`, you could clone the value
+  --> $DIR/pin_move.rs:7:5
+   |
+LL |     struct NotCopy<T>(T);
+   |     ^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |     pin!(pointee);
+   |          ------- you could clone this value
+
+error[E0507]: cannot move out of a mutable reference
+  --> $DIR/pin_move.rs:18:10
+   |
+LL |     pin!(*&mut pointee);
+   |          ^^^^^^^^^^^^^ move occurs because value has type `b::NotCopy<PhantomPinned>`, which does not implement the `Copy` trait
+   |
+note: if `b::NotCopy<PhantomPinned>` implemented `Clone`, you could clone the value
+  --> $DIR/pin_move.rs:16:5
+   |
+LL |     struct NotCopy<T>(T);
+   |     ^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
+LL |     let mut pointee = NotCopy(PhantomPinned);
+LL |     pin!(*&mut pointee);
+   |          ------------- you could clone this value
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0382, E0507.
+For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/precondition-checks/copy-nonoverlapping.rs b/tests/ui/precondition-checks/copy-nonoverlapping.rs
index 81018e4bff3..eacaa63e543 100644
--- a/tests/ui/precondition-checks/copy-nonoverlapping.rs
+++ b/tests/ui/precondition-checks/copy-nonoverlapping.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::copy_nonoverlapping requires
 //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/copy.rs b/tests/ui/precondition-checks/copy.rs
index 694853f950a..1fadd90bf70 100644
--- a/tests/ui/precondition-checks/copy.rs
+++ b/tests/ui/precondition-checks/copy.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::copy requires
 //@ revisions: null_src null_dst misaligned_src misaligned_dst
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/read_volatile.rs b/tests/ui/precondition-checks/read_volatile.rs
index e14881d0290..ada8932c398 100644
--- a/tests/ui/precondition-checks/read_volatile.rs
+++ b/tests/ui/precondition-checks/read_volatile.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires
 //@ revisions: null misaligned
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/replace.rs b/tests/ui/precondition-checks/replace.rs
index 2808cee7b64..44afbd8174c 100644
--- a/tests/ui/precondition-checks/replace.rs
+++ b/tests/ui/precondition-checks/replace.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::replace requires
 //@ revisions: null misaligned
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
index 3801639e255..9b9ded69a83 100644
--- a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
+++ b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts_mut requires
 //@ revisions: null misaligned toolarge
 
+#![allow(invalid_null_arguments)]
+
 fn main() {
     unsafe {
         #[cfg(null)]
diff --git a/tests/ui/precondition-checks/slice-from-raw-parts.rs b/tests/ui/precondition-checks/slice-from-raw-parts.rs
index a3690fa045e..96578c1eae5 100644
--- a/tests/ui/precondition-checks/slice-from-raw-parts.rs
+++ b/tests/ui/precondition-checks/slice-from-raw-parts.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts requires
 //@ revisions: null misaligned toolarge
 
+#![allow(invalid_null_arguments)]
+
 fn main() {
     unsafe {
         #[cfg(null)]
diff --git a/tests/ui/precondition-checks/swap-nonoverlapping.rs b/tests/ui/precondition-checks/swap-nonoverlapping.rs
index 52e4a3c870b..ea1f6f36ad7 100644
--- a/tests/ui/precondition-checks/swap-nonoverlapping.rs
+++ b/tests/ui/precondition-checks/swap-nonoverlapping.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::swap_nonoverlapping requires
 //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/write_volatile.rs b/tests/ui/precondition-checks/write_volatile.rs
index ac0b89b5ecf..0d5ecb014b3 100644
--- a/tests/ui/precondition-checks/write_volatile.rs
+++ b/tests/ui/precondition-checks/write_volatile.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires
 //@ revisions: null misaligned
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/zero-size-null.rs b/tests/ui/precondition-checks/zero-size-null.rs
index 43a81175f94..55d768fc9e5 100644
--- a/tests/ui/precondition-checks/zero-size-null.rs
+++ b/tests/ui/precondition-checks/zero-size-null.rs
@@ -7,8 +7,10 @@ use std::ptr;
 
 fn main() {
     unsafe {
+        #[expect(invalid_null_arguments)] // false-positive, copy of 0
         ptr::copy_nonoverlapping::<u8>(ptr::null(), ptr::null_mut(), 0);
         ptr::copy_nonoverlapping::<()>(ptr::null(), ptr::null_mut(), 123);
+        #[expect(invalid_null_arguments)] // false-positive, copy of 0
         ptr::copy::<u8>(ptr::null(), ptr::null_mut(), 0);
         ptr::copy::<()>(ptr::null(), ptr::null_mut(), 123);
         ptr::swap::<()>(ptr::null_mut(), ptr::null_mut());
diff --git a/tests/ui/print-request/print-lints-help.rs b/tests/ui/print-request/print-lints-help.rs
index 420eae27ed4..6dd88a701c3 100644
--- a/tests/ui/print-request/print-lints-help.rs
+++ b/tests/ui/print-request/print-lints-help.rs
@@ -2,6 +2,7 @@
 //! `--print=lints` (which is not a valid print request).
 
 //@ compile-flags: --print lints
-//@ error-pattern: error: unknown print request: `lints`
 //@ error-pattern: help: use `-Whelp` to print a list of lints
 //@ error-pattern: help: for more information, see the rustc book
+
+//~? ERROR unknown print request: `lints`
diff --git a/tests/ui/print-request/print-lints-help.stderr b/tests/ui/print-request/print-lints-help.stderr
index 0530d11f2e8..bc48b2fa73c 100644
--- a/tests/ui/print-request/print-lints-help.stderr
+++ b/tests/ui/print-request/print-lints-help.stderr
@@ -1,6 +1,6 @@
 error: unknown print request: `lints`
   |
-  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
   = help: use `-Whelp` to print a list of lints
   = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
 
diff --git a/tests/ui/print-request/stability.rs b/tests/ui/print-request/stability.rs
index c3421224d72..54142ce78ce 100644
--- a/tests/ui/print-request/stability.rs
+++ b/tests/ui/print-request/stability.rs
@@ -16,19 +16,18 @@
 
 //@ revisions: all_target_specs_json
 //@[all_target_specs_json] compile-flags: --print=all-target-specs-json
-//@[all_target_specs_json] error-pattern: the `-Z unstable-options` flag must also be passed
+
+//@ revisions: crate_root_lint_levels
+//@[crate_root_lint_levels] compile-flags: --print=crate-root-lint-levels
 
 //@ revisions: check_cfg
 //@[check_cfg] compile-flags: --print=check-cfg
-//@[check_cfg] error-pattern: the `-Z unstable-options` flag must also be passed
 
 //@ revisions: supported_crate_types
 //@[supported_crate_types] compile-flags: --print=supported-crate-types
-//@[supported_crate_types] error-pattern: the `-Z unstable-options` flag must also be passed
 
 //@ revisions: target_spec_json
 //@[target_spec_json] compile-flags: --print=target-spec-json
-//@[target_spec_json] error-pattern: the `-Z unstable-options` flag must also be passed
 
 // =======================
 // Stable print requests
@@ -105,3 +104,9 @@
 //@[tls_models] check-pass
 
 fn main() {}
+
+//[all_target_specs_json]~? ERROR the `-Z unstable-options` flag must also be passed to enable the `all-target-specs-json` print option
+//[crate_root_lint_levels]~? ERROR the `-Z unstable-options` flag must also be passed to enable the `crate-root-lint-levels` print option
+//[check_cfg]~? ERROR the `-Z unstable-options` flag must also be passed to enable the `check-cfg` print option
+//[supported_crate_types]~? ERROR the `-Z unstable-options` flag must also be passed to enable the `supported-crate-types` print option
+//[target_spec_json]~? ERROR the `-Z unstable-options` flag must also be passed to enable the `target-spec-json` print option
diff --git a/tests/ui/privacy/privacy-ns1.stderr b/tests/ui/privacy/privacy-ns1.stderr
index 3396330c993..c782c67e71c 100644
--- a/tests/ui/privacy/privacy-ns1.stderr
+++ b/tests/ui/privacy/privacy-ns1.stderr
@@ -7,6 +7,14 @@ LL |     pub struct Baz;
 LL |     Bar();
    |     ^^^
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns1.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: a unit struct with a similar name exists
    |
 LL -     Bar();
@@ -26,6 +34,14 @@ LL |     pub struct Baz;
 LL |     Bar();
    |     ^^^
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns1.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: a unit struct with a similar name exists
    |
 LL -     Bar();
@@ -45,6 +61,14 @@ LL |     pub struct Baz;
 LL |     let _x: Box<Bar>;
    |                 ^^^
    |
+note: these traits exist but are inaccessible
+  --> $DIR/privacy-ns1.rs:25:5
+   |
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo2::Bar`: not accessible
+...
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo3::Bar`: not accessible
 help: a struct with a similar name exists
    |
 LL -     let _x: Box<Bar>;
diff --git a/tests/ui/privacy/privacy-ns2.stderr b/tests/ui/privacy/privacy-ns2.stderr
index ac98682b2b3..fe1f0c9bd48 100644
--- a/tests/ui/privacy/privacy-ns2.stderr
+++ b/tests/ui/privacy/privacy-ns2.stderr
@@ -4,6 +4,14 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Bar
 LL |     Bar();
    |     ^^^ not a function, tuple struct or tuple variant
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns2.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: consider importing this function instead
    |
 LL + use foo2::Bar;
@@ -18,6 +26,14 @@ LL |     pub struct Baz;
 LL |     Bar();
    |     ^^^
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns2.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: a unit struct with a similar name exists
    |
 LL -     Bar();
@@ -34,6 +50,14 @@ error[E0573]: expected type, found function `Bar`
 LL |     let _x : Bar();
    |              ^^^^^ not a type
    |
+note: these traits exist but are inaccessible
+  --> $DIR/privacy-ns2.rs:31:5
+   |
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo2::Bar`: not accessible
+...
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo3::Bar`: not accessible
 help: use `=` if you meant to assign
    |
 LL -     let _x : Bar();
diff --git a/tests/ui/privacy/private-inferred-type-3.rs b/tests/ui/privacy/private-inferred-type-3.rs
index 7bf6bea4b0f..820b0cbb30f 100644
--- a/tests/ui/privacy/private-inferred-type-3.rs
+++ b/tests/ui/privacy/private-inferred-type-3.rs
@@ -1,17 +1,16 @@
 //@ aux-build:private-inferred-type.rs
 
-//@ error-pattern:type `fn() {ext::priv_fn}` is private
-//@ error-pattern:static `ext::PRIV_STATIC` is private
-//@ error-pattern:type `ext::PrivEnum` is private
-//@ error-pattern:type `fn() {<u8 as ext::PrivTrait>::method}` is private
-//@ error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private
-//@ error-pattern:type `fn(u8) -> PubTupleStruct {PubTupleStruct}` is private
-//@ error-pattern:type `for<'a> fn(&'a Pub<u8>) {Pub::<u8>::priv_method}` is private
-
 #![feature(decl_macro)]
 
 extern crate private_inferred_type as ext;
 
 fn main() {
     ext::m!();
+    //~^ ERROR type `fn() {ext::priv_fn}` is private
+    //~| ERROR static `ext::PRIV_STATIC` is private
+    //~| ERROR type `ext::PrivEnum` is private
+    //~| ERROR type `fn() {<u8 as ext::PrivTrait>::method}` is private
+    //~| ERROR type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private
+    //~| ERROR type `fn(u8) -> PubTupleStruct {PubTupleStruct}` is private
+    //~| ERROR type `for<'a> fn(&'a Pub<u8>) {Pub::<u8>::priv_method}` is private
 }
diff --git a/tests/ui/privacy/private-inferred-type-3.stderr b/tests/ui/privacy/private-inferred-type-3.stderr
index 42faeb4bf34..0b4899c8d3d 100644
--- a/tests/ui/privacy/private-inferred-type-3.stderr
+++ b/tests/ui/privacy/private-inferred-type-3.stderr
@@ -1,5 +1,5 @@
 error: type `fn() {ext::priv_fn}` is private
-  --> $DIR/private-inferred-type-3.rs:16:5
+  --> $DIR/private-inferred-type-3.rs:8:5
    |
 LL |     ext::m!();
    |     ^^^^^^^^^ private type
@@ -7,7 +7,7 @@ LL |     ext::m!();
    = note: this error originates in the macro `ext::m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: static `ext::PRIV_STATIC` is private
-  --> $DIR/private-inferred-type-3.rs:16:5
+  --> $DIR/private-inferred-type-3.rs:8:5
    |
 LL |     ext::m!();
    |     ^^^^^^^^^ private static
@@ -15,7 +15,7 @@ LL |     ext::m!();
    = note: this error originates in the macro `ext::m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: type `ext::PrivEnum` is private
-  --> $DIR/private-inferred-type-3.rs:16:5
+  --> $DIR/private-inferred-type-3.rs:8:5
    |
 LL |     ext::m!();
    |     ^^^^^^^^^ private type
@@ -23,7 +23,7 @@ LL |     ext::m!();
    = note: this error originates in the macro `ext::m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: type `fn() {<u8 as ext::PrivTrait>::method}` is private
-  --> $DIR/private-inferred-type-3.rs:16:5
+  --> $DIR/private-inferred-type-3.rs:8:5
    |
 LL |     ext::m!();
    |     ^^^^^^^^^ private type
@@ -31,7 +31,7 @@ LL |     ext::m!();
    = note: this error originates in the macro `ext::m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private
-  --> $DIR/private-inferred-type-3.rs:16:5
+  --> $DIR/private-inferred-type-3.rs:8:5
    |
 LL |     ext::m!();
    |     ^^^^^^^^^ private type
@@ -39,7 +39,7 @@ LL |     ext::m!();
    = note: this error originates in the macro `ext::m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: type `fn(u8) -> PubTupleStruct {PubTupleStruct}` is private
-  --> $DIR/private-inferred-type-3.rs:16:5
+  --> $DIR/private-inferred-type-3.rs:8:5
    |
 LL |     ext::m!();
    |     ^^^^^^^^^ private type
@@ -47,7 +47,7 @@ LL |     ext::m!();
    = note: this error originates in the macro `ext::m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: type `for<'a> fn(&'a Pub<u8>) {Pub::<u8>::priv_method}` is private
-  --> $DIR/private-inferred-type-3.rs:16:5
+  --> $DIR/private-inferred-type-3.rs:8:5
    |
 LL |     ext::m!();
    |     ^^^^^^^^^ private type
diff --git a/tests/ui/proc-macro/export-macro.rs b/tests/ui/proc-macro/export-macro.rs
index e6001d06f0f..33bf8cfb255 100644
--- a/tests/ui/proc-macro/export-macro.rs
+++ b/tests/ui/proc-macro/export-macro.rs
@@ -1,11 +1,9 @@
-//@ error-pattern: cannot export macro_rules! macros from a `proc-macro` crate
-
 //@ force-host
 //@ no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
 
 #[macro_export]
-macro_rules! foo {
+macro_rules! foo { //~ ERROR cannot export macro_rules! macros from a `proc-macro` crate type
     ($e:expr) => ($e)
 }
diff --git a/tests/ui/proc-macro/export-macro.stderr b/tests/ui/proc-macro/export-macro.stderr
index 410770eca08..be586d50459 100644
--- a/tests/ui/proc-macro/export-macro.stderr
+++ b/tests/ui/proc-macro/export-macro.stderr
@@ -1,5 +1,5 @@
 error: cannot export macro_rules! macros from a `proc-macro` crate type currently
-  --> $DIR/export-macro.rs:9:1
+  --> $DIR/export-macro.rs:7:1
    |
 LL | macro_rules! foo {
    | ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs
index 6afafb7114a..df236cce6d2 100644
--- a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs
+++ b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs
@@ -4,8 +4,10 @@
 //@ edition:2018
 //@ proc-macro: issue-59191.rs
 //@ needs-unwind (affects error output)
-//@ error-pattern: error: `#[panic_handler]` function required
 
 #![feature(custom_inner_attributes)]
 #![issue_59191::no_main]
 #![issue_59191::no_main]
+
+//~? ERROR `#[panic_handler]` function required, but not found
+//~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/proc-macro/macro-rules-derive-cfg.stdout b/tests/ui/proc-macro/macro-rules-derive-cfg.stdout
index c1e46b50d40..9482b2784d2 100644
--- a/tests/ui/proc-macro/macro-rules-derive-cfg.stdout
+++ b/tests/ui/proc-macro/macro-rules-derive-cfg.stdout
@@ -1,8 +1,9 @@
 PRINT-DERIVE INPUT (DISPLAY): struct
-Foo([bool; #[rustc_dummy(first)] #[rustc_dummy(second)]
-{ #![rustc_dummy(third)] #[rustc_dummy(fourth)] 30 }]);
+Foo([bool; #[rustc_dummy(first)]
+#[rustc_dummy(second)] { #![rustc_dummy(third)] #[rustc_dummy(fourth)] 30 }]);
 PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct
-Foo([bool; #[rustc_dummy(first)] #[rustc_dummy(second)]
+Foo([bool; #[rustc_dummy(first)]
+#[rustc_dummy(second)]
 { #! [rustc_dummy(third)] #[rustc_dummy(fourth)] 30 }]);
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
@@ -53,97 +54,103 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
                         ],
                         span: $DIR/macro-rules-derive-cfg.rs:18:21: 18:63 (#3),
                     },
-                    Punct {
-                        ch: '#',
-                        spacing: Alone,
-                        span: $DIR/macro-rules-derive-cfg.rs:23:13: 23:14 (#0),
-                    },
                     Group {
-                        delimiter: Bracket,
-                        stream: TokenStream [
-                            Ident {
-                                ident: "rustc_dummy",
-                                span: $DIR/macro-rules-derive-cfg.rs:23:36: 23:47 (#0),
-                            },
-                            Group {
-                                delimiter: Parenthesis,
-                                stream: TokenStream [
-                                    Ident {
-                                        ident: "second",
-                                        span: $DIR/macro-rules-derive-cfg.rs:23:48: 23:54 (#0),
-                                    },
-                                ],
-                                span: $DIR/macro-rules-derive-cfg.rs:23:47: 23:55 (#0),
-                            },
-                        ],
-                        span: $DIR/macro-rules-derive-cfg.rs:23:14: 23:57 (#0),
-                    },
-                    Group {
-                        delimiter: Brace,
+                        delimiter: None,
                         stream: TokenStream [
                             Punct {
                                 ch: '#',
-                                spacing: Joint,
-                                span: $DIR/macro-rules-derive-cfg.rs:24:5: 24:6 (#0),
-                            },
-                            Punct {
-                                ch: '!',
                                 spacing: Alone,
-                                span: $DIR/macro-rules-derive-cfg.rs:24:6: 24:7 (#0),
+                                span: $DIR/macro-rules-derive-cfg.rs:23:13: 23:14 (#0),
                             },
                             Group {
                                 delimiter: Bracket,
                                 stream: TokenStream [
                                     Ident {
                                         ident: "rustc_dummy",
-                                        span: $DIR/macro-rules-derive-cfg.rs:24:29: 24:40 (#0),
+                                        span: $DIR/macro-rules-derive-cfg.rs:23:36: 23:47 (#0),
                                     },
                                     Group {
                                         delimiter: Parenthesis,
                                         stream: TokenStream [
                                             Ident {
-                                                ident: "third",
-                                                span: $DIR/macro-rules-derive-cfg.rs:24:41: 24:46 (#0),
+                                                ident: "second",
+                                                span: $DIR/macro-rules-derive-cfg.rs:23:48: 23:54 (#0),
                                             },
                                         ],
-                                        span: $DIR/macro-rules-derive-cfg.rs:24:40: 24:47 (#0),
+                                        span: $DIR/macro-rules-derive-cfg.rs:23:47: 23:55 (#0),
                                     },
                                 ],
-                                span: $DIR/macro-rules-derive-cfg.rs:24:7: 24:49 (#0),
-                            },
-                            Punct {
-                                ch: '#',
-                                spacing: Alone,
-                                span: $DIR/macro-rules-derive-cfg.rs:25:5: 25:6 (#0),
+                                span: $DIR/macro-rules-derive-cfg.rs:23:14: 23:57 (#0),
                             },
                             Group {
-                                delimiter: Bracket,
+                                delimiter: Brace,
                                 stream: TokenStream [
-                                    Ident {
-                                        ident: "rustc_dummy",
-                                        span: $DIR/macro-rules-derive-cfg.rs:25:28: 25:39 (#0),
+                                    Punct {
+                                        ch: '#',
+                                        spacing: Joint,
+                                        span: $DIR/macro-rules-derive-cfg.rs:24:5: 24:6 (#0),
+                                    },
+                                    Punct {
+                                        ch: '!',
+                                        spacing: Alone,
+                                        span: $DIR/macro-rules-derive-cfg.rs:24:6: 24:7 (#0),
                                     },
                                     Group {
-                                        delimiter: Parenthesis,
+                                        delimiter: Bracket,
+                                        stream: TokenStream [
+                                            Ident {
+                                                ident: "rustc_dummy",
+                                                span: $DIR/macro-rules-derive-cfg.rs:24:29: 24:40 (#0),
+                                            },
+                                            Group {
+                                                delimiter: Parenthesis,
+                                                stream: TokenStream [
+                                                    Ident {
+                                                        ident: "third",
+                                                        span: $DIR/macro-rules-derive-cfg.rs:24:41: 24:46 (#0),
+                                                    },
+                                                ],
+                                                span: $DIR/macro-rules-derive-cfg.rs:24:40: 24:47 (#0),
+                                            },
+                                        ],
+                                        span: $DIR/macro-rules-derive-cfg.rs:24:7: 24:49 (#0),
+                                    },
+                                    Punct {
+                                        ch: '#',
+                                        spacing: Alone,
+                                        span: $DIR/macro-rules-derive-cfg.rs:25:5: 25:6 (#0),
+                                    },
+                                    Group {
+                                        delimiter: Bracket,
                                         stream: TokenStream [
                                             Ident {
-                                                ident: "fourth",
-                                                span: $DIR/macro-rules-derive-cfg.rs:25:40: 25:46 (#0),
+                                                ident: "rustc_dummy",
+                                                span: $DIR/macro-rules-derive-cfg.rs:25:28: 25:39 (#0),
+                                            },
+                                            Group {
+                                                delimiter: Parenthesis,
+                                                stream: TokenStream [
+                                                    Ident {
+                                                        ident: "fourth",
+                                                        span: $DIR/macro-rules-derive-cfg.rs:25:40: 25:46 (#0),
+                                                    },
+                                                ],
+                                                span: $DIR/macro-rules-derive-cfg.rs:25:39: 25:47 (#0),
                                             },
                                         ],
-                                        span: $DIR/macro-rules-derive-cfg.rs:25:39: 25:47 (#0),
+                                        span: $DIR/macro-rules-derive-cfg.rs:25:6: 25:49 (#0),
+                                    },
+                                    Literal {
+                                        kind: Integer,
+                                        symbol: "30",
+                                        suffix: None,
+                                        span: $DIR/macro-rules-derive-cfg.rs:26:5: 26:7 (#0),
                                     },
                                 ],
-                                span: $DIR/macro-rules-derive-cfg.rs:25:6: 25:49 (#0),
-                            },
-                            Literal {
-                                kind: Integer,
-                                symbol: "30",
-                                suffix: None,
-                                span: $DIR/macro-rules-derive-cfg.rs:26:5: 26:7 (#0),
+                                span: $DIR/macro-rules-derive-cfg.rs:23:58: 27:2 (#0),
                             },
                         ],
-                        span: $DIR/macro-rules-derive-cfg.rs:23:58: 27:2 (#0),
+                        span: $DIR/macro-rules-derive-cfg.rs:18:64: 18:69 (#3),
                     },
                 ],
                 span: $DIR/macro-rules-derive-cfg.rs:18:13: 18:70 (#3),
diff --git a/tests/ui/proc-macro/no-macro-use-attr.rs b/tests/ui/proc-macro/no-macro-use-attr.rs
index d44f51bfd8d..25200378131 100644
--- a/tests/ui/proc-macro/no-macro-use-attr.rs
+++ b/tests/ui/proc-macro/no-macro-use-attr.rs
@@ -1,10 +1,9 @@
+//@ check-pass
 //@ proc-macro: test-macros.rs
 
-#![feature(rustc_attrs)]
 #![warn(unused_extern_crates)]
 
 extern crate test_macros;
 //~^ WARN unused extern crate
 
-#[rustc_error]
-fn main() {} //~ ERROR fatal error triggered by #[rustc_error]
+fn main() {}
diff --git a/tests/ui/proc-macro/no-macro-use-attr.stderr b/tests/ui/proc-macro/no-macro-use-attr.stderr
index 3dda3cc7d5a..4913672450a 100644
--- a/tests/ui/proc-macro/no-macro-use-attr.stderr
+++ b/tests/ui/proc-macro/no-macro-use-attr.stderr
@@ -10,11 +10,5 @@ note: the lint level is defined here
 LL | #![warn(unused_extern_crates)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/no-macro-use-attr.rs:10:1
-   |
-LL | fn main() {}
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error; 1 warning emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
index c80a33206fb..6fd6cb47469 100644
--- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
+++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
@@ -5,19 +5,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
         stream: TokenStream [
             Ident {
                 ident: "struct",
-                span: $DIR/nonterminal-token-hygiene.rs:32:5: 32:11 (#4),
+                span: $DIR/nonterminal-token-hygiene.rs:32:5: 32:11 (#5),
             },
             Ident {
                 ident: "S",
-                span: $DIR/nonterminal-token-hygiene.rs:32:12: 32:13 (#4),
+                span: $DIR/nonterminal-token-hygiene.rs:32:12: 32:13 (#5),
             },
             Punct {
                 ch: ';',
                 spacing: Alone,
-                span: $DIR/nonterminal-token-hygiene.rs:32:13: 32:14 (#4),
+                span: $DIR/nonterminal-token-hygiene.rs:32:13: 32:14 (#5),
             },
         ],
-        span: $DIR/nonterminal-token-hygiene.rs:22:27: 22:32 (#5),
+        span: $DIR/nonterminal-token-hygiene.rs:22:27: 22:32 (#4),
     },
 ]
 #![feature /* 0#0 */(prelude_import)]
@@ -59,7 +59,7 @@ macro_rules! outer
 struct S /* 0#0 */;
 macro inner /* 0#3 */ { () => { print_bang! { struct S; } } }
 
-struct S /* 0#4 */;
+struct S /* 0#5 */;
 // OK, not a duplicate definition of `S`
 
 fn main /* 0#0 */() {}
@@ -70,7 +70,7 @@ crate0::{{expn0}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt:
 crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
 crate0::{{expn2}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "outer")
 crate0::{{expn3}}: parent: crate0::{{expn2}}, call_site_ctxt: #3, def_site_ctxt: #3, kind: Macro(Bang, "inner")
-crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #5, def_site_ctxt: #0, kind: Macro(Bang, "print_bang")
+crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #4, def_site_ctxt: #0, kind: Macro(Bang, "print_bang")
 crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented")
 crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented")
 crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented")
@@ -83,9 +83,9 @@ SyntaxContexts:
 #1: parent: #0, outer_mark: (crate0::{{expn1}}, Opaque)
 #2: parent: #0, outer_mark: (crate0::{{expn1}}, Transparent)
 #3: parent: #0, outer_mark: (crate0::{{expn2}}, SemiTransparent)
-#4: parent: #0, outer_mark: (crate0::{{expn3}}, Opaque)
-#5: parent: #3, outer_mark: (crate0::{{expn3}}, Opaque)
+#4: parent: #3, outer_mark: (crate0::{{expn3}}, Opaque)
+#5: parent: #0, outer_mark: (crate0::{{expn3}}, Opaque)
 #6: parent: #0, outer_mark: (crate0::{{expn4}}, Opaque)
-#7: parent: #5, outer_mark: (crate0::{{expn4}}, Transparent)
-#8: parent: #4, outer_mark: (crate0::{{expn4}}, SemiTransparent)
+#7: parent: #4, outer_mark: (crate0::{{expn4}}, Transparent)
+#8: parent: #5, outer_mark: (crate0::{{expn4}}, SemiTransparent)
 */
diff --git a/tests/ui/proc-macro/panic-abort.rs b/tests/ui/proc-macro/panic-abort.rs
index 40d8aec5ef6..58e1d006433 100644
--- a/tests/ui/proc-macro/panic-abort.rs
+++ b/tests/ui/proc-macro/panic-abort.rs
@@ -1,4 +1,5 @@
-//@ error-pattern: building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
 //@ compile-flags: --crate-type proc-macro -Cpanic=abort
 //@ force-host
 //@ check-pass
+
+//~? WARN building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
diff --git a/tests/ui/proc-macro/two-crate-types-1.rs b/tests/ui/proc-macro/two-crate-types-1.rs
index 432b0a601b2..9d21a430537 100644
--- a/tests/ui/proc-macro/two-crate-types-1.rs
+++ b/tests/ui/proc-macro/two-crate-types-1.rs
@@ -1,7 +1,7 @@
-//@ error-pattern: cannot mix `proc-macro` crate type with others
-
 //@ force-host
 //@ no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
 #![crate_type = "rlib"]
+
+//~? ERROR cannot mix `proc-macro` crate type with others
diff --git a/tests/ui/proc-macro/two-crate-types-2.rs b/tests/ui/proc-macro/two-crate-types-2.rs
index 491c5c71d76..c4cc0b4d80d 100644
--- a/tests/ui/proc-macro/two-crate-types-2.rs
+++ b/tests/ui/proc-macro/two-crate-types-2.rs
@@ -1,3 +1,4 @@
-//@ error-pattern: cannot mix `proc-macro` crate type with others
 //@ compile-flags: --crate-type rlib --crate-type proc-macro
 //@ force-host
+
+//~? ERROR cannot mix `proc-macro` crate type with others
diff --git a/tests/ui/reachable/unreachable-code-ret.rs b/tests/ui/reachable/unreachable-code-ret.rs
index ed9fbd5c5a2..746c4d53e7b 100644
--- a/tests/ui/reachable/unreachable-code-ret.rs
+++ b/tests/ui/reachable/unreachable-code-ret.rs
@@ -1,8 +1,6 @@
-//@ error-pattern: unreachable statement
-
 #![deny(unreachable_code)]
 
 fn main() {
     return;
-    println!("Paul is dead");
+    println!("Paul is dead"); //~ ERROR unreachable statement
 }
diff --git a/tests/ui/reachable/unreachable-code-ret.stderr b/tests/ui/reachable/unreachable-code-ret.stderr
index 824515a2271..d86def536df 100644
--- a/tests/ui/reachable/unreachable-code-ret.stderr
+++ b/tests/ui/reachable/unreachable-code-ret.stderr
@@ -1,5 +1,5 @@
 error: unreachable statement
-  --> $DIR/unreachable-code-ret.rs:7:5
+  --> $DIR/unreachable-code-ret.rs:5:5
    |
 LL |     return;
    |     ------ any code following this expression is unreachable
@@ -7,7 +7,7 @@ LL |     println!("Paul is dead");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: the lint level is defined here
-  --> $DIR/unreachable-code-ret.rs:3:9
+  --> $DIR/unreachable-code-ret.rs:1:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/resolve/auxiliary/macro_helpers.rs b/tests/ui/resolve/auxiliary/macro_helpers.rs
new file mode 100644
index 00000000000..43aa336457d
--- /dev/null
+++ b/tests/ui/resolve/auxiliary/macro_helpers.rs
@@ -0,0 +1,16 @@
+/* macro namespace. */
+
+extern crate proc_macro;
+use proc_macro::*;
+use std::str::FromStr;
+
+const ERROR: &str = "fn helper() { \"helper\" }";
+// https://doc.rust-lang.org/nightly/std/prelude/v1/index.html#attributes
+// NOTE: all the bang macros in std are currently unstable.
+#[proc_macro_attribute] pub fn test       // lang.
+    (_: TokenStream, _: TokenStream) -> TokenStream {
+        TokenStream::from_str("fn test_macro() { \"\" }").unwrap() }
+// https://doc.rust-lang.org/nightly/reference/attributes.html#built-in-attributes-index
+#[proc_macro_attribute] pub fn global_allocator // lang.
+    (_: TokenStream, _: TokenStream) -> TokenStream {
+        TokenStream::from_str("fn global_allocator_macro() { \"\" }").unwrap() }
diff --git a/tests/ui/resolve/bad-env-capture.rs b/tests/ui/resolve/bad-env-capture.rs
index ccd98b6ef06..a0efe88e2a9 100644
--- a/tests/ui/resolve/bad-env-capture.rs
+++ b/tests/ui/resolve/bad-env-capture.rs
@@ -1,6 +1,8 @@
-//@ error-pattern: can't capture dynamic environment in a fn item
 fn foo() {
     let x: isize;
     fn bar() { log(debug, x); }
+    //~^ ERROR can't capture dynamic environment in a fn item
+    //~| ERROR cannot find value `debug` in this scope
+    //~| ERROR cannot find function `log` in this scope
 }
 fn main() { foo(); }
diff --git a/tests/ui/resolve/bad-env-capture.stderr b/tests/ui/resolve/bad-env-capture.stderr
index 59b1fabfd7c..a3a15ca245b 100644
--- a/tests/ui/resolve/bad-env-capture.stderr
+++ b/tests/ui/resolve/bad-env-capture.stderr
@@ -1,5 +1,5 @@
 error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/bad-env-capture.rs:4:27
+  --> $DIR/bad-env-capture.rs:3:27
    |
 LL |     fn bar() { log(debug, x); }
    |                           ^
@@ -7,13 +7,13 @@ LL |     fn bar() { log(debug, x); }
    = help: use the `|| { ... }` closure form instead
 
 error[E0425]: cannot find value `debug` in this scope
-  --> $DIR/bad-env-capture.rs:4:20
+  --> $DIR/bad-env-capture.rs:3:20
    |
 LL |     fn bar() { log(debug, x); }
    |                    ^^^^^ not found in this scope
 
 error[E0425]: cannot find function `log` in this scope
-  --> $DIR/bad-env-capture.rs:4:16
+  --> $DIR/bad-env-capture.rs:3:16
    |
 LL |     fn bar() { log(debug, x); }
    |                ^^^ not found in this scope
diff --git a/tests/ui/resolve/bad-env-capture2.rs b/tests/ui/resolve/bad-env-capture2.rs
index 84d1832be60..8298e6fcd24 100644
--- a/tests/ui/resolve/bad-env-capture2.rs
+++ b/tests/ui/resolve/bad-env-capture2.rs
@@ -1,5 +1,7 @@
-//@ error-pattern: can't capture dynamic environment in a fn item
 fn foo(x: isize) {
     fn bar() { log(debug, x); }
+    //~^ ERROR can't capture dynamic environment in a fn item
+    //~| ERROR cannot find value `debug` in this scope
+    //~| ERROR cannot find function `log` in this scope
 }
 fn main() { foo(2); }
diff --git a/tests/ui/resolve/bad-env-capture2.stderr b/tests/ui/resolve/bad-env-capture2.stderr
index 811c259de6b..403fe2d32b9 100644
--- a/tests/ui/resolve/bad-env-capture2.stderr
+++ b/tests/ui/resolve/bad-env-capture2.stderr
@@ -1,5 +1,5 @@
 error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/bad-env-capture2.rs:3:27
+  --> $DIR/bad-env-capture2.rs:2:27
    |
 LL |     fn bar() { log(debug, x); }
    |                           ^
@@ -7,13 +7,13 @@ LL |     fn bar() { log(debug, x); }
    = help: use the `|| { ... }` closure form instead
 
 error[E0425]: cannot find value `debug` in this scope
-  --> $DIR/bad-env-capture2.rs:3:20
+  --> $DIR/bad-env-capture2.rs:2:20
    |
 LL |     fn bar() { log(debug, x); }
    |                    ^^^^^ not found in this scope
 
 error[E0425]: cannot find function `log` in this scope
-  --> $DIR/bad-env-capture2.rs:3:16
+  --> $DIR/bad-env-capture2.rs:2:16
    |
 LL |     fn bar() { log(debug, x); }
    |                ^^^ not found in this scope
diff --git a/tests/ui/resolve/bad-env-capture3.rs b/tests/ui/resolve/bad-env-capture3.rs
index 849b84cb1ab..8f5440d3339 100644
--- a/tests/ui/resolve/bad-env-capture3.rs
+++ b/tests/ui/resolve/bad-env-capture3.rs
@@ -1,7 +1,9 @@
-//@ error-pattern: can't capture dynamic environment in a fn item
 fn foo(x: isize) {
     fn mth() {
         fn bar() { log(debug, x); }
+        //~^ ERROR can't capture dynamic environment in a fn item
+        //~| ERROR cannot find value `debug` in this scope
+        //~| ERROR cannot find function `log` in this scope
     }
 }
 
diff --git a/tests/ui/resolve/bad-env-capture3.stderr b/tests/ui/resolve/bad-env-capture3.stderr
index eab37fde96e..962eb72ee68 100644
--- a/tests/ui/resolve/bad-env-capture3.stderr
+++ b/tests/ui/resolve/bad-env-capture3.stderr
@@ -1,5 +1,5 @@
 error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/bad-env-capture3.rs:4:31
+  --> $DIR/bad-env-capture3.rs:3:31
    |
 LL |         fn bar() { log(debug, x); }
    |                               ^
@@ -7,13 +7,13 @@ LL |         fn bar() { log(debug, x); }
    = help: use the `|| { ... }` closure form instead
 
 error[E0425]: cannot find value `debug` in this scope
-  --> $DIR/bad-env-capture3.rs:4:24
+  --> $DIR/bad-env-capture3.rs:3:24
    |
 LL |         fn bar() { log(debug, x); }
    |                        ^^^^^ not found in this scope
 
 error[E0425]: cannot find function `log` in this scope
-  --> $DIR/bad-env-capture3.rs:4:20
+  --> $DIR/bad-env-capture3.rs:3:20
    |
 LL |         fn bar() { log(debug, x); }
    |                    ^^^ not found in this scope
diff --git a/tests/ui/resolve/issue-21221-1.stderr b/tests/ui/resolve/issue-21221-1.stderr
index ccf03afaa19..dafa41bf312 100644
--- a/tests/ui/resolve/issue-21221-1.stderr
+++ b/tests/ui/resolve/issue-21221-1.stderr
@@ -19,6 +19,17 @@ error[E0412]: cannot find type `Mul` in this scope
 LL | fn getMul() -> Mul {
    |                ^^^ not found in this scope
    |
+note: these items exist but are inaccessible
+  --> $DIR/issue-21221-1.rs:10:5
+   |
+LL |     enum Mul {
+   |     ^^^^^^^^ `mul3::Mul`: not accessible
+...
+LL |     type Mul = String;
+   |     ^^^^^^^^^^^^^^^^^^ `mul4::Mul`: not accessible
+...
+LL |     struct Mul{
+   |     ^^^^^^^^^^ `mul5::Mul`: not accessible
 help: consider importing one of these traits
    |
 LL + use std::ops::Mul;
diff --git a/tests/ui/resolve/prelude-order.rs b/tests/ui/resolve/prelude-order.rs
new file mode 100644
index 00000000000..a3f194270d4
--- /dev/null
+++ b/tests/ui/resolve/prelude-order.rs
@@ -0,0 +1,89 @@
+//@ proc-macro:macro_helpers.rs
+//@ compile-flags: --crate-type=lib
+
+/* There are 5 preludes and 3 namespaces. Test the order in which they are resolved.
+ * See https://doc.rust-lang.org/nightly/reference/names/preludes.html.
+ *
+ * Macros cannot be in the type or value namespace.
+ * Tools and extern crates cannot be in the macro or value namespace.
+ *
+ * Test the following truth tables:
+
+Type:
+| ...... |  tool  | extern | macro  | lang   | libs |
+|   tool |    N/A |                   mirror
+| extern | extern |    N/A |             universe
+|  macro |    N/A |    N/A |    N/A |
+|   lang |   tool | extern |    N/A |   N/A  |
+|   libs |   tool | extern |    N/A |   X    |  N/A |
+
+Macro:
+| ...... |  tool  | extern | macro  | lang   | libs |
+|   tool |    N/A |                   mirror
+| extern |    N/A |    N/A |             universe
+|  macro |    N/A |    N/A |    N/A |
+|   lang |    N/A |    N/A |  macro |   N/A  |
+|   libs |    N/A |    N/A |  macro |   X    | N/A  |
+
+Value: N/A. Only libs has items in the value namespace.
+
+† ambiguous
+X don't care (controlled namespace with no overlap)
+
+* Types are tested with `#[name::inner]`. Macros are tested with `#[name]`.
+* WARNING: I have found in testing that attribute macros give ambiguity errors in some contexts
+* instead of choosing a prelude. Have not been able to replicate.
+*
+* There should be 7 total tests.
+* See `rustc_resolve::ident::visit_scopes` for more information,
+* and for a definition of "controlled namespace".
+*/
+
+#![feature(register_tool)]
+
+/* tool prelude */
+#![register_tool(type_ns)] // extern prelude. type.
+#![register_tool(i8)]      // lang   prelude. type.
+#![register_tool(Sync)]    // libs   prelude. type.
+
+/* extern prelude */
+extern crate macro_helpers as type_ns; // tool prelude. type.
+extern crate macro_helpers as usize;   // lang prelude. type.
+extern crate macro_helpers as Option;  // libs prelude. type.
+
+/* macro_use prelude */
+#[macro_use]
+extern crate macro_helpers as _;
+
+/* lang and libs implicitly in scope */
+
+// tool/extern -> extern
+#[type_ns::inner] //~ ERROR could not find `inner` in `type_ns`
+fn t1() {}
+
+// tool/lang -> tool
+#[i8::inner] // ok
+fn t2() {}
+
+// tool/libs -> tool
+#[Sync::not_real] // ok
+fn t3() {}
+
+// extern/lang -> extern
+#[usize::inner] //~ ERROR could not find `inner` in `usize`
+fn e1() {} // NOTE: testing with `-> usize` isn't valid, crates aren't considered in that scope
+           // (unless they have generic arguments, for some reason.)
+
+// extern/libs -> extern
+// https://github.com/rust-lang/rust/issues/139095
+fn e2() -> Option<i32> { None } //~ ERROR: expected type, found crate
+
+// macro/libs -> macro
+#[test] //~ ERROR mismatched types
+fn m1() {}
+
+// macro/lang -> macro
+#[global_allocator] //~ ERROR mismatched types
+fn m2() {}
+
+// lang/libs: no items that currently overlap, in either macro or type ns.
diff --git a/tests/ui/resolve/prelude-order.stderr b/tests/ui/resolve/prelude-order.stderr
new file mode 100644
index 00000000000..1b9cc94285a
--- /dev/null
+++ b/tests/ui/resolve/prelude-order.stderr
@@ -0,0 +1,47 @@
+error[E0433]: failed to resolve: could not find `inner` in `type_ns`
+  --> $DIR/prelude-order.rs:61:12
+   |
+LL | #[type_ns::inner]
+   |            ^^^^^ could not find `inner` in `type_ns`
+
+error[E0433]: failed to resolve: could not find `inner` in `usize`
+  --> $DIR/prelude-order.rs:73:10
+   |
+LL | #[usize::inner]
+   |          ^^^^^ could not find `inner` in `usize`
+
+error[E0573]: expected type, found crate `Option`
+  --> $DIR/prelude-order.rs:79:12
+   |
+LL | fn e2() -> Option<i32> { None }
+   |            ^^^^^^^^^^^ not a type
+   |
+help: consider importing this enum instead
+   |
+LL + use std::option::Option;
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/prelude-order.rs:82:1
+   |
+LL | #[test]
+   | ^^^^^^^- help: try adding a return type: `-> &'static str`
+   | |
+   | expected `()`, found `&str`
+   |
+   = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0308]: mismatched types
+  --> $DIR/prelude-order.rs:86:1
+   |
+LL | #[global_allocator]
+   | ^^^^^^^^^^^^^^^^^^^- help: try adding a return type: `-> &'static str`
+   | |
+   | expected `()`, found `&str`
+   |
+   = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0308, E0433, E0573.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/return/ret-non-nil.rs b/tests/ui/return/ret-non-nil.rs
index 1d039ffe18c..b9a53086b3c 100644
--- a/tests/ui/return/ret-non-nil.rs
+++ b/tests/ui/return/ret-non-nil.rs
@@ -1,7 +1,5 @@
-//@ error-pattern: `return;` in a function whose return type is not `()`
-
 fn f() { return; }
 
-fn g() -> isize { return; }
+fn g() -> isize { return; } //~ ERROR `return;` in a function whose return type is not `()`
 
 fn main() { f(); g(); }
diff --git a/tests/ui/return/ret-non-nil.stderr b/tests/ui/return/ret-non-nil.stderr
index 802900e61a3..44edecf501f 100644
--- a/tests/ui/return/ret-non-nil.stderr
+++ b/tests/ui/return/ret-non-nil.stderr
@@ -1,5 +1,5 @@
 error[E0069]: `return;` in a function whose return type is not `()`
-  --> $DIR/ret-non-nil.rs:5:19
+  --> $DIR/ret-non-nil.rs:3:19
    |
 LL | fn g() -> isize { return; }
    |           -----   ^^^^^^ return type is not `()`
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.no_gate.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.no_gate.stderr
index 08584349626..c5756269def 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.no_gate.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.no_gate.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature `structural_match`
-  --> $DIR/feature-gate.rs:29:6
+  --> $DIR/feature-gate.rs:27:6
    |
 LL | impl std::marker::StructuralPartialEq for Foo { }
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.rs
index 711b07fee3b..694081654d5 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.rs
@@ -3,11 +3,10 @@
 // used in a match.
 
 //@ revisions: with_gate no_gate
-
+//@[with_gate] check-pass
 // gate-test-structural_match
 
 #![allow(unused)]
-#![feature(rustc_attrs)]
 #![cfg_attr(with_gate, feature(structural_match))]
 
 
@@ -17,8 +16,7 @@ struct Foo {
 
 const FOO: Foo = Foo { x: 0 };
 
-#[rustc_error]
-fn main() { //[with_gate]~ ERROR fatal error triggered by #[rustc_error]
+fn main() {
     let y = Foo { x: 1 };
     match y {
         FOO => { }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.with_gate.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.with_gate.stderr
deleted file mode 100644
index 505b7d79cad..00000000000
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/feature-gate.with_gate.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/feature-gate.rs:21:1
-   |
-LL | fn main() {
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/rfcs/rfc-1717-dllimport/missing-link-attr.rs b/tests/ui/rfcs/rfc-1717-dllimport/missing-link-attr.rs
index d54b428bf22..9dc856959c0 100644
--- a/tests/ui/rfcs/rfc-1717-dllimport/missing-link-attr.rs
+++ b/tests/ui/rfcs/rfc-1717-dllimport/missing-link-attr.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: -l foo:bar
-//@ error-pattern: renaming of the library `foo` was specified
 
 #![crate_type = "lib"]
+
+//~? ERROR renaming of the library `foo` was specified
diff --git a/tests/ui/rfcs/rfc-1717-dllimport/multiple-renames.rs b/tests/ui/rfcs/rfc-1717-dllimport/multiple-renames.rs
index ec1a246245e..69132895510 100644
--- a/tests/ui/rfcs/rfc-1717-dllimport/multiple-renames.rs
+++ b/tests/ui/rfcs/rfc-1717-dllimport/multiple-renames.rs
@@ -1,7 +1,8 @@
 //@ compile-flags: -l foo:bar -l foo:baz
-//@ error-pattern: multiple renamings were specified for library
 
 #![crate_type = "lib"]
 
 #[link(name = "foo")]
 extern "C" {}
+
+//~? ERROR multiple renamings were specified for library `foo`
diff --git a/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.rs b/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.rs
index 2a13d22e22a..e1fec305932 100644
--- a/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.rs
+++ b/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -l dylib=foo:bar
-//@ error-pattern: overriding linking modifiers from command line is not supported
 
 #![feature(native_link_modifiers_as_needed)]
 
@@ -7,3 +6,4 @@
 
 #[link(name = "foo", kind = "dylib", modifiers = "-as-needed")]
 extern "C" {}
+//~^ ERROR overriding linking modifiers from command line is not supported
diff --git a/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.stderr b/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.stderr
index ce145689f90..84b197a9b98 100644
--- a/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.stderr
+++ b/tests/ui/rfcs/rfc-1717-dllimport/rename-modifiers.stderr
@@ -1,5 +1,5 @@
 error: overriding linking modifiers from command line is not supported
-  --> $DIR/rename-modifiers.rs:9:1
+  --> $DIR/rename-modifiers.rs:8:1
    |
 LL | extern "C" {}
    | ^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-1717-dllimport/rename-to-empty.rs b/tests/ui/rfcs/rfc-1717-dllimport/rename-to-empty.rs
index 39205a11dd7..6fee80f0294 100644
--- a/tests/ui/rfcs/rfc-1717-dllimport/rename-to-empty.rs
+++ b/tests/ui/rfcs/rfc-1717-dllimport/rename-to-empty.rs
@@ -1,7 +1,8 @@
 //@ compile-flags: -l foo:
-//@ error-pattern: an empty renaming target was specified for library
 
 #![crate_type = "lib"]
 
 #[link(name = "foo")]
 extern "C" {}
+
+//~? ERROR an empty renaming target was specified for library `foo`
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs
index 4b2fc4a03b6..110c03d0e54 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs
@@ -59,8 +59,10 @@ fn _macros() {
     }
     use_expr!((let 0 = 1 && 0 == 0));
     //~^ ERROR expected expression, found `let` statement
+    //~| ERROR expected expression, found `let` statement
     use_expr!((let 0 = 1));
     //~^ ERROR expected expression, found `let` statement
+    //~| ERROR expected expression, found `let` statement
     match () {
         #[cfg(FALSE)]
         () if let 0 = 1 => {}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr
index 1c710b04897..0997f0c81a0 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr
@@ -124,15 +124,33 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:62:16
+  --> $DIR/feature-gate.rs:60:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `let` statement
+  --> $DIR/feature-gate.rs:63:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/feature-gate.rs:63:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: no rules expected keyword `let`
-  --> $DIR/feature-gate.rs:70:15
+  --> $DIR/feature-gate.rs:72:15
    |
 LL |     macro_rules! use_expr {
    |     --------------------- when calling this macro
@@ -202,7 +220,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:66:12
+  --> $DIR/feature-gate.rs:68:12
    |
 LL |         () if let 0 = 1 => {}
    |            ^^^^^^^^^^^^
@@ -262,6 +280,6 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 23 previous errors
+error: aborting due to 25 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr
index db32b8c1de4..817e226bc45 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr
@@ -233,7 +233,7 @@ LL |     while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:99:9
+  --> $DIR/disallowed-positions.rs:103:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^^^^^^^
@@ -241,7 +241,7 @@ LL |     if &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:102:9
+  --> $DIR/disallowed-positions.rs:106:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^^^^^^^
@@ -249,7 +249,7 @@ LL |     if !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:104:9
+  --> $DIR/disallowed-positions.rs:108:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^^^^^^^
@@ -257,7 +257,7 @@ LL |     if *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:106:9
+  --> $DIR/disallowed-positions.rs:110:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^^^^^^^
@@ -265,7 +265,7 @@ LL |     if -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:114:9
+  --> $DIR/disallowed-positions.rs:118:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
@@ -273,20 +273,20 @@ LL |     if (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:117:16
+  --> $DIR/disallowed-positions.rs:121:16
    |
 LL |     if true || let 0 = 0 {}
    |                ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:117:13
+  --> $DIR/disallowed-positions.rs:121:13
    |
 LL |     if true || let 0 = 0 {}
    |             ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:119:17
+  --> $DIR/disallowed-positions.rs:123:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
@@ -294,7 +294,7 @@ LL |     if (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:121:25
+  --> $DIR/disallowed-positions.rs:125:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -302,7 +302,7 @@ LL |     if true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:123:25
+  --> $DIR/disallowed-positions.rs:127:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -310,7 +310,7 @@ LL |     if true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:127:12
+  --> $DIR/disallowed-positions.rs:131:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^
@@ -318,7 +318,7 @@ LL |     if x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:130:15
+  --> $DIR/disallowed-positions.rs:134:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
@@ -326,7 +326,7 @@ LL |     if true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:133:11
+  --> $DIR/disallowed-positions.rs:137:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
@@ -334,7 +334,7 @@ LL |     if ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:135:9
+  --> $DIR/disallowed-positions.rs:139:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
@@ -342,7 +342,7 @@ LL |     if (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:139:8
+  --> $DIR/disallowed-positions.rs:143:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,7 +350,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:142:8
+  --> $DIR/disallowed-positions.rs:146:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -358,7 +358,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:148:8
+  --> $DIR/disallowed-positions.rs:152:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -366,7 +366,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:154:8
+  --> $DIR/disallowed-positions.rs:158:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -374,7 +374,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:158:19
+  --> $DIR/disallowed-positions.rs:162:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^
@@ -382,7 +382,7 @@ LL |     if let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:161:15
+  --> $DIR/disallowed-positions.rs:165:15
    |
 LL |     if return let 0 = 0 {}
    |               ^^^
@@ -390,7 +390,7 @@ LL |     if return let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:164:21
+  --> $DIR/disallowed-positions.rs:168:21
    |
 LL |     loop { if break let 0 = 0 {} }
    |                     ^^^
@@ -398,7 +398,7 @@ LL |     loop { if break let 0 = 0 {} }
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:167:15
+  --> $DIR/disallowed-positions.rs:171:15
    |
 LL |     if (match let 0 = 0 { _ => { false } }) {}
    |               ^^^
@@ -406,7 +406,7 @@ LL |     if (match let 0 = 0 { _ => { false } }) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:170:9
+  --> $DIR/disallowed-positions.rs:174:9
    |
 LL |     if (let 0 = 0, false).1 {}
    |         ^^^^^^^^^
@@ -414,7 +414,7 @@ LL |     if (let 0 = 0, false).1 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:173:9
+  --> $DIR/disallowed-positions.rs:177:9
    |
 LL |     if (let 0 = 0,) {}
    |         ^^^^^^^^^
@@ -422,7 +422,7 @@ LL |     if (let 0 = 0,) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:177:13
+  --> $DIR/disallowed-positions.rs:181:13
    |
 LL |         if (let 0 = 0).await {}
    |             ^^^^^^^^^
@@ -430,7 +430,7 @@ LL |         if (let 0 = 0).await {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:181:12
+  --> $DIR/disallowed-positions.rs:185:12
    |
 LL |     if (|| let 0 = 0) {}
    |            ^^^
@@ -438,7 +438,7 @@ LL |     if (|| let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:184:9
+  --> $DIR/disallowed-positions.rs:188:9
    |
 LL |     if (let 0 = 0)() {}
    |         ^^^^^^^^^
@@ -446,7 +446,7 @@ LL |     if (let 0 = 0)() {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:190:12
+  --> $DIR/disallowed-positions.rs:194:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -454,7 +454,7 @@ LL |     while &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:193:12
+  --> $DIR/disallowed-positions.rs:197:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -462,7 +462,7 @@ LL |     while !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:195:12
+  --> $DIR/disallowed-positions.rs:199:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -470,7 +470,7 @@ LL |     while *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:197:12
+  --> $DIR/disallowed-positions.rs:201:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -478,7 +478,7 @@ LL |     while -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:205:12
+  --> $DIR/disallowed-positions.rs:209:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
@@ -486,20 +486,20 @@ LL |     while (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:208:19
+  --> $DIR/disallowed-positions.rs:212:19
    |
 LL |     while true || let 0 = 0 {}
    |                   ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:208:16
+  --> $DIR/disallowed-positions.rs:212:16
    |
 LL |     while true || let 0 = 0 {}
    |                ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:210:20
+  --> $DIR/disallowed-positions.rs:214:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
@@ -507,7 +507,7 @@ LL |     while (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:212:28
+  --> $DIR/disallowed-positions.rs:216:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -515,7 +515,7 @@ LL |     while true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:214:28
+  --> $DIR/disallowed-positions.rs:218:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -523,7 +523,7 @@ LL |     while true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:218:15
+  --> $DIR/disallowed-positions.rs:222:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^
@@ -531,7 +531,7 @@ LL |     while x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:221:18
+  --> $DIR/disallowed-positions.rs:225:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
@@ -539,7 +539,7 @@ LL |     while true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:224:14
+  --> $DIR/disallowed-positions.rs:228:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
@@ -547,7 +547,7 @@ LL |     while ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:226:12
+  --> $DIR/disallowed-positions.rs:230:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
@@ -555,7 +555,7 @@ LL |     while (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:230:11
+  --> $DIR/disallowed-positions.rs:234:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -563,7 +563,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:233:11
+  --> $DIR/disallowed-positions.rs:237:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -571,7 +571,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:239:11
+  --> $DIR/disallowed-positions.rs:243:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -579,7 +579,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:245:11
+  --> $DIR/disallowed-positions.rs:249:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -587,7 +587,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:249:22
+  --> $DIR/disallowed-positions.rs:253:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^
@@ -595,7 +595,7 @@ LL |     while let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:252:18
+  --> $DIR/disallowed-positions.rs:256:18
    |
 LL |     while return let 0 = 0 {}
    |                  ^^^
@@ -603,7 +603,7 @@ LL |     while return let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:255:39
+  --> $DIR/disallowed-positions.rs:259:39
    |
 LL |     'outer: loop { while break 'outer let 0 = 0 {} }
    |                                       ^^^
@@ -611,7 +611,7 @@ LL |     'outer: loop { while break 'outer let 0 = 0 {} }
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:258:18
+  --> $DIR/disallowed-positions.rs:262:18
    |
 LL |     while (match let 0 = 0 { _ => { false } }) {}
    |                  ^^^
@@ -619,7 +619,7 @@ LL |     while (match let 0 = 0 { _ => { false } }) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:261:12
+  --> $DIR/disallowed-positions.rs:265:12
    |
 LL |     while (let 0 = 0, false).1 {}
    |            ^^^^^^^^^
@@ -627,7 +627,7 @@ LL |     while (let 0 = 0, false).1 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:264:12
+  --> $DIR/disallowed-positions.rs:268:12
    |
 LL |     while (let 0 = 0,) {}
    |            ^^^^^^^^^
@@ -635,7 +635,7 @@ LL |     while (let 0 = 0,) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:268:16
+  --> $DIR/disallowed-positions.rs:272:16
    |
 LL |         while (let 0 = 0).await {}
    |                ^^^^^^^^^
@@ -643,7 +643,7 @@ LL |         while (let 0 = 0).await {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:272:15
+  --> $DIR/disallowed-positions.rs:276:15
    |
 LL |     while (|| let 0 = 0) {}
    |               ^^^
@@ -651,7 +651,7 @@ LL |     while (|| let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:275:12
+  --> $DIR/disallowed-positions.rs:279:12
    |
 LL |     while (let 0 = 0)() {}
    |            ^^^^^^^^^
@@ -659,7 +659,7 @@ LL |     while (let 0 = 0)() {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:292:6
+  --> $DIR/disallowed-positions.rs:296:6
    |
 LL |     &let 0 = 0;
    |      ^^^
@@ -667,7 +667,7 @@ LL |     &let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:295:6
+  --> $DIR/disallowed-positions.rs:299:6
    |
 LL |     !let 0 = 0;
    |      ^^^
@@ -675,7 +675,7 @@ LL |     !let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:297:6
+  --> $DIR/disallowed-positions.rs:301:6
    |
 LL |     *let 0 = 0;
    |      ^^^
@@ -683,7 +683,7 @@ LL |     *let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:299:6
+  --> $DIR/disallowed-positions.rs:303:6
    |
 LL |     -let 0 = 0;
    |      ^^^
@@ -691,7 +691,7 @@ LL |     -let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:301:13
+  --> $DIR/disallowed-positions.rs:305:13
    |
 LL |     let _ = let _ = 3;
    |             ^^^
@@ -699,7 +699,7 @@ LL |     let _ = let _ = 3;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:309:6
+  --> $DIR/disallowed-positions.rs:313:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^
@@ -707,7 +707,7 @@ LL |     (let 0 = 0)?;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:312:13
+  --> $DIR/disallowed-positions.rs:316:13
    |
 LL |     true || let 0 = 0;
    |             ^^^
@@ -715,7 +715,7 @@ LL |     true || let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:314:14
+  --> $DIR/disallowed-positions.rs:318:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^
@@ -723,7 +723,7 @@ LL |     (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:316:22
+  --> $DIR/disallowed-positions.rs:320:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^
@@ -731,7 +731,7 @@ LL |     true && (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:320:9
+  --> $DIR/disallowed-positions.rs:324:9
    |
 LL |     x = let 0 = 0;
    |         ^^^
@@ -739,7 +739,7 @@ LL |     x = let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:323:12
+  --> $DIR/disallowed-positions.rs:327:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^
@@ -747,7 +747,7 @@ LL |     true..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:325:8
+  --> $DIR/disallowed-positions.rs:329:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^
@@ -755,7 +755,7 @@ LL |     ..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:327:6
+  --> $DIR/disallowed-positions.rs:331:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^
@@ -763,7 +763,7 @@ LL |     (let 0 = 0)..;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:330:6
+  --> $DIR/disallowed-positions.rs:334:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^
@@ -771,7 +771,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:334:6
+  --> $DIR/disallowed-positions.rs:338:6
    |
 LL |     (let true = let true = true);
    |      ^^^
@@ -779,7 +779,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:334:17
+  --> $DIR/disallowed-positions.rs:338:17
    |
 LL |     (let true = let true = true);
    |                 ^^^
@@ -787,7 +787,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:340:25
+  --> $DIR/disallowed-positions.rs:344:25
    |
 LL |         let x = true && let y = 1;
    |                         ^^^
@@ -795,7 +795,7 @@ LL |         let x = true && let y = 1;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:346:19
+  --> $DIR/disallowed-positions.rs:350:19
    |
 LL |         [1, 2, 3][let _ = ()]
    |                   ^^^
@@ -803,7 +803,7 @@ LL |         [1, 2, 3][let _ = ()]
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:351:6
+  --> $DIR/disallowed-positions.rs:355:6
    |
 LL |     &let 0 = 0
    |      ^^^
@@ -811,7 +811,7 @@ LL |     &let 0 = 0
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:362:17
+  --> $DIR/disallowed-positions.rs:366:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -819,7 +819,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:367:17
+  --> $DIR/disallowed-positions.rs:371:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -827,7 +827,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:372:17
+  --> $DIR/disallowed-positions.rs:376:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -835,7 +835,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:383:17
+  --> $DIR/disallowed-positions.rs:387:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -843,7 +843,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/disallowed-positions.rs:383:9
+  --> $DIR/disallowed-positions.rs:387:9
    |
 LL |         true && let 1 = 1
    |         ^^^^^^^^^^^^^^^^^
@@ -854,124 +854,124 @@ LL |         { true && let 1 = 1 }
    |         +                   +
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:393:9
+  --> $DIR/disallowed-positions.rs:397:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:393:9
+  --> $DIR/disallowed-positions.rs:397:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:397:9
+  --> $DIR/disallowed-positions.rs:401:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:397:9
+  --> $DIR/disallowed-positions.rs:401:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:400:9
+  --> $DIR/disallowed-positions.rs:404:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:400:9
+  --> $DIR/disallowed-positions.rs:404:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:400:32
+  --> $DIR/disallowed-positions.rs:404:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:400:32
+  --> $DIR/disallowed-positions.rs:404:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:408:9
+  --> $DIR/disallowed-positions.rs:412:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:408:9
+  --> $DIR/disallowed-positions.rs:412:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:408:31
+  --> $DIR/disallowed-positions.rs:412:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:408:31
+  --> $DIR/disallowed-positions.rs:412:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:412:9
+  --> $DIR/disallowed-positions.rs:416:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:412:9
+  --> $DIR/disallowed-positions.rs:416:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:412:31
+  --> $DIR/disallowed-positions.rs:416:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:412:31
+  --> $DIR/disallowed-positions.rs:416:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:416:9
+  --> $DIR/disallowed-positions.rs:420:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:416:9
+  --> $DIR/disallowed-positions.rs:420:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:436:22
+  --> $DIR/disallowed-positions.rs:440:22
    |
 LL |     let x = (true && let y = 1);
    |                      ^^^
@@ -979,7 +979,7 @@ LL |     let x = (true && let y = 1);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:441:20
+  --> $DIR/disallowed-positions.rs:445:20
    |
 LL |         ([1, 2, 3][let _ = ()])
    |                    ^^^
@@ -995,15 +995,51 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:93:16
+  --> $DIR/disallowed-positions.rs:91:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:91:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:95:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:95:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:95:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:130:8
+  --> $DIR/disallowed-positions.rs:134:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -1012,7 +1048,7 @@ LL |     if true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:139:12
+  --> $DIR/disallowed-positions.rs:143:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1023,7 +1059,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:142:12
+  --> $DIR/disallowed-positions.rs:146:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1034,7 +1070,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:148:12
+  --> $DIR/disallowed-positions.rs:152:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1045,7 +1081,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:154:12
+  --> $DIR/disallowed-positions.rs:158:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1056,7 +1092,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:110:20
+  --> $DIR/disallowed-positions.rs:114:20
    |
 LL |         if let 0 = 0? {}
    |                    ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1064,7 +1100,7 @@ LL |         if let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:221:11
+  --> $DIR/disallowed-positions.rs:225:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -1073,7 +1109,7 @@ LL |     while true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:230:15
+  --> $DIR/disallowed-positions.rs:234:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1084,7 +1120,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:233:15
+  --> $DIR/disallowed-positions.rs:237:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1095,7 +1131,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:239:15
+  --> $DIR/disallowed-positions.rs:243:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1106,7 +1142,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:245:15
+  --> $DIR/disallowed-positions.rs:249:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1117,7 +1153,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:201:23
+  --> $DIR/disallowed-positions.rs:205:23
    |
 LL |         while let 0 = 0? {}
    |                       ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1125,7 +1161,7 @@ LL |         while let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:330:10
+  --> $DIR/disallowed-positions.rs:334:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1136,14 +1172,14 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:305:17
+  --> $DIR/disallowed-positions.rs:309:17
    |
 LL |         let 0 = 0?;
    |                 ^^ the `?` operator cannot be applied to type `{integer}`
    |
    = help: the trait `Try` is not implemented for `{integer}`
 
-error: aborting due to 121 previous errors
+error: aborting due to 125 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr
index ad16a0f8ed8..bab50c22c03 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr
@@ -233,7 +233,7 @@ LL |     while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:99:9
+  --> $DIR/disallowed-positions.rs:103:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^^^^^^^
@@ -241,7 +241,7 @@ LL |     if &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:102:9
+  --> $DIR/disallowed-positions.rs:106:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^^^^^^^
@@ -249,7 +249,7 @@ LL |     if !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:104:9
+  --> $DIR/disallowed-positions.rs:108:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^^^^^^^
@@ -257,7 +257,7 @@ LL |     if *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:106:9
+  --> $DIR/disallowed-positions.rs:110:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^^^^^^^
@@ -265,7 +265,7 @@ LL |     if -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:114:9
+  --> $DIR/disallowed-positions.rs:118:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
@@ -273,20 +273,20 @@ LL |     if (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:117:16
+  --> $DIR/disallowed-positions.rs:121:16
    |
 LL |     if true || let 0 = 0 {}
    |                ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:117:13
+  --> $DIR/disallowed-positions.rs:121:13
    |
 LL |     if true || let 0 = 0 {}
    |             ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:119:17
+  --> $DIR/disallowed-positions.rs:123:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
@@ -294,7 +294,7 @@ LL |     if (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:121:25
+  --> $DIR/disallowed-positions.rs:125:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -302,7 +302,7 @@ LL |     if true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:123:25
+  --> $DIR/disallowed-positions.rs:127:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -310,7 +310,7 @@ LL |     if true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:127:12
+  --> $DIR/disallowed-positions.rs:131:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^
@@ -318,7 +318,7 @@ LL |     if x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:130:15
+  --> $DIR/disallowed-positions.rs:134:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
@@ -326,7 +326,7 @@ LL |     if true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:133:11
+  --> $DIR/disallowed-positions.rs:137:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
@@ -334,7 +334,7 @@ LL |     if ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:135:9
+  --> $DIR/disallowed-positions.rs:139:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
@@ -342,7 +342,7 @@ LL |     if (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:139:8
+  --> $DIR/disallowed-positions.rs:143:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,7 +350,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:142:8
+  --> $DIR/disallowed-positions.rs:146:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -358,7 +358,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:148:8
+  --> $DIR/disallowed-positions.rs:152:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -366,7 +366,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:154:8
+  --> $DIR/disallowed-positions.rs:158:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -374,7 +374,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:158:19
+  --> $DIR/disallowed-positions.rs:162:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^
@@ -382,7 +382,7 @@ LL |     if let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:161:15
+  --> $DIR/disallowed-positions.rs:165:15
    |
 LL |     if return let 0 = 0 {}
    |               ^^^
@@ -390,7 +390,7 @@ LL |     if return let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:164:21
+  --> $DIR/disallowed-positions.rs:168:21
    |
 LL |     loop { if break let 0 = 0 {} }
    |                     ^^^
@@ -398,7 +398,7 @@ LL |     loop { if break let 0 = 0 {} }
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:167:15
+  --> $DIR/disallowed-positions.rs:171:15
    |
 LL |     if (match let 0 = 0 { _ => { false } }) {}
    |               ^^^
@@ -406,7 +406,7 @@ LL |     if (match let 0 = 0 { _ => { false } }) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:170:9
+  --> $DIR/disallowed-positions.rs:174:9
    |
 LL |     if (let 0 = 0, false).1 {}
    |         ^^^^^^^^^
@@ -414,7 +414,7 @@ LL |     if (let 0 = 0, false).1 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:173:9
+  --> $DIR/disallowed-positions.rs:177:9
    |
 LL |     if (let 0 = 0,) {}
    |         ^^^^^^^^^
@@ -422,7 +422,7 @@ LL |     if (let 0 = 0,) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:177:13
+  --> $DIR/disallowed-positions.rs:181:13
    |
 LL |         if (let 0 = 0).await {}
    |             ^^^^^^^^^
@@ -430,7 +430,7 @@ LL |         if (let 0 = 0).await {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:181:12
+  --> $DIR/disallowed-positions.rs:185:12
    |
 LL |     if (|| let 0 = 0) {}
    |            ^^^
@@ -438,7 +438,7 @@ LL |     if (|| let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:184:9
+  --> $DIR/disallowed-positions.rs:188:9
    |
 LL |     if (let 0 = 0)() {}
    |         ^^^^^^^^^
@@ -446,7 +446,7 @@ LL |     if (let 0 = 0)() {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:190:12
+  --> $DIR/disallowed-positions.rs:194:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -454,7 +454,7 @@ LL |     while &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:193:12
+  --> $DIR/disallowed-positions.rs:197:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -462,7 +462,7 @@ LL |     while !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:195:12
+  --> $DIR/disallowed-positions.rs:199:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -470,7 +470,7 @@ LL |     while *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:197:12
+  --> $DIR/disallowed-positions.rs:201:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -478,7 +478,7 @@ LL |     while -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:205:12
+  --> $DIR/disallowed-positions.rs:209:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
@@ -486,20 +486,20 @@ LL |     while (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:208:19
+  --> $DIR/disallowed-positions.rs:212:19
    |
 LL |     while true || let 0 = 0 {}
    |                   ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:208:16
+  --> $DIR/disallowed-positions.rs:212:16
    |
 LL |     while true || let 0 = 0 {}
    |                ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:210:20
+  --> $DIR/disallowed-positions.rs:214:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
@@ -507,7 +507,7 @@ LL |     while (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:212:28
+  --> $DIR/disallowed-positions.rs:216:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -515,7 +515,7 @@ LL |     while true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:214:28
+  --> $DIR/disallowed-positions.rs:218:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -523,7 +523,7 @@ LL |     while true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:218:15
+  --> $DIR/disallowed-positions.rs:222:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^
@@ -531,7 +531,7 @@ LL |     while x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:221:18
+  --> $DIR/disallowed-positions.rs:225:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
@@ -539,7 +539,7 @@ LL |     while true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:224:14
+  --> $DIR/disallowed-positions.rs:228:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
@@ -547,7 +547,7 @@ LL |     while ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:226:12
+  --> $DIR/disallowed-positions.rs:230:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
@@ -555,7 +555,7 @@ LL |     while (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:230:11
+  --> $DIR/disallowed-positions.rs:234:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -563,7 +563,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:233:11
+  --> $DIR/disallowed-positions.rs:237:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -571,7 +571,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:239:11
+  --> $DIR/disallowed-positions.rs:243:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -579,7 +579,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:245:11
+  --> $DIR/disallowed-positions.rs:249:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -587,7 +587,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:249:22
+  --> $DIR/disallowed-positions.rs:253:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^
@@ -595,7 +595,7 @@ LL |     while let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:252:18
+  --> $DIR/disallowed-positions.rs:256:18
    |
 LL |     while return let 0 = 0 {}
    |                  ^^^
@@ -603,7 +603,7 @@ LL |     while return let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:255:39
+  --> $DIR/disallowed-positions.rs:259:39
    |
 LL |     'outer: loop { while break 'outer let 0 = 0 {} }
    |                                       ^^^
@@ -611,7 +611,7 @@ LL |     'outer: loop { while break 'outer let 0 = 0 {} }
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:258:18
+  --> $DIR/disallowed-positions.rs:262:18
    |
 LL |     while (match let 0 = 0 { _ => { false } }) {}
    |                  ^^^
@@ -619,7 +619,7 @@ LL |     while (match let 0 = 0 { _ => { false } }) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:261:12
+  --> $DIR/disallowed-positions.rs:265:12
    |
 LL |     while (let 0 = 0, false).1 {}
    |            ^^^^^^^^^
@@ -627,7 +627,7 @@ LL |     while (let 0 = 0, false).1 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:264:12
+  --> $DIR/disallowed-positions.rs:268:12
    |
 LL |     while (let 0 = 0,) {}
    |            ^^^^^^^^^
@@ -635,7 +635,7 @@ LL |     while (let 0 = 0,) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:268:16
+  --> $DIR/disallowed-positions.rs:272:16
    |
 LL |         while (let 0 = 0).await {}
    |                ^^^^^^^^^
@@ -643,7 +643,7 @@ LL |         while (let 0 = 0).await {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:272:15
+  --> $DIR/disallowed-positions.rs:276:15
    |
 LL |     while (|| let 0 = 0) {}
    |               ^^^
@@ -651,7 +651,7 @@ LL |     while (|| let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:275:12
+  --> $DIR/disallowed-positions.rs:279:12
    |
 LL |     while (let 0 = 0)() {}
    |            ^^^^^^^^^
@@ -659,7 +659,7 @@ LL |     while (let 0 = 0)() {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:292:6
+  --> $DIR/disallowed-positions.rs:296:6
    |
 LL |     &let 0 = 0;
    |      ^^^
@@ -667,7 +667,7 @@ LL |     &let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:295:6
+  --> $DIR/disallowed-positions.rs:299:6
    |
 LL |     !let 0 = 0;
    |      ^^^
@@ -675,7 +675,7 @@ LL |     !let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:297:6
+  --> $DIR/disallowed-positions.rs:301:6
    |
 LL |     *let 0 = 0;
    |      ^^^
@@ -683,7 +683,7 @@ LL |     *let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:299:6
+  --> $DIR/disallowed-positions.rs:303:6
    |
 LL |     -let 0 = 0;
    |      ^^^
@@ -691,7 +691,7 @@ LL |     -let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:301:13
+  --> $DIR/disallowed-positions.rs:305:13
    |
 LL |     let _ = let _ = 3;
    |             ^^^
@@ -699,7 +699,7 @@ LL |     let _ = let _ = 3;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:309:6
+  --> $DIR/disallowed-positions.rs:313:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^
@@ -707,7 +707,7 @@ LL |     (let 0 = 0)?;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:312:13
+  --> $DIR/disallowed-positions.rs:316:13
    |
 LL |     true || let 0 = 0;
    |             ^^^
@@ -715,7 +715,7 @@ LL |     true || let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:314:14
+  --> $DIR/disallowed-positions.rs:318:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^
@@ -723,7 +723,7 @@ LL |     (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:316:22
+  --> $DIR/disallowed-positions.rs:320:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^
@@ -731,7 +731,7 @@ LL |     true && (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:320:9
+  --> $DIR/disallowed-positions.rs:324:9
    |
 LL |     x = let 0 = 0;
    |         ^^^
@@ -739,7 +739,7 @@ LL |     x = let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:323:12
+  --> $DIR/disallowed-positions.rs:327:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^
@@ -747,7 +747,7 @@ LL |     true..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:325:8
+  --> $DIR/disallowed-positions.rs:329:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^
@@ -755,7 +755,7 @@ LL |     ..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:327:6
+  --> $DIR/disallowed-positions.rs:331:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^
@@ -763,7 +763,7 @@ LL |     (let 0 = 0)..;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:330:6
+  --> $DIR/disallowed-positions.rs:334:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^
@@ -771,7 +771,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:334:6
+  --> $DIR/disallowed-positions.rs:338:6
    |
 LL |     (let true = let true = true);
    |      ^^^
@@ -779,7 +779,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:334:17
+  --> $DIR/disallowed-positions.rs:338:17
    |
 LL |     (let true = let true = true);
    |                 ^^^
@@ -787,7 +787,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:340:25
+  --> $DIR/disallowed-positions.rs:344:25
    |
 LL |         let x = true && let y = 1;
    |                         ^^^
@@ -795,7 +795,7 @@ LL |         let x = true && let y = 1;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:346:19
+  --> $DIR/disallowed-positions.rs:350:19
    |
 LL |         [1, 2, 3][let _ = ()]
    |                   ^^^
@@ -803,7 +803,7 @@ LL |         [1, 2, 3][let _ = ()]
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:351:6
+  --> $DIR/disallowed-positions.rs:355:6
    |
 LL |     &let 0 = 0
    |      ^^^
@@ -811,7 +811,7 @@ LL |     &let 0 = 0
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:362:17
+  --> $DIR/disallowed-positions.rs:366:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -819,7 +819,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:367:17
+  --> $DIR/disallowed-positions.rs:371:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -827,7 +827,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:372:17
+  --> $DIR/disallowed-positions.rs:376:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -835,7 +835,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:383:17
+  --> $DIR/disallowed-positions.rs:387:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -843,7 +843,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/disallowed-positions.rs:383:9
+  --> $DIR/disallowed-positions.rs:387:9
    |
 LL |         true && let 1 = 1
    |         ^^^^^^^^^^^^^^^^^
@@ -854,124 +854,124 @@ LL |         { true && let 1 = 1 }
    |         +                   +
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:393:9
+  --> $DIR/disallowed-positions.rs:397:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:393:9
+  --> $DIR/disallowed-positions.rs:397:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:397:9
+  --> $DIR/disallowed-positions.rs:401:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:397:9
+  --> $DIR/disallowed-positions.rs:401:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:400:9
+  --> $DIR/disallowed-positions.rs:404:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:400:9
+  --> $DIR/disallowed-positions.rs:404:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:400:32
+  --> $DIR/disallowed-positions.rs:404:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:400:32
+  --> $DIR/disallowed-positions.rs:404:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:408:9
+  --> $DIR/disallowed-positions.rs:412:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:408:9
+  --> $DIR/disallowed-positions.rs:412:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:408:31
+  --> $DIR/disallowed-positions.rs:412:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:408:31
+  --> $DIR/disallowed-positions.rs:412:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:412:9
+  --> $DIR/disallowed-positions.rs:416:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:412:9
+  --> $DIR/disallowed-positions.rs:416:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:412:31
+  --> $DIR/disallowed-positions.rs:416:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:412:31
+  --> $DIR/disallowed-positions.rs:416:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:416:9
+  --> $DIR/disallowed-positions.rs:420:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:416:9
+  --> $DIR/disallowed-positions.rs:420:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:436:22
+  --> $DIR/disallowed-positions.rs:440:22
    |
 LL |     let x = (true && let y = 1);
    |                      ^^^
@@ -979,7 +979,7 @@ LL |     let x = (true && let y = 1);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:441:20
+  --> $DIR/disallowed-positions.rs:445:20
    |
 LL |         ([1, 2, 3][let _ = ()])
    |                    ^^^
@@ -995,12 +995,48 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:93:16
+  --> $DIR/disallowed-positions.rs:91:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:91:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:95:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:95:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:95:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0658]: `let` expressions in this position are unstable
   --> $DIR/disallowed-positions.rs:49:8
@@ -1043,7 +1079,7 @@ LL |     while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/disallowed-positions.rs:404:8
+  --> $DIR/disallowed-positions.rs:408:8
    |
 LL |     if let Some(a) = opt && (true && true) {
    |        ^^^^^^^^^^^^^^^^^
@@ -1053,7 +1089,7 @@ LL |     if let Some(a) = opt && (true && true) {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/disallowed-positions.rs:420:28
+  --> $DIR/disallowed-positions.rs:424:28
    |
 LL |     if (true && (true)) && let Some(a) = opt {
    |                            ^^^^^^^^^^^^^^^^^
@@ -1063,7 +1099,7 @@ LL |     if (true && (true)) && let Some(a) = opt {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/disallowed-positions.rs:423:18
+  --> $DIR/disallowed-positions.rs:427:18
    |
 LL |     if (true) && let Some(a) = opt {
    |                  ^^^^^^^^^^^^^^^^^
@@ -1073,7 +1109,7 @@ LL |     if (true) && let Some(a) = opt {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/disallowed-positions.rs:426:16
+  --> $DIR/disallowed-positions.rs:430:16
    |
 LL |     if true && let Some(a) = opt {
    |                ^^^^^^^^^^^^^^^^^
@@ -1083,7 +1119,7 @@ LL |     if true && let Some(a) = opt {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/disallowed-positions.rs:431:8
+  --> $DIR/disallowed-positions.rs:435:8
    |
 LL |     if let true = (true && fun()) && (true) {
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1093,7 +1129,7 @@ LL |     if let true = (true && fun()) && (true) {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:130:8
+  --> $DIR/disallowed-positions.rs:134:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -1102,7 +1138,7 @@ LL |     if true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:139:12
+  --> $DIR/disallowed-positions.rs:143:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1113,7 +1149,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:142:12
+  --> $DIR/disallowed-positions.rs:146:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1124,7 +1160,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:148:12
+  --> $DIR/disallowed-positions.rs:152:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1135,7 +1171,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:154:12
+  --> $DIR/disallowed-positions.rs:158:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1146,7 +1182,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:110:20
+  --> $DIR/disallowed-positions.rs:114:20
    |
 LL |         if let 0 = 0? {}
    |                    ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1154,7 +1190,7 @@ LL |         if let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:221:11
+  --> $DIR/disallowed-positions.rs:225:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -1163,7 +1199,7 @@ LL |     while true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:230:15
+  --> $DIR/disallowed-positions.rs:234:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1174,7 +1210,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:233:15
+  --> $DIR/disallowed-positions.rs:237:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1185,7 +1221,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:239:15
+  --> $DIR/disallowed-positions.rs:243:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1196,7 +1232,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:245:15
+  --> $DIR/disallowed-positions.rs:249:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1207,7 +1243,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:201:23
+  --> $DIR/disallowed-positions.rs:205:23
    |
 LL |         while let 0 = 0? {}
    |                       ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1215,7 +1251,7 @@ LL |         while let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:330:10
+  --> $DIR/disallowed-positions.rs:334:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1226,14 +1262,14 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:305:17
+  --> $DIR/disallowed-positions.rs:309:17
    |
 LL |         let 0 = 0?;
    |                 ^^ the `?` operator cannot be applied to type `{integer}`
    |
    = help: the trait `Try` is not implemented for `{integer}`
 
-error: aborting due to 130 previous errors
+error: aborting due to 134 previous errors
 
 Some errors have detailed explanations: E0277, E0308, E0658.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr
index 2d5fd1144ad..943956feb4e 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr
@@ -233,7 +233,7 @@ LL |     while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:99:9
+  --> $DIR/disallowed-positions.rs:103:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^^^^^^^
@@ -241,7 +241,7 @@ LL |     if &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:102:9
+  --> $DIR/disallowed-positions.rs:106:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^^^^^^^
@@ -249,7 +249,7 @@ LL |     if !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:104:9
+  --> $DIR/disallowed-positions.rs:108:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^^^^^^^
@@ -257,7 +257,7 @@ LL |     if *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:106:9
+  --> $DIR/disallowed-positions.rs:110:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^^^^^^^
@@ -265,7 +265,7 @@ LL |     if -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:114:9
+  --> $DIR/disallowed-positions.rs:118:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
@@ -273,20 +273,20 @@ LL |     if (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:117:16
+  --> $DIR/disallowed-positions.rs:121:16
    |
 LL |     if true || let 0 = 0 {}
    |                ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:117:13
+  --> $DIR/disallowed-positions.rs:121:13
    |
 LL |     if true || let 0 = 0 {}
    |             ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:119:17
+  --> $DIR/disallowed-positions.rs:123:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
@@ -294,7 +294,7 @@ LL |     if (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:121:25
+  --> $DIR/disallowed-positions.rs:125:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -302,7 +302,7 @@ LL |     if true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:123:25
+  --> $DIR/disallowed-positions.rs:127:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -310,7 +310,7 @@ LL |     if true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:127:12
+  --> $DIR/disallowed-positions.rs:131:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^
@@ -318,7 +318,7 @@ LL |     if x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:130:15
+  --> $DIR/disallowed-positions.rs:134:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
@@ -326,7 +326,7 @@ LL |     if true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:133:11
+  --> $DIR/disallowed-positions.rs:137:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
@@ -334,7 +334,7 @@ LL |     if ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:135:9
+  --> $DIR/disallowed-positions.rs:139:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
@@ -342,7 +342,7 @@ LL |     if (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:139:8
+  --> $DIR/disallowed-positions.rs:143:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,7 +350,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:142:8
+  --> $DIR/disallowed-positions.rs:146:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -358,7 +358,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:148:8
+  --> $DIR/disallowed-positions.rs:152:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -366,7 +366,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:154:8
+  --> $DIR/disallowed-positions.rs:158:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -374,7 +374,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:158:19
+  --> $DIR/disallowed-positions.rs:162:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^
@@ -382,7 +382,7 @@ LL |     if let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:161:15
+  --> $DIR/disallowed-positions.rs:165:15
    |
 LL |     if return let 0 = 0 {}
    |               ^^^
@@ -390,7 +390,7 @@ LL |     if return let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:164:21
+  --> $DIR/disallowed-positions.rs:168:21
    |
 LL |     loop { if break let 0 = 0 {} }
    |                     ^^^
@@ -398,7 +398,7 @@ LL |     loop { if break let 0 = 0 {} }
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:167:15
+  --> $DIR/disallowed-positions.rs:171:15
    |
 LL |     if (match let 0 = 0 { _ => { false } }) {}
    |               ^^^
@@ -406,7 +406,7 @@ LL |     if (match let 0 = 0 { _ => { false } }) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:170:9
+  --> $DIR/disallowed-positions.rs:174:9
    |
 LL |     if (let 0 = 0, false).1 {}
    |         ^^^^^^^^^
@@ -414,7 +414,7 @@ LL |     if (let 0 = 0, false).1 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:173:9
+  --> $DIR/disallowed-positions.rs:177:9
    |
 LL |     if (let 0 = 0,) {}
    |         ^^^^^^^^^
@@ -422,7 +422,7 @@ LL |     if (let 0 = 0,) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:177:13
+  --> $DIR/disallowed-positions.rs:181:13
    |
 LL |         if (let 0 = 0).await {}
    |             ^^^^^^^^^
@@ -430,7 +430,7 @@ LL |         if (let 0 = 0).await {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:181:12
+  --> $DIR/disallowed-positions.rs:185:12
    |
 LL |     if (|| let 0 = 0) {}
    |            ^^^
@@ -438,7 +438,7 @@ LL |     if (|| let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:184:9
+  --> $DIR/disallowed-positions.rs:188:9
    |
 LL |     if (let 0 = 0)() {}
    |         ^^^^^^^^^
@@ -446,7 +446,7 @@ LL |     if (let 0 = 0)() {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:190:12
+  --> $DIR/disallowed-positions.rs:194:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -454,7 +454,7 @@ LL |     while &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:193:12
+  --> $DIR/disallowed-positions.rs:197:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -462,7 +462,7 @@ LL |     while !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:195:12
+  --> $DIR/disallowed-positions.rs:199:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -470,7 +470,7 @@ LL |     while *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:197:12
+  --> $DIR/disallowed-positions.rs:201:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -478,7 +478,7 @@ LL |     while -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:205:12
+  --> $DIR/disallowed-positions.rs:209:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
@@ -486,20 +486,20 @@ LL |     while (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:208:19
+  --> $DIR/disallowed-positions.rs:212:19
    |
 LL |     while true || let 0 = 0 {}
    |                   ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:208:16
+  --> $DIR/disallowed-positions.rs:212:16
    |
 LL |     while true || let 0 = 0 {}
    |                ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:210:20
+  --> $DIR/disallowed-positions.rs:214:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
@@ -507,7 +507,7 @@ LL |     while (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:212:28
+  --> $DIR/disallowed-positions.rs:216:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -515,7 +515,7 @@ LL |     while true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:214:28
+  --> $DIR/disallowed-positions.rs:218:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -523,7 +523,7 @@ LL |     while true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:218:15
+  --> $DIR/disallowed-positions.rs:222:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^
@@ -531,7 +531,7 @@ LL |     while x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:221:18
+  --> $DIR/disallowed-positions.rs:225:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
@@ -539,7 +539,7 @@ LL |     while true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:224:14
+  --> $DIR/disallowed-positions.rs:228:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
@@ -547,7 +547,7 @@ LL |     while ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:226:12
+  --> $DIR/disallowed-positions.rs:230:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
@@ -555,7 +555,7 @@ LL |     while (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:230:11
+  --> $DIR/disallowed-positions.rs:234:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -563,7 +563,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:233:11
+  --> $DIR/disallowed-positions.rs:237:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -571,7 +571,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:239:11
+  --> $DIR/disallowed-positions.rs:243:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -579,7 +579,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:245:11
+  --> $DIR/disallowed-positions.rs:249:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -587,7 +587,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:249:22
+  --> $DIR/disallowed-positions.rs:253:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^
@@ -595,7 +595,7 @@ LL |     while let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:252:18
+  --> $DIR/disallowed-positions.rs:256:18
    |
 LL |     while return let 0 = 0 {}
    |                  ^^^
@@ -603,7 +603,7 @@ LL |     while return let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:255:39
+  --> $DIR/disallowed-positions.rs:259:39
    |
 LL |     'outer: loop { while break 'outer let 0 = 0 {} }
    |                                       ^^^
@@ -611,7 +611,7 @@ LL |     'outer: loop { while break 'outer let 0 = 0 {} }
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:258:18
+  --> $DIR/disallowed-positions.rs:262:18
    |
 LL |     while (match let 0 = 0 { _ => { false } }) {}
    |                  ^^^
@@ -619,7 +619,7 @@ LL |     while (match let 0 = 0 { _ => { false } }) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:261:12
+  --> $DIR/disallowed-positions.rs:265:12
    |
 LL |     while (let 0 = 0, false).1 {}
    |            ^^^^^^^^^
@@ -627,7 +627,7 @@ LL |     while (let 0 = 0, false).1 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:264:12
+  --> $DIR/disallowed-positions.rs:268:12
    |
 LL |     while (let 0 = 0,) {}
    |            ^^^^^^^^^
@@ -635,7 +635,7 @@ LL |     while (let 0 = 0,) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:268:16
+  --> $DIR/disallowed-positions.rs:272:16
    |
 LL |         while (let 0 = 0).await {}
    |                ^^^^^^^^^
@@ -643,7 +643,7 @@ LL |         while (let 0 = 0).await {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:272:15
+  --> $DIR/disallowed-positions.rs:276:15
    |
 LL |     while (|| let 0 = 0) {}
    |               ^^^
@@ -651,7 +651,7 @@ LL |     while (|| let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:275:12
+  --> $DIR/disallowed-positions.rs:279:12
    |
 LL |     while (let 0 = 0)() {}
    |            ^^^^^^^^^
@@ -659,7 +659,7 @@ LL |     while (let 0 = 0)() {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:292:6
+  --> $DIR/disallowed-positions.rs:296:6
    |
 LL |     &let 0 = 0;
    |      ^^^
@@ -667,7 +667,7 @@ LL |     &let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:295:6
+  --> $DIR/disallowed-positions.rs:299:6
    |
 LL |     !let 0 = 0;
    |      ^^^
@@ -675,7 +675,7 @@ LL |     !let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:297:6
+  --> $DIR/disallowed-positions.rs:301:6
    |
 LL |     *let 0 = 0;
    |      ^^^
@@ -683,7 +683,7 @@ LL |     *let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:299:6
+  --> $DIR/disallowed-positions.rs:303:6
    |
 LL |     -let 0 = 0;
    |      ^^^
@@ -691,7 +691,7 @@ LL |     -let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:301:13
+  --> $DIR/disallowed-positions.rs:305:13
    |
 LL |     let _ = let _ = 3;
    |             ^^^
@@ -699,7 +699,7 @@ LL |     let _ = let _ = 3;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:309:6
+  --> $DIR/disallowed-positions.rs:313:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^
@@ -707,7 +707,7 @@ LL |     (let 0 = 0)?;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:312:13
+  --> $DIR/disallowed-positions.rs:316:13
    |
 LL |     true || let 0 = 0;
    |             ^^^
@@ -715,7 +715,7 @@ LL |     true || let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:314:14
+  --> $DIR/disallowed-positions.rs:318:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^
@@ -723,7 +723,7 @@ LL |     (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:316:22
+  --> $DIR/disallowed-positions.rs:320:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^
@@ -731,7 +731,7 @@ LL |     true && (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:320:9
+  --> $DIR/disallowed-positions.rs:324:9
    |
 LL |     x = let 0 = 0;
    |         ^^^
@@ -739,7 +739,7 @@ LL |     x = let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:323:12
+  --> $DIR/disallowed-positions.rs:327:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^
@@ -747,7 +747,7 @@ LL |     true..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:325:8
+  --> $DIR/disallowed-positions.rs:329:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^
@@ -755,7 +755,7 @@ LL |     ..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:327:6
+  --> $DIR/disallowed-positions.rs:331:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^
@@ -763,7 +763,7 @@ LL |     (let 0 = 0)..;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:330:6
+  --> $DIR/disallowed-positions.rs:334:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^
@@ -771,7 +771,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:334:6
+  --> $DIR/disallowed-positions.rs:338:6
    |
 LL |     (let true = let true = true);
    |      ^^^
@@ -779,7 +779,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:334:17
+  --> $DIR/disallowed-positions.rs:338:17
    |
 LL |     (let true = let true = true);
    |                 ^^^
@@ -787,7 +787,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:340:25
+  --> $DIR/disallowed-positions.rs:344:25
    |
 LL |         let x = true && let y = 1;
    |                         ^^^
@@ -795,7 +795,7 @@ LL |         let x = true && let y = 1;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:346:19
+  --> $DIR/disallowed-positions.rs:350:19
    |
 LL |         [1, 2, 3][let _ = ()]
    |                   ^^^
@@ -803,7 +803,7 @@ LL |         [1, 2, 3][let _ = ()]
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:351:6
+  --> $DIR/disallowed-positions.rs:355:6
    |
 LL |     &let 0 = 0
    |      ^^^
@@ -811,7 +811,7 @@ LL |     &let 0 = 0
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:362:17
+  --> $DIR/disallowed-positions.rs:366:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -819,7 +819,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:367:17
+  --> $DIR/disallowed-positions.rs:371:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -827,7 +827,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:372:17
+  --> $DIR/disallowed-positions.rs:376:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -835,7 +835,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:383:17
+  --> $DIR/disallowed-positions.rs:387:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -843,7 +843,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/disallowed-positions.rs:383:9
+  --> $DIR/disallowed-positions.rs:387:9
    |
 LL |         true && let 1 = 1
    |         ^^^^^^^^^^^^^^^^^
@@ -854,124 +854,124 @@ LL |         { true && let 1 = 1 }
    |         +                   +
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:393:9
+  --> $DIR/disallowed-positions.rs:397:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:393:9
+  --> $DIR/disallowed-positions.rs:397:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:397:9
+  --> $DIR/disallowed-positions.rs:401:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:397:9
+  --> $DIR/disallowed-positions.rs:401:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:400:9
+  --> $DIR/disallowed-positions.rs:404:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:400:9
+  --> $DIR/disallowed-positions.rs:404:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:400:32
+  --> $DIR/disallowed-positions.rs:404:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:400:32
+  --> $DIR/disallowed-positions.rs:404:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:408:9
+  --> $DIR/disallowed-positions.rs:412:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:408:9
+  --> $DIR/disallowed-positions.rs:412:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:408:31
+  --> $DIR/disallowed-positions.rs:412:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:408:31
+  --> $DIR/disallowed-positions.rs:412:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:412:9
+  --> $DIR/disallowed-positions.rs:416:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:412:9
+  --> $DIR/disallowed-positions.rs:416:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:412:31
+  --> $DIR/disallowed-positions.rs:416:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:412:31
+  --> $DIR/disallowed-positions.rs:416:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:416:9
+  --> $DIR/disallowed-positions.rs:420:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:416:9
+  --> $DIR/disallowed-positions.rs:420:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:436:22
+  --> $DIR/disallowed-positions.rs:440:22
    |
 LL |     let x = (true && let y = 1);
    |                      ^^^
@@ -979,7 +979,7 @@ LL |     let x = (true && let y = 1);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:441:20
+  --> $DIR/disallowed-positions.rs:445:20
    |
 LL |         ([1, 2, 3][let _ = ()])
    |                    ^^^
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs
index 8eb8d617d58..99f99c2be72 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -90,8 +90,12 @@ fn _macros() {
     }
     use_expr!((let 0 = 1 && 0 == 0));
     //[feature,no_feature]~^ ERROR expected expression, found `let` statement
+    //[feature,no_feature]~| ERROR expected expression, found `let` statement
+    //[feature,no_feature]~| ERROR expected expression, found `let` statement
     use_expr!((let 0 = 1));
     //[feature,no_feature]~^ ERROR expected expression, found `let` statement
+    //[feature,no_feature]~| ERROR expected expression, found `let` statement
+    //[feature,no_feature]~| ERROR expected expression, found `let` statement
 }
 
 #[cfg(not(nothing))]
diff --git a/tests/ui/rmeta/no_optitimized_mir.rs b/tests/ui/rmeta/no_optitimized_mir.rs
index 708cdfc803f..c8ed00b039b 100644
--- a/tests/ui/rmeta/no_optitimized_mir.rs
+++ b/tests/ui/rmeta/no_optitimized_mir.rs
@@ -10,4 +10,4 @@ fn main() {
     rmeta_meta::missing_optimized_mir();
 }
 
-//~? ERROR missing optimized MIR for an item in the crate `rmeta_meta`
+//~? ERROR missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta`
diff --git a/tests/ui/rmeta/no_optitimized_mir.stderr b/tests/ui/rmeta/no_optitimized_mir.stderr
index 92f22d78000..254f100aa7b 100644
--- a/tests/ui/rmeta/no_optitimized_mir.stderr
+++ b/tests/ui/rmeta/no_optitimized_mir.stderr
@@ -1,4 +1,4 @@
-error: missing optimized MIR for an item in the crate `rmeta_meta`
+error: missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta`
    |
 note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled with `--emit=metadata`?)
   --> $DIR/auxiliary/rmeta-meta.rs:10:1
diff --git a/tests/ui/rmeta/rmeta_bin.rs b/tests/ui/rmeta/rmeta_bin.rs
index c7d2050cd59..9eb65241faf 100644
--- a/tests/ui/rmeta/rmeta_bin.rs
+++ b/tests/ui/rmeta/rmeta_bin.rs
@@ -2,7 +2,6 @@
 //@ compile-flags: --crate-type=bin
 //@ aux-build:rmeta-meta.rs
 //@ no-prefer-dynamic
-//@ error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found
 
 // Check that building a bin crate fails if a dependent crate is metadata-only.
 
@@ -12,3 +11,5 @@ use rmeta_meta::Foo;
 fn main() {
     let _ = Foo { field: 42 };
 }
+
+//~? ERROR crate `rmeta_meta` required to be available in rlib format, but was not found in this form
diff --git a/tests/ui/rmeta/rmeta_lib.rs b/tests/ui/rmeta/rmeta_lib.rs
index 1be4ee8de79..d1a2b653ed8 100644
--- a/tests/ui/rmeta/rmeta_lib.rs
+++ b/tests/ui/rmeta/rmeta_lib.rs
@@ -1,7 +1,6 @@
 //@ build-fail
 //@ aux-build:rmeta-meta.rs
 //@ no-prefer-dynamic
-//@ error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found
 
 // Check that building a non-metadata crate fails if a dependent crate is
 // metadata-only.
@@ -12,3 +11,5 @@ use rmeta_meta::Foo;
 fn main() {
     let _ = Foo { field: 42 };
 }
+
+//~? ERROR crate `rmeta_meta` required to be available in rlib format, but was not found in this form
diff --git a/tests/ui/rustc-error.rs b/tests/ui/rustc-error.rs
deleted file mode 100644
index 69d57948fb5..00000000000
--- a/tests/ui/rustc-error.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(rustc_attrs)]
-
-#[rustc_error]
-fn main() {
-    //~^ ERROR fatal error triggered by #[rustc_error]
-}
diff --git a/tests/ui/rustc-error.stderr b/tests/ui/rustc-error.stderr
deleted file mode 100644
index 67451195b64..00000000000
--- a/tests/ui/rustc-error.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/rustc-error.rs:4:1
-   |
-LL | fn main() {
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/sanitizer/incompatible.rs b/tests/ui/sanitizer/incompatible.rs
index d000abb26ac..c706a5a2e4e 100644
--- a/tests/ui/sanitizer/incompatible.rs
+++ b/tests/ui/sanitizer/incompatible.rs
@@ -1,7 +1,8 @@
 //@ compile-flags: -Z sanitizer=address -Z sanitizer=memory --target x86_64-unknown-linux-gnu
 //@ needs-llvm-components: x86
-//@ error-pattern: error: `-Zsanitizer=address` is incompatible with `-Zsanitizer=memory`
 
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//~? ERROR `-Zsanitizer=address` is incompatible with `-Zsanitizer=memory`
diff --git a/tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs
new file mode 100644
index 00000000000..12aabb3b862
--- /dev/null
+++ b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs
@@ -0,0 +1,9 @@
+// Verifies that `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`.
+//
+//@ needs-sanitizer-kcfi
+//@ compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer-kcfi-arity
+
+//~? ERROR `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr
new file mode 100644
index 00000000000..4ed1b754fd4
--- /dev/null
+++ b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr
@@ -0,0 +1,4 @@
+error: `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs
new file mode 100644
index 00000000000..8a724b853e1
--- /dev/null
+++ b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs
@@ -0,0 +1,11 @@
+// Verifies that `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later.
+//
+//@ needs-sanitizer-kcfi
+//@ compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Cpanic=abort -Zsanitizer=kcfi -Zsanitizer-kcfi-arity
+//@ build-fail
+//@ max-llvm-major-version: 20
+
+//~? ERROR `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later.
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr
new file mode 100644
index 00000000000..ac6bd7411fd
--- /dev/null
+++ b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr
@@ -0,0 +1,4 @@
+error: `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later.
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/sanitizer/unsupported-target.rs b/tests/ui/sanitizer/unsupported-target.rs
index 7c7dc24b5d9..14925548e92 100644
--- a/tests/ui/sanitizer/unsupported-target.rs
+++ b/tests/ui/sanitizer/unsupported-target.rs
@@ -1,6 +1,8 @@
 //@ compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu
 //@ needs-llvm-components: x86
-//@ error-pattern: error: leak sanitizer is not supported for this target
+
 #![feature(no_core)]
 #![no_core]
 #![no_main]
+
+//~? ERROR leak sanitizer is not supported for this target
diff --git a/tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs b/tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs
new file mode 100644
index 00000000000..2bc70de2a34
--- /dev/null
+++ b/tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs
@@ -0,0 +1,26 @@
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/rust/issues/138937>.
+
+// Previously, we'd take the normalized param env's clauses which included
+// `<PF as TraitC>::Value = i32`, which comes from the supertraits of `TraitD`
+// after normalizing `<PF as TraitC>::Value = <PF as TraitD>::Scalar`. Since
+// `normalize_param_env_or_error` ends up re-elaborating `PF: TraitD`, we'd
+// end up with both versions of this predicate (normalized and unnormalized).
+// Since these projections preds are not equal, we'd fail with ambiguity.
+
+trait TraitB<T> {}
+
+trait TraitC: TraitB<Self::Value> {
+    type Value;
+}
+
+trait TraitD: TraitC<Value = Self::Scalar> {
+    type Scalar;
+}
+
+trait TraitE {
+    fn apply<PF: TraitD<Scalar = i32>>(&self);
+}
+
+fn main() {}
diff --git a/tests/ui/simd/empty-simd-vector-in-operand.rs b/tests/ui/simd/empty-simd-vector-in-operand.rs
new file mode 100644
index 00000000000..2a2a6c0737d
--- /dev/null
+++ b/tests/ui/simd/empty-simd-vector-in-operand.rs
@@ -0,0 +1,15 @@
+// Regression test for issue #134224.
+//@ only-x86_64
+
+#![feature(repr_simd)]
+
+#[repr(simd)]
+struct A();
+//~^ ERROR SIMD vector cannot be empty
+
+fn main() {
+    unsafe {
+        std::arch::asm!("{}", in(xmm_reg) A());
+        //~^ use of empty SIMD vector `A`
+    }
+}
diff --git a/tests/ui/simd/empty-simd-vector-in-operand.stderr b/tests/ui/simd/empty-simd-vector-in-operand.stderr
new file mode 100644
index 00000000000..7210dddd461
--- /dev/null
+++ b/tests/ui/simd/empty-simd-vector-in-operand.stderr
@@ -0,0 +1,15 @@
+error[E0075]: SIMD vector cannot be empty
+  --> $DIR/empty-simd-vector-in-operand.rs:7:1
+   |
+LL | struct A();
+   | ^^^^^^^^
+
+error: use of empty SIMD vector `A`
+  --> $DIR/empty-simd-vector-in-operand.rs:12:43
+   |
+LL |         std::arch::asm!("{}", in(xmm_reg) A());
+   |                                           ^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0075`.
diff --git a/tests/ui/simd/monomorphize-too-long.rs b/tests/ui/simd/monomorphize-too-long.rs
index 4bcde782292..4fac987b0b5 100644
--- a/tests/ui/simd/monomorphize-too-long.rs
+++ b/tests/ui/simd/monomorphize-too-long.rs
@@ -1,5 +1,4 @@
 //@ build-fail
-//@ error-pattern: monomorphising SIMD type `Simd<u16, 54321>` of length greater than 32768
 
 #![feature(repr_simd)]
 
@@ -9,3 +8,5 @@ struct Simd<T, const N: usize>([T; N]);
 fn main() {
     let _too_big = Simd([1_u16; 54321]);
 }
+
+//~? ERROR monomorphising SIMD type `Simd<u16, 54321>` of length greater than 32768
diff --git a/tests/ui/simd/monomorphize-zero-length.rs b/tests/ui/simd/monomorphize-zero-length.rs
index 44b4cfc0bcf..d38870c572d 100644
--- a/tests/ui/simd/monomorphize-zero-length.rs
+++ b/tests/ui/simd/monomorphize-zero-length.rs
@@ -1,5 +1,4 @@
 //@ build-fail
-//@ error-pattern: monomorphising SIMD type `Simd<f64, 0>` of zero length
 
 #![feature(repr_simd)]
 
@@ -9,3 +8,5 @@ struct Simd<T, const N: usize>([T; N]);
 fn main() {
     let _empty = Simd([1.0; 0]);
 }
+
+//~? ERROR monomorphising SIMD type `Simd<f64, 0>` of zero length
diff --git a/tests/ui/simd/type-generic-monomorphisation-empty.rs b/tests/ui/simd/type-generic-monomorphisation-empty.rs
index 4700f642065..c08dc9fe3df 100644
--- a/tests/ui/simd/type-generic-monomorphisation-empty.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-empty.rs
@@ -2,11 +2,11 @@
 
 #![feature(repr_simd, intrinsics)]
 
-//@ error-pattern:monomorphising SIMD type `Simd<0>` of zero length
-
 #[repr(simd)]
 struct Simd<const N: usize>([f32; N]);
 
 fn main() {
     let _ = Simd::<0>([]);
 }
+
+//~? ERROR monomorphising SIMD type `Simd<0>` of zero length
diff --git a/tests/ui/simd/type-generic-monomorphisation-non-primitive.rs b/tests/ui/simd/type-generic-monomorphisation-non-primitive.rs
index a2f6998c6d9..7924aeb8684 100644
--- a/tests/ui/simd/type-generic-monomorphisation-non-primitive.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-non-primitive.rs
@@ -4,11 +4,11 @@
 
 struct E;
 
-//@ error-pattern:monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
-
 #[repr(simd)]
 struct S<T>([T; 4]);
 
 fn main() {
     let _v: Option<S<E>> = None;
 }
+
+//~? ERROR monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
diff --git a/tests/ui/simd/type-generic-monomorphisation-oversized.rs b/tests/ui/simd/type-generic-monomorphisation-oversized.rs
index 9949f913c44..efe3480317c 100644
--- a/tests/ui/simd/type-generic-monomorphisation-oversized.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-oversized.rs
@@ -2,11 +2,11 @@
 
 #![feature(repr_simd, intrinsics)]
 
-//@ error-pattern:monomorphising SIMD type `Simd<65536>` of length greater than 32768
-
 #[repr(simd)]
 struct Simd<const N: usize>([f32; N]);
 
 fn main() {
     let _ = Simd::<65536>([0.; 65536]);
 }
+
+//~? ERROR monomorphising SIMD type `Simd<65536>` of length greater than 32768
diff --git a/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs b/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs
index 18fc0753430..97640514dee 100644
--- a/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs
@@ -2,11 +2,11 @@
 
 #![feature(repr_simd)]
 
-//@ error-pattern:monomorphising SIMD type `S<*mut [u8]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
-
 #[repr(simd)]
 struct S<T>([T; 4]);
 
 fn main() {
     let _v: Option<S<*mut [u8]>> = None;
 }
+
+//~? ERROR monomorphising SIMD type `S<*mut [u8]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
diff --git a/tests/ui/simd/type-generic-monomorphisation.rs b/tests/ui/simd/type-generic-monomorphisation.rs
index 8b8d645a264..2563b917e34 100644
--- a/tests/ui/simd/type-generic-monomorphisation.rs
+++ b/tests/ui/simd/type-generic-monomorphisation.rs
@@ -2,9 +2,6 @@
 
 #![feature(repr_simd, intrinsics)]
 
-
-//@ error-pattern:monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
-
 struct X(Vec<i32>);
 #[repr(simd)]
 struct Simd2<T>([T; 2]);
@@ -12,3 +9,5 @@ struct Simd2<T>([T; 2]);
 fn main() {
     let _ = Simd2([X(vec![]), X(vec![])]);
 }
+
+//~? ERROR monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
diff --git a/tests/ui/simd/type-wide-ptr.rs b/tests/ui/simd/type-wide-ptr.rs
index 41d9fac26ad..5740a4e8318 100644
--- a/tests/ui/simd/type-wide-ptr.rs
+++ b/tests/ui/simd/type-wide-ptr.rs
@@ -2,11 +2,11 @@
 
 #![feature(repr_simd)]
 
-//@ error-pattern:monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
-
 #[repr(simd)]
 struct S([*mut [u8]; 4]);
 
 fn main() {
     let _v: Option<S> = None;
 }
+
+//~? ERROR monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
diff --git a/tests/ui/sized/dont-incompletely-prefer-built-in.rs b/tests/ui/sized/dont-incompletely-prefer-built-in.rs
new file mode 100644
index 00000000000..f5bf0c8915e
--- /dev/null
+++ b/tests/ui/sized/dont-incompletely-prefer-built-in.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+struct W<T: ?Sized>(T);
+
+fn is_sized<T: Sized>(x: *const T) {}
+
+fn dummy<T: ?Sized>() -> *const T { todo!() }
+
+fn non_param_where_bound<T: ?Sized>()
+where
+    W<T>: Sized,
+{
+    let x: *const W<_> = dummy();
+    is_sized::<W<_>>(x);
+    let _: *const W<T> = x;
+}
+
+fn main() {}
diff --git a/tests/ui/span/range-2.rs b/tests/ui/span/range-2.rs
index c4bb16f44bd..2e8252169b7 100644
--- a/tests/ui/span/range-2.rs
+++ b/tests/ui/span/range-2.rs
@@ -1,6 +1,6 @@
 // Test range syntax - borrow errors.
-#![feature(rustc_attrs)]
-pub fn main() { #![rustc_error] // rust-lang/rust#49855
+
+pub fn main() {
     let r = {
         let a = 42;
         let b = 42;
diff --git a/tests/ui/span/regionck-unboxed-closure-lifetimes.rs b/tests/ui/span/regionck-unboxed-closure-lifetimes.rs
index 60ccaa872e7..fe6c353e8f8 100644
--- a/tests/ui/span/regionck-unboxed-closure-lifetimes.rs
+++ b/tests/ui/span/regionck-unboxed-closure-lifetimes.rs
@@ -1,7 +1,6 @@
-#![feature(rustc_attrs)]
 use std::ops::FnMut;
 
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
     let mut f;
     {
         let c = 1;
diff --git a/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr b/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr
index 225f83b6e66..bb6298211bc 100644
--- a/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr
+++ b/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `c` does not live long enough
-  --> $DIR/regionck-unboxed-closure-lifetimes.rs:8:21
+  --> $DIR/regionck-unboxed-closure-lifetimes.rs:7:21
    |
 LL |         let c = 1;
    |             - binding `c` declared here
diff --git a/tests/ui/stable-mir-print/async-closure.stdout b/tests/ui/stable-mir-print/async-closure.stdout
index 21df1fd3954..12e7a5530ac 100644
--- a/tests/ui/stable-mir-print/async-closure.stdout
+++ b/tests/ui/stable-mir-print/async-closure.stdout
@@ -56,7 +56,7 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo
         unreachable;
     }
 }
-fn foo::{closure#0}::{closure#1}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
+fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
     let mut _0: Poll<()>;
     let  _3: i32;
     let mut _4: &i32;
diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
index 191daff2137..24e38948647 100644
--- a/tests/ui/stats/input-stats.stderr
+++ b/tests/ui/stats/input-stats.stderr
@@ -10,9 +10,9 @@ ast-stats-1 - DocComment                32 ( 0.5%)             1
 ast-stats-1 - Normal                    32 ( 0.5%)             1
 ast-stats-1 WherePredicate            72 ( 1.1%)             1            72
 ast-stats-1 - BoundPredicate            72 ( 1.1%)             1
+ast-stats-1 ForeignItem               80 ( 1.2%)             1            80
+ast-stats-1 - Fn                        80 ( 1.2%)             1
 ast-stats-1 Local                     80 ( 1.2%)             1            80
-ast-stats-1 ForeignItem               88 ( 1.3%)             1            88
-ast-stats-1 - Fn                        88 ( 1.3%)             1
 ast-stats-1 Arm                       96 ( 1.4%)             2            48
 ast-stats-1 FnDecl                   120 ( 1.8%)             5            24
 ast-stats-1 Param                    160 ( 2.4%)             4            40
@@ -23,37 +23,37 @@ ast-stats-1 - Expr                      96 ( 1.4%)             3
 ast-stats-1 Block                    192 ( 2.9%)             6            32
 ast-stats-1 FieldDef                 208 ( 3.1%)             2           104
 ast-stats-1 Variant                  208 ( 3.1%)             2           104
-ast-stats-1 AssocItem                352 ( 5.3%)             4            88
-ast-stats-1 - Fn                       176 ( 2.6%)             2
-ast-stats-1 - Type                     176 ( 2.6%)             2
-ast-stats-1 GenericBound             352 ( 5.3%)             4            88
-ast-stats-1 - Trait                    352 ( 5.3%)             4
-ast-stats-1 GenericParam             480 ( 7.2%)             5            96
+ast-stats-1 AssocItem                320 ( 4.8%)             4            80
+ast-stats-1 - Fn                       160 ( 2.4%)             2
+ast-stats-1 - Type                     160 ( 2.4%)             2
+ast-stats-1 GenericBound             352 ( 5.2%)             4            88
+ast-stats-1 - Trait                    352 ( 5.2%)             4
+ast-stats-1 GenericParam             480 ( 7.1%)             5            96
 ast-stats-1 Pat                      504 ( 7.5%)             7            72
 ast-stats-1 - Struct                    72 ( 1.1%)             1
 ast-stats-1 - Wild                      72 ( 1.1%)             1
-ast-stats-1 - Ident                    360 ( 5.4%)             5
+ast-stats-1 - Ident                    360 ( 5.3%)             5
 ast-stats-1 Expr                     576 ( 8.6%)             8            72
 ast-stats-1 - Match                     72 ( 1.1%)             1
 ast-stats-1 - Path                      72 ( 1.1%)             1
 ast-stats-1 - Struct                    72 ( 1.1%)             1
 ast-stats-1 - Lit                      144 ( 2.1%)             2
 ast-stats-1 - Block                    216 ( 3.2%)             3
-ast-stats-1 PathSegment              744 (11.1%)            31            24
-ast-stats-1 Ty                       896 (13.4%)            14            64
+ast-stats-1 PathSegment              744 (11.0%)            31            24
+ast-stats-1 Ty                       896 (13.3%)            14            64
 ast-stats-1 - Ptr                       64 ( 1.0%)             1
 ast-stats-1 - Ref                       64 ( 1.0%)             1
 ast-stats-1 - ImplicitSelf             128 ( 1.9%)             2
 ast-stats-1 - Path                     640 ( 9.5%)            10
-ast-stats-1 Item                   1_224 (18.3%)             9           136
-ast-stats-1 - Enum                     136 ( 2.0%)             1
-ast-stats-1 - ForeignMod               136 ( 2.0%)             1
-ast-stats-1 - Impl                     136 ( 2.0%)             1
-ast-stats-1 - Trait                    136 ( 2.0%)             1
-ast-stats-1 - Fn                       272 ( 4.1%)             2
-ast-stats-1 - Use                      408 ( 6.1%)             3
+ast-stats-1 Item                   1_296 (19.2%)             9           144
+ast-stats-1 - Enum                     144 ( 2.1%)             1
+ast-stats-1 - ForeignMod               144 ( 2.1%)             1
+ast-stats-1 - Impl                     144 ( 2.1%)             1
+ast-stats-1 - Trait                    144 ( 2.1%)             1
+ast-stats-1 - Fn                       288 ( 4.3%)             2
+ast-stats-1 - Use                      432 ( 6.4%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  6_704                   116
+ast-stats-1 Total                  6_736                   116
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
@@ -61,12 +61,12 @@ ast-stats-2 ----------------------------------------------------------------
 ast-stats-2 Crate                     40 ( 0.5%)             1            40
 ast-stats-2 GenericArgs               40 ( 0.5%)             1            40
 ast-stats-2 - AngleBracketed            40 ( 0.5%)             1
-ast-stats-2 ExprField                 48 ( 0.7%)             1            48
+ast-stats-2 ExprField                 48 ( 0.6%)             1            48
 ast-stats-2 WherePredicate            72 ( 1.0%)             1            72
 ast-stats-2 - BoundPredicate            72 ( 1.0%)             1
+ast-stats-2 ForeignItem               80 ( 1.1%)             1            80
+ast-stats-2 - Fn                        80 ( 1.1%)             1
 ast-stats-2 Local                     80 ( 1.1%)             1            80
-ast-stats-2 ForeignItem               88 ( 1.2%)             1            88
-ast-stats-2 - Fn                        88 ( 1.2%)             1
 ast-stats-2 Arm                       96 ( 1.3%)             2            48
 ast-stats-2 FnDecl                   120 ( 1.6%)             5            24
 ast-stats-2 InlineAsm                120 ( 1.6%)             1           120
@@ -81,13 +81,13 @@ ast-stats-2 - Expr                      96 ( 1.3%)             3
 ast-stats-2 Block                    192 ( 2.6%)             6            32
 ast-stats-2 FieldDef                 208 ( 2.8%)             2           104
 ast-stats-2 Variant                  208 ( 2.8%)             2           104
-ast-stats-2 AssocItem                352 ( 4.8%)             4            88
-ast-stats-2 - Fn                       176 ( 2.4%)             2
-ast-stats-2 - Type                     176 ( 2.4%)             2
+ast-stats-2 AssocItem                320 ( 4.3%)             4            80
+ast-stats-2 - Fn                       160 ( 2.2%)             2
+ast-stats-2 - Type                     160 ( 2.2%)             2
 ast-stats-2 GenericBound             352 ( 4.8%)             4            88
 ast-stats-2 - Trait                    352 ( 4.8%)             4
 ast-stats-2 GenericParam             480 ( 6.5%)             5            96
-ast-stats-2 Pat                      504 ( 6.9%)             7            72
+ast-stats-2 Pat                      504 ( 6.8%)             7            72
 ast-stats-2 - Struct                    72 ( 1.0%)             1
 ast-stats-2 - Wild                      72 ( 1.0%)             1
 ast-stats-2 - Ident                    360 ( 4.9%)             5
@@ -96,24 +96,24 @@ ast-stats-2 - InlineAsm                 72 ( 1.0%)             1
 ast-stats-2 - Match                     72 ( 1.0%)             1
 ast-stats-2 - Path                      72 ( 1.0%)             1
 ast-stats-2 - Struct                    72 ( 1.0%)             1
-ast-stats-2 - Lit                      144 ( 2.0%)             2
+ast-stats-2 - Lit                      144 ( 1.9%)             2
 ast-stats-2 - Block                    216 ( 2.9%)             3
-ast-stats-2 PathSegment              864 (11.8%)            36            24
-ast-stats-2 Ty                       896 (12.2%)            14            64
+ast-stats-2 PathSegment              864 (11.7%)            36            24
+ast-stats-2 Ty                       896 (12.1%)            14            64
 ast-stats-2 - Ptr                       64 ( 0.9%)             1
 ast-stats-2 - Ref                       64 ( 0.9%)             1
 ast-stats-2 - ImplicitSelf             128 ( 1.7%)             2
-ast-stats-2 - Path                     640 ( 8.7%)            10
-ast-stats-2 Item                   1_496 (20.3%)            11           136
-ast-stats-2 - Enum                     136 ( 1.8%)             1
-ast-stats-2 - ExternCrate              136 ( 1.8%)             1
-ast-stats-2 - ForeignMod               136 ( 1.8%)             1
-ast-stats-2 - Impl                     136 ( 1.8%)             1
-ast-stats-2 - Trait                    136 ( 1.8%)             1
-ast-stats-2 - Fn                       272 ( 3.7%)             2
-ast-stats-2 - Use                      544 ( 7.4%)             4
+ast-stats-2 - Path                     640 ( 8.6%)            10
+ast-stats-2 Item                   1_584 (21.4%)            11           144
+ast-stats-2 - Enum                     144 ( 1.9%)             1
+ast-stats-2 - ExternCrate              144 ( 1.9%)             1
+ast-stats-2 - ForeignMod               144 ( 1.9%)             1
+ast-stats-2 - Impl                     144 ( 1.9%)             1
+ast-stats-2 - Trait                    144 ( 1.9%)             1
+ast-stats-2 - Fn                       288 ( 3.9%)             2
+ast-stats-2 - Use                      576 ( 7.8%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  7_352                   127
+ast-stats-2 Total                  7_400                   127
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr
index bedbbd9cb50..60cae7e84e3 100644
--- a/tests/ui/str/str-idx.stderr
+++ b/tests/ui/str/str-idx.stderr
@@ -4,11 +4,12 @@ error[E0277]: the type `str` cannot be indexed by `{integer}`
 LL |     let _: u8 = s[4];
    |                   ^ string indices are ranges of `usize`
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `str` to implement `Index<{integer}>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -19,11 +20,12 @@ LL |     let _ = s.get(4);
    |               |
    |               required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
@@ -35,11 +37,12 @@ LL |     let _ = s.get_unchecked(4);
    |               |
    |               required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get_unchecked`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr
index f09a4c329e5..4e3fe126ed8 100644
--- a/tests/ui/str/str-mut-idx.stderr
+++ b/tests/ui/str/str-mut-idx.stderr
@@ -31,8 +31,9 @@ LL |     s[1usize] = bot();
    |       ^^^^^^ string indices are ranges of `usize`
    |
    = help: the trait `SliceIndex<str>` is not implemented for `usize`
-           but trait `SliceIndex<[_]>` is implemented for it
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `str` to implement `Index<usize>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -43,11 +44,12 @@ LL |     s.get_mut(1);
    |       |
    |       required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get_mut`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
@@ -59,11 +61,12 @@ LL |     s.get_unchecked_mut(1);
    |       |
    |       required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get_unchecked_mut`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
diff --git a/tests/ui/suggestions/attribute-typos.rs b/tests/ui/suggestions/attribute-typos.rs
index 7c8231bbb24..4c2336e105e 100644
--- a/tests/ui/suggestions/attribute-typos.rs
+++ b/tests/ui/suggestions/attribute-typos.rs
@@ -4,8 +4,8 @@ fn foo() {}
 #[tests] //~ ERROR cannot find attribute `tests` in this scope
 fn bar() {}
 
-#[rustc_err]
-//~^ ERROR cannot find attribute `rustc_err` in this scope
+#[rustc_dumm]
+//~^ ERROR cannot find attribute `rustc_dumm` in this scope
 //~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
 
 fn main() {}
diff --git a/tests/ui/suggestions/attribute-typos.stderr b/tests/ui/suggestions/attribute-typos.stderr
index b871c9b45a5..a1a01c0abd6 100644
--- a/tests/ui/suggestions/attribute-typos.stderr
+++ b/tests/ui/suggestions/attribute-typos.stderr
@@ -1,14 +1,14 @@
 error: attributes starting with `rustc` are reserved for use by the `rustc` compiler
   --> $DIR/attribute-typos.rs:7:3
    |
-LL | #[rustc_err]
-   |   ^^^^^^^^^
+LL | #[rustc_dumm]
+   |   ^^^^^^^^^^
 
-error: cannot find attribute `rustc_err` in this scope
+error: cannot find attribute `rustc_dumm` in this scope
   --> $DIR/attribute-typos.rs:7:3
    |
-LL | #[rustc_err]
-   |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_error`
+LL | #[rustc_dumm]
+   |   ^^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_dummy`
 
 error: cannot find attribute `tests` in this scope
   --> $DIR/attribute-typos.rs:4:3
diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr
index 0335d8eafde..937f32677a6 100644
--- a/tests/ui/suggestions/suggest-dereferencing-index.stderr
+++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr
@@ -4,9 +4,10 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `&usize`
 LL |     let one_item_please: i32 = [1, 2, 3][i];
    |                                          ^ slice indices are of type `usize` or ranges of `usize`
    |
-   = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&_`
-           but it is implemented for `_`
-   = help: for that trait implementation, expected `usize`, found `&usize`
+   = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[{integer}]` to implement `Index<&usize>`
    = note: 1 redundant requirement hidden
    = note: required for `[{integer}; 3]` to implement `Index<&usize>`
diff --git a/tests/ui/tail-typeck.rs b/tests/ui/tail-typeck.rs
index feef58a3388..1deb43c9496 100644
--- a/tests/ui/tail-typeck.rs
+++ b/tests/ui/tail-typeck.rs
@@ -1,6 +1,4 @@
-//@ error-pattern: mismatched types
-
-fn f() -> isize { return g(); }
+fn f() -> isize { return g(); } //~ ERROR mismatched types
 
 fn g() -> usize { return 0; }
 
diff --git a/tests/ui/tail-typeck.stderr b/tests/ui/tail-typeck.stderr
index 0e470a7b405..3cfbfa0fb56 100644
--- a/tests/ui/tail-typeck.stderr
+++ b/tests/ui/tail-typeck.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/tail-typeck.rs:3:26
+  --> $DIR/tail-typeck.rs:1:26
    |
 LL | fn f() -> isize { return g(); }
    |           -----          ^^^ expected `isize`, found `usize`
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
index 81f138b175f..12e7e3bc45b 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
@@ -5,9 +5,11 @@
 //@ compile-flags: -Ctarget-feature=-sse
 // For now this is just a warning.
 //@ build-pass
-//@error-pattern: must be enabled to ensure that the ABI
+
 #![feature(no_core, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
 pub trait Sized {}
+
+//~? WARN target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
index 7242bcc85bf..33e4f12694f 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
@@ -3,9 +3,11 @@
 //@ compile-flags: -Ctarget-feature=-neon
 // For now this is just a warning.
 //@ build-pass
-//@error-pattern: must be enabled to ensure that the ABI
+
 #![feature(no_core, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
 pub trait Sized {}
+
+//~? WARN target feature `neon` must be enabled to ensure that the ABI of the current target can be implemented correctly
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
index 7eebcf05dc0..e1bd25ffad1 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
@@ -4,9 +4,12 @@
 //@ compile-flags: -Ctarget-feature=-x87
 // For now this is just a warning.
 //@ build-pass
-//@error-pattern: must be enabled to ensure that the ABI
+
 #![feature(no_core, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
 pub trait Sized {}
+
+//~? WARN target feature `x87` must be enabled to ensure that the ABI of the current target can be implemented correctly
+//~? WARN unstable feature specified for `-Ctarget-feature`: `x87`
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs
index f277a309cd6..4ccc6e0e941 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs
@@ -4,9 +4,12 @@
 //@ compile-flags: -Ctarget-feature=+soft-float
 // For now this is just a warning.
 //@ build-pass
-//@error-pattern: must be disabled to ensure that the ABI
+
 #![feature(no_core, lang_items, riscv_target_feature)]
 #![no_core]
 
 #[lang = "sized"]
 pub trait Sized {}
+
+//~? WARN target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctl
+//~? WARN unstable feature specified for `-Ctarget-feature`: `soft-float`
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
index cf85c521228..fda0b1c08cb 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
@@ -10,3 +10,5 @@
 
 #[lang = "sized"]
 pub trait Sized {}
+
+//~? WARN target feature `forced-atomics` cannot be disabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs
index 245841eb039..a04d7e34753 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs
@@ -4,9 +4,11 @@
 //@ compile-flags: -Ctarget-feature=+forced-atomics
 // For now this is just a warning.
 //@ build-pass
-//@error-pattern: unsound because it changes the ABI
+
 #![feature(no_core, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
 pub trait Sized {}
+
+//~? WARN target feature `forced-atomics` cannot be enabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations
diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr
index dc8a5304164..05ae49d6b0d 100644
--- a/tests/ui/target-feature/invalid-attribute.stderr
+++ b/tests/ui/target-feature/invalid-attribute.stderr
@@ -98,6 +98,12 @@ LL |
 LL | trait Baz {}
    | ------------ not a function definition
 
+error: cannot use `#[inline(always)]` with `#[target_feature]`
+  --> $DIR/invalid-attribute.rs:69:1
+   |
+LL | #[inline(always)]
+   | ^^^^^^^^^^^^^^^^^
+
 error: attribute should be applied to a function definition
   --> $DIR/invalid-attribute.rs:74:1
    |
@@ -163,12 +169,6 @@ error: malformed `target_feature` attribute input
 LL | #[target_feature(disable = "baz")]
    |                  ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
 
-error: cannot use `#[inline(always)]` with `#[target_feature]`
-  --> $DIR/invalid-attribute.rs:69:1
-   |
-LL | #[inline(always)]
-   | ^^^^^^^^^^^^^^^^^
-
 error[E0046]: not all trait items implemented, missing: `foo`
   --> $DIR/invalid-attribute.rs:81:1
    |
diff --git a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs
index 28d026c1a9a..be6cd2b6faf 100644
--- a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs
+++ b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs
@@ -3,10 +3,11 @@
 //@ compile-flags: -Ctarget-cpu=pentium
 // For now this is just a warning.
 //@ build-pass
-//@error-pattern: must be enabled
 
 #![feature(no_core, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
 pub trait Sized {}
+
+//~? WARN target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
diff --git a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr
index 0e31dea24ea..4ff42d31e94 100644
--- a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr
+++ b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr
@@ -1,10 +1,10 @@
 error[E0428]: the name `foo` is defined multiple times
-  --> $DIR/tied-features-no-implication.rs:28:1
+  --> $DIR/tied-features-no-implication.rs:27:1
    |
 LL | fn foo() {}
    | -------- previous definition of the value `foo` here
 ...
-LL | pub unsafe fn foo() {
+LL | pub unsafe fn foo() {}
    | ^^^^^^^^^^^^^^^^^^^ `foo` redefined here
    |
    = note: `foo` must be defined only once in the value namespace of this module
diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs
index 157b50bb0d3..1625f71431a 100644
--- a/tests/ui/target-feature/tied-features-no-implication.rs
+++ b/tests/ui/target-feature/tied-features-no-implication.rs
@@ -2,9 +2,8 @@
 //@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
 //@ needs-llvm-components: aarch64
 //@[paca] compile-flags: -Ctarget-feature=+paca
-//@[paca] error-pattern: the target features paca, pacg must all be either enabled or disabled together
 //@[pacg] compile-flags: -Ctarget-feature=+pacg
-//@[pacg] error-pattern: the name `foo` is defined multiple times
+
 #![feature(no_core, lang_items)]
 #![no_core]
 
@@ -25,5 +24,6 @@ fn foo() {}
 // be).
 
 #[cfg(target_feature = "pacg")]
-pub unsafe fn foo() {
-}
+pub unsafe fn foo() {} //[pacg]~ ERROR the name `foo` is defined multiple times
+
+//[paca]~? ERROR the target features paca, pacg must all be either enabled or disabled together
diff --git a/tests/ui/test-attrs/test-panic-abort-disabled.rs b/tests/ui/test-attrs/test-panic-abort-disabled.rs
index e83be65f925..cb1b2af9e26 100644
--- a/tests/ui/test-attrs/test-panic-abort-disabled.rs
+++ b/tests/ui/test-attrs/test-panic-abort-disabled.rs
@@ -1,4 +1,3 @@
-//@ error-pattern:building tests with panic=abort is not supported
 //@ no-prefer-dynamic
 //@ compile-flags: --test -Cpanic=abort -Zpanic-abort-tests=no
 //@ run-flags: --test-threads=1
@@ -18,3 +17,5 @@ fn it_works() {
 fn it_panics() {
     assert_eq!(1 + 1, 4);
 }
+
+//~? ERROR building tests with panic=abort is not supported without `-Zpanic_abort_tests`
diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs
index 9e81cb53fc1..78ff85489be 100644
--- a/tests/ui/track-diagnostics/track.rs
+++ b/tests/ui/track-diagnostics/track.rs
@@ -15,4 +15,7 @@
 
 fn main() {
     break rust
+    //~^ ERROR cannot find value `rust` in this scope
+    //~| ERROR `break` outside of a loop or labeled block
+    //~| ERROR It looks like you're trying to break rust; would you like some ICE?
 }
diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs
index 5805fd21220..f51a42cf86f 100644
--- a/tests/ui/track-diagnostics/track2.rs
+++ b/tests/ui/track-diagnostics/track2.rs
@@ -6,5 +6,5 @@
 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC"
 
 fn main() {
-    let _moved @ _from = String::from("foo");
+    let _moved @ _from = String::from("foo"); //~ ERROR use of moved value
 }
diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs
index bac1fc7e184..428067572af 100644
--- a/tests/ui/track-diagnostics/track3.rs
+++ b/tests/ui/track-diagnostics/track3.rs
@@ -7,4 +7,6 @@
 
 fn main() {
     let _unimported = Blah { field: u8 };
+    //~^ ERROR cannot find struct, variant or union type `Blah` in this scope
+    //~| ERROR expected value, found builtin type `u8`
 }
diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs
index ec9e3efa481..b6edfdba259 100644
--- a/tests/ui/track-diagnostics/track4.rs
+++ b/tests/ui/track-diagnostics/track4.rs
@@ -5,7 +5,7 @@
 // updating everytime someone adds or removes a line.
 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC"
 
-pub onion {
+pub onion { //~ ERROR missing `enum` for enum definition
     Owo(u8),
     Uwu(i8),
 }
diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs
index e72e3482ad3..800bb21b2b1 100644
--- a/tests/ui/track-diagnostics/track5.rs
+++ b/tests/ui/track-diagnostics/track5.rs
@@ -5,4 +5,4 @@
 // updating everytime someone adds or removes a line.
 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC"
 
-}
+} //~ ERROR unexpected closing delimiter: `}`
diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs
index e4d124a22e4..55db2ecf939 100644
--- a/tests/ui/track-diagnostics/track6.rs
+++ b/tests/ui/track-diagnostics/track6.rs
@@ -11,7 +11,7 @@ pub trait Foo {
 }
 
 impl <T> Foo for T {
-    default fn bar() {}
+    default fn bar() {} //~ ERROR specialization is unstable
 }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/assoc-type.current.stderr b/tests/ui/traits/const-traits/assoc-type.current.stderr
index 4bf9acfbd65..7526369194b 100644
--- a/tests/ui/traits/const-traits/assoc-type.current.stderr
+++ b/tests/ui/traits/const-traits/assoc-type.current.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::Bar`
   --> $DIR/assoc-type.rs:33:15
    |
 LL |     type Bar: ~const Add;
-   |               ^^^^^^ required by this bound in `Foo::Bar`
+   |               ^^^^^^^^^^ required by this bound in `Foo::Bar`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/assoc-type.next.stderr b/tests/ui/traits/const-traits/assoc-type.next.stderr
index 4bf9acfbd65..7526369194b 100644
--- a/tests/ui/traits/const-traits/assoc-type.next.stderr
+++ b/tests/ui/traits/const-traits/assoc-type.next.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::Bar`
   --> $DIR/assoc-type.rs:33:15
    |
 LL |     type Bar: ~const Add;
-   |               ^^^^^^ required by this bound in `Foo::Bar`
+   |               ^^^^^^^^^^ required by this bound in `Foo::Bar`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
index 74a22186a16..11bbe8bbb40 100644
--- a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `equals_self`
   --> $DIR/call-generic-method-nonconst.rs:17:25
    |
 LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
-   |                         ^^^^^^ required by this bound in `equals_self`
+   |                         ^^^^^^^^^^ required by this bound in `equals_self`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
index 2b5e66b1a08..76207ea0939 100644
--- a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
@@ -8,14 +8,14 @@ note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `const
   --> $DIR/const-drop-fail-2.rs:25:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
-   |         ------          ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         --------        ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |
    |         unsatisfied trait bound introduced here
 note: required by a bound in `check`
   --> $DIR/const-drop-fail-2.rs:21:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
index 2b5e66b1a08..76207ea0939 100644
--- a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
@@ -8,14 +8,14 @@ note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `const
   --> $DIR/const-drop-fail-2.rs:25:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
-   |         ------          ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         --------        ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |
    |         unsatisfied trait bound introduced here
 note: required by a bound in `check`
   --> $DIR/const-drop-fail-2.rs:21:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-opaque.no.stderr b/tests/ui/traits/const-traits/const-opaque.no.stderr
index 1278e125746..47e692936e0 100644
--- a/tests/ui/traits/const-traits/const-opaque.no.stderr
+++ b/tests/ui/traits/const-traits/const-opaque.no.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `bar`
   --> $DIR/const-opaque.rs:26:17
    |
 LL | const fn bar<T: ~const Foo>(t: T) -> impl ~const Foo {
-   |                 ^^^^^^ required by this bound in `bar`
+   |                 ^^^^^^^^^^ required by this bound in `bar`
 
 error[E0277]: the trait bound `(): const Foo` is not satisfied
   --> $DIR/const-opaque.rs:33:12
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
index 8c284bde67e..b3017523b27 100644
--- a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `foo`
   --> $DIR/default-method-body-is-const-body-checking.rs:7:28
    |
 LL | const fn foo<T>() where T: ~const Tr {}
-   |                            ^^^^^^ required by this bound in `foo`
+   |                            ^^^^^^^^^ required by this bound in `foo`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/feature-gate.gated.stderr b/tests/ui/traits/const-traits/feature-gate.gated.stderr
deleted file mode 100644
index 12f9355e41d..00000000000
--- a/tests/ui/traits/const-traits/feature-gate.gated.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/feature-gate.rs:22:1
-   |
-LL | fn main() {}
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/traits/const-traits/feature-gate.rs b/tests/ui/traits/const-traits/feature-gate.rs
index c36ec3538c3..921dfb054e3 100644
--- a/tests/ui/traits/const-traits/feature-gate.rs
+++ b/tests/ui/traits/const-traits/feature-gate.rs
@@ -1,8 +1,8 @@
 //@ revisions: stock gated
+//@[gated] check-pass
 // gate-test-const_trait_impl
 
 #![cfg_attr(gated, feature(const_trait_impl))]
-#![feature(rustc_attrs)]
 
 struct S;
 #[const_trait] //[stock]~ ERROR `const_trait` is a temporary placeholder
@@ -18,5 +18,4 @@ macro_rules! discard { ($ty:ty) => {} }
 discard! { impl ~const T } //[stock]~ ERROR const trait impls are experimental
 discard! { impl const T } //[stock]~ ERROR const trait impls are experimental
 
-#[rustc_error]
-fn main() {} //[gated]~ ERROR fatal error triggered by #[rustc_error]
+fn main() {}
diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
index 0d53bc5897e..7e72dc9abaa 100644
--- a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
+++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::Assoc`
   --> $DIR/item-bound-entailment-fails.rs:5:20
    |
 LL |     type Assoc<T>: ~const Bar
-   |                    ^^^^^^ required by this bound in `Foo::Assoc`
+   |                    ^^^^^^^^^^ required by this bound in `Foo::Assoc`
 
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/item-bound-entailment-fails.rs:24:21
@@ -20,12 +20,12 @@ note: required for `C<T>` to implement `~const Bar`
   --> $DIR/item-bound-entailment-fails.rs:14:15
    |
 LL | impl<T> const Bar for C<T> where T: ~const Bar {}
-   |               ^^^     ^^^^          ------ unsatisfied trait bound introduced here
+   |               ^^^     ^^^^          ---------- unsatisfied trait bound introduced here
 note: required by a bound in `Foo::Assoc`
   --> $DIR/item-bound-entailment-fails.rs:5:20
    |
 LL |     type Assoc<T>: ~const Bar
-   |                    ^^^^^^ required by this bound in `Foo::Assoc`
+   |                    ^^^^^^^^^^ required by this bound in `Foo::Assoc`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/minicore-fn-fail.stderr b/tests/ui/traits/const-traits/minicore-fn-fail.stderr
index fa8be631a26..03c7ade87c0 100644
--- a/tests/ui/traits/const-traits/minicore-fn-fail.stderr
+++ b/tests/ui/traits/const-traits/minicore-fn-fail.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `call_indirect`
   --> $DIR/minicore-fn-fail.rs:11:27
    |
 LL | const fn call_indirect<T: ~const Fn()>(t: &T) { t() }
-   |                           ^^^^^^ required by this bound in `call_indirect`
+   |                           ^^^^^^^^^^^ required by this bound in `call_indirect`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/predicate-entailment-fails.stderr b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
index 369e95688a9..dfdc4d23250 100644
--- a/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
+++ b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
@@ -5,7 +5,7 @@ LL |     type Bar<T> where T: ~const Bar;
    |     ----------- definition of `Bar` from trait
 ...
 LL |     type Bar<T> = () where T: const Bar;
-   |                               ^^^^^ impl has extra requirement `T: const Bar`
+   |                               ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:17:26
@@ -14,7 +14,7 @@ LL |     fn foo<T>() where T: ~const Bar;
    |     -------------------------------- definition of `foo` from trait
 ...
 LL |     fn foo<T>() where T: const Bar {}
-   |                          ^^^^^ impl has extra requirement `T: const Bar`
+   |                          ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:28:31
@@ -23,7 +23,7 @@ LL |     type Bar<T> where T: Bar;
    |     ----------- definition of `Bar` from trait
 ...
 LL |     type Bar<T> = () where T: const Bar;
-   |                               ^^^^^ impl has extra requirement `T: const Bar`
+   |                               ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:31:26
@@ -32,7 +32,7 @@ LL |     fn foo<T>() where T: Bar;
    |     ------------------------- definition of `foo` from trait
 ...
 LL |     fn foo<T>() where T: const Bar {}
-   |                          ^^^^^ impl has extra requirement `T: const Bar`
+   |                          ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:35:31
@@ -41,7 +41,7 @@ LL |     type Bar<T> where T: Bar;
    |     ----------- definition of `Bar` from trait
 ...
 LL |     type Bar<T> = () where T: ~const Bar;
-   |                               ^^^^^^ impl has extra requirement `T: ~const Bar`
+   |                               ^^^^^^^^^^ impl has extra requirement `T: ~const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:38:26
@@ -50,7 +50,7 @@ LL |     fn foo<T>() where T: Bar;
    |     ------------------------- definition of `foo` from trait
 ...
 LL |     fn foo<T>() where T: ~const Bar {}
-   |                          ^^^^^^ impl has extra requirement `T: ~const Bar`
+   |                          ^^^^^^^^^^ impl has extra requirement `T: ~const Bar`
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
index 4100ae1c6bf..4ebd7b9757f 100644
--- a/tests/ui/traits/const-traits/trait-where-clause-const.stderr
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::b`
   --> $DIR/trait-where-clause-const.rs:15:24
    |
 LL |     fn b() where Self: ~const Bar;
-   |                        ^^^^^^ required by this bound in `Foo::b`
+   |                        ^^^^^^^^^^ required by this bound in `Foo::b`
 
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/trait-where-clause-const.rs:23:12
@@ -20,7 +20,7 @@ note: required by a bound in `Foo::c`
   --> $DIR/trait-where-clause-const.rs:16:13
    |
 LL |     fn c<T: ~const Bar>();
-   |             ^^^^^^ required by this bound in `Foo::c`
+   |             ^^^^^^^^^^ required by this bound in `Foo::c`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
index bda6a029cc2..be761e49ba0 100644
--- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
@@ -28,7 +28,7 @@ note: required by a bound in `require`
   --> $DIR/unsatisfied-const-trait-bound.rs:8:15
    |
 LL | fn require<T: const Trait>() {}
-   |               ^^^^^ required by this bound in `require`
+   |               ^^^^^^^^^^^ required by this bound in `require`
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs
new file mode 100644
index 00000000000..3818456d3a6
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(auto_traits, lang_items, no_core, rustc_attrs, trait_alias)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "default_trait1"]
+auto trait DefaultTrait1 {}
+
+#[lang = "default_trait2"]
+auto trait DefaultTrait2 {}
+
+trait Trait<Rhs: ?Sized = Self> {}
+trait Trait1 : Trait {}
+
+trait Trait2 {
+    type Type;
+}
+trait Trait3<T> = Trait2<Type = T>;
+
+fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/default-bounds.rs b/tests/ui/traits/default_auto_traits/default-bounds.rs
new file mode 100644
index 00000000000..64733a40034
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/default-bounds.rs
@@ -0,0 +1,41 @@
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(
+    auto_traits,
+    lang_items,
+    negative_impls,
+    no_core,
+    rustc_attrs
+)]
+#![allow(incomplete_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+pub trait Copy {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+#[lang = "default_trait2"]
+auto trait SyncDrop {}
+
+struct Forbidden;
+
+impl !Leak for Forbidden {}
+impl !SyncDrop for Forbidden {}
+
+struct Accepted;
+
+fn bar<T: Leak>(_: T) {}
+
+fn main() {
+    // checking that bounds can be added explicitly
+    bar(Forbidden);
+    //~^ ERROR the trait bound `Forbidden: Leak` is not satisfied
+    //~| ERROR the trait bound `Forbidden: SyncDrop` is not satisfied
+    bar(Accepted);
+}
diff --git a/tests/ui/traits/default_auto_traits/default-bounds.stderr b/tests/ui/traits/default_auto_traits/default-bounds.stderr
new file mode 100644
index 00000000000..10fdcc43417
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/default-bounds.stderr
@@ -0,0 +1,31 @@
+error[E0277]: the trait bound `Forbidden: SyncDrop` is not satisfied
+  --> $DIR/default-bounds.rs:37:9
+   |
+LL |     bar(Forbidden);
+   |     --- ^^^^^^^^^ the trait `SyncDrop` is not implemented for `Forbidden`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `bar`
+  --> $DIR/default-bounds.rs:33:8
+   |
+LL | fn bar<T: Leak>(_: T) {}
+   |        ^ required by this bound in `bar`
+
+error[E0277]: the trait bound `Forbidden: Leak` is not satisfied
+  --> $DIR/default-bounds.rs:37:9
+   |
+LL |     bar(Forbidden);
+   |     --- ^^^^^^^^^ the trait `Leak` is not implemented for `Forbidden`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `bar`
+  --> $DIR/default-bounds.rs:33:11
+   |
+LL | fn bar<T: Leak>(_: T) {}
+   |           ^^^^ required by this bound in `bar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/extern-types.current.stderr b/tests/ui/traits/default_auto_traits/extern-types.current.stderr
new file mode 100644
index 00000000000..e1bd99b900f
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/extern-types.current.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied
+  --> $DIR/extern-types.rs:44:13
+   |
+LL |         foo(x);
+   |         --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque`
+   |         |
+   |         required by a bound introduced by this call
+   |
+note: required by a bound in `foo`
+  --> $DIR/extern-types.rs:20:8
+   |
+LL | fn foo<T: ?Sized>(_: &T) {}
+   |        ^ required by this bound in `foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/extern-types.next.stderr b/tests/ui/traits/default_auto_traits/extern-types.next.stderr
new file mode 100644
index 00000000000..e1bd99b900f
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/extern-types.next.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied
+  --> $DIR/extern-types.rs:44:13
+   |
+LL |         foo(x);
+   |         --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque`
+   |         |
+   |         required by a bound introduced by this call
+   |
+note: required by a bound in `foo`
+  --> $DIR/extern-types.rs:20:8
+   |
+LL | fn foo<T: ?Sized>(_: &T) {}
+   |        ^ required by this bound in `foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/extern-types.rs b/tests/ui/traits/default_auto_traits/extern-types.rs
new file mode 100644
index 00000000000..822d4c0637f
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/extern-types.rs
@@ -0,0 +1,49 @@
+//@  compile-flags:  -Zexperimental-default-bounds
+//@ revisions: current next
+//@ [next] compile-flags: -Znext-solver
+
+#![feature(auto_traits, extern_types, lang_items, negative_impls, no_core, rustc_attrs)]
+#![allow(incomplete_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+pub trait Copy {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+// implicit T: Leak here
+fn foo<T: ?Sized>(_: &T) {}
+
+mod extern_leak {
+    use crate::*;
+
+    extern "C" {
+        type Opaque;
+    }
+
+    fn forward_extern_ty(x: &Opaque) {
+        // ok, extern type leak by default
+        crate::foo(x);
+    }
+}
+
+mod extern_non_leak {
+    use crate::*;
+
+    extern "C" {
+        type Opaque;
+    }
+
+    impl !Leak for Opaque {}
+    fn forward_extern_ty(x: &Opaque) {
+        foo(x);
+        //~^ ERROR: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs
new file mode 100644
index 00000000000..49f2faba146
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs
@@ -0,0 +1,61 @@
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(
+    auto_traits,
+    lang_items,
+    more_maybe_bounds,
+    negative_impls,
+    no_core,
+    rustc_attrs
+)]
+#![allow(internal_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+pub trait Copy {}
+impl<'a, T: ?Sized> Copy for &'a T {}
+
+#[lang = "legacy_receiver"]
+trait Receiver {}
+impl<T: ?Sized + ?Leak> Receiver for &T {}
+
+#[lang = "unsize"]
+trait Unsize<T: ?Sized + ?Leak> {}
+
+#[lang = "coerce_unsized"]
+trait CoerceUnsized<T: ?Leak + ?Sized> {}
+impl<'a, 'b: 'a, T: ?Sized + ?Leak + Unsize<U>, U: ?Sized + ?Leak> CoerceUnsized<&'a U> for &'b T {}
+
+#[lang = "dispatch_from_dyn"]
+trait DispatchFromDyn<T: ?Leak> {}
+impl<'a, T: ?Sized + ?Leak + Unsize<U>, U: ?Sized + ?Leak> DispatchFromDyn<&'a U> for &'a T {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+struct NonLeakS;
+impl !Leak for NonLeakS {}
+struct LeakS;
+
+trait Trait {
+    fn leak_foo(&self) {}
+    fn maybe_leak_foo(&self) where Self: ?Leak {}
+}
+
+impl Trait for NonLeakS {}
+impl Trait for LeakS {}
+
+fn main() {
+    let _: &dyn Trait = &NonLeakS;
+    //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
+    let _: &dyn Trait = &LeakS;
+    let _: &(dyn Trait + ?Leak) = &LeakS;
+    let x: &(dyn Trait + ?Leak) = &NonLeakS;
+    x.leak_foo();
+    //~^ ERROR the trait bound `dyn Trait: Leak` is not satisfied
+    x.maybe_leak_foo();
+}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr
new file mode 100644
index 00000000000..b7ffb66e60b
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:53:25
+   |
+LL |     let _: &dyn Trait = &NonLeakS;
+   |                         ^^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS`
+   |
+   = note: required for the cast from `&NonLeakS` to `&dyn Trait + Leak`
+
+error[E0277]: the trait bound `dyn Trait: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:58:7
+   |
+LL |     x.leak_foo();
+   |       ^^^^^^^^ the trait `Leak` is not implemented for `dyn Trait`
+   |
+note: required by a bound in `Trait::leak_foo`
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:45:5
+   |
+LL |     fn leak_foo(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs
new file mode 100644
index 00000000000..761f22d1be5
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs
@@ -0,0 +1,115 @@
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(
+    auto_traits,
+    associated_type_defaults,
+    generic_const_items,
+    lang_items,
+    more_maybe_bounds,
+    negative_impls,
+    no_core,
+    rustc_attrs
+)]
+#![allow(incomplete_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "legacy_receiver"]
+trait LegacyReceiver {}
+impl<T: ?Sized + ?Leak> LegacyReceiver for &T {}
+impl<T: ?Sized> LegacyReceiver for &mut T {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+struct NonLeakS;
+impl !Leak for NonLeakS {}
+struct LeakS;
+
+mod supertraits {
+    use crate::*;
+
+    trait MaybeLeakT1: ?Leak {}
+    trait MaybeLeakT2 where Self: ?Leak {}
+
+    impl MaybeLeakT1 for NonLeakS {}
+    impl MaybeLeakT2 for NonLeakS {}
+}
+
+mod maybe_self_assoc_type {
+    use crate::*;
+
+    trait TestBase1<T: ?Sized> {}
+    trait TestBase2<T: ?Leak + ?Sized> {}
+
+    trait Test1<T> {
+        type MaybeLeakSelf: TestBase1<Self> where Self: ?Leak;
+        //~^ ERROR the trait bound `Self: Leak` is not satisfied
+        type LeakSelf: TestBase1<Self>;
+    }
+
+    trait Test2<T> {
+        type MaybeLeakSelf: TestBase2<Self> where Self: ?Leak;
+        type LeakSelf: TestBase2<Self>;
+    }
+
+    trait Test3 {
+        type Leak1 = LeakS;
+        type Leak2 = NonLeakS;
+        //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
+    }
+
+    trait Test4 {
+        type MaybeLeak1: ?Leak = LeakS;
+        type MaybeLeak2: ?Leak = NonLeakS;
+    }
+
+    trait Test5: ?Leak {
+        // ok, because assoc types have implicit where Self: Leak
+        type MaybeLeakSelf1: TestBase1<Self>;
+        type MaybeLeakSelf2: TestBase2<Self>;
+    }
+}
+
+mod maybe_self_assoc_const {
+    use crate::*;
+
+    const fn size_of<T: ?Sized>() -> usize {
+        0
+    }
+
+    trait Trait {
+        const CLeak: usize = size_of::<Self>();
+        const CNonLeak: usize = size_of::<Self>() where Self: ?Leak;
+        //~^ ERROR the trait bound `Self: Leak` is not satisfied
+    }
+}
+
+mod methods {
+    use crate::*;
+
+    trait Trait {
+        fn leak_foo(&self) {}
+        fn maybe_leak_foo(&self) where Self: ?Leak {}
+        fn mut_leak_foo(&mut self) {}
+        // there is no relax bound on corresponding Receiver impl
+        fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {}
+        //~^  `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types`
+    }
+
+    impl Trait for NonLeakS {}
+    impl Trait for LeakS {}
+
+    fn foo() {
+        LeakS.leak_foo();
+        LeakS.maybe_leak_foo();
+        NonLeakS.leak_foo();
+        //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
+        NonLeakS.maybe_leak_foo();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr
new file mode 100644
index 00000000000..3dd8418b100
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr
@@ -0,0 +1,71 @@
+error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:61:22
+   |
+LL |         type Leak2 = NonLeakS;
+   |                      ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS`
+   |
+note: required by a bound in `Test3::Leak2`
+  --> $DIR/maybe-bounds-in-traits.rs:61:9
+   |
+LL |         type Leak2 = NonLeakS;
+   |         ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test3::Leak2`
+
+error[E0277]: the trait bound `Self: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:49:29
+   |
+LL |         type MaybeLeakSelf: TestBase1<Self> where Self: ?Leak;
+   |                             ^^^^^^^^^^^^^^^ the trait `Leak` is not implemented for `Self`
+   |
+note: required by a bound in `TestBase1`
+  --> $DIR/maybe-bounds-in-traits.rs:45:21
+   |
+LL |     trait TestBase1<T: ?Sized> {}
+   |                     ^ required by this bound in `TestBase1`
+help: consider further restricting `Self`
+   |
+LL |     trait Test1<T>: Leak {
+   |                   ++++++
+
+error[E0658]: `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+  --> $DIR/maybe-bounds-in-traits.rs:99:31
+   |
+LL |         fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {}
+   |                               ^^^^^^^^^
+   |
+   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
+
+error[E0277]: the trait bound `Self: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:86:43
+   |
+LL |         const CNonLeak: usize = size_of::<Self>() where Self: ?Leak;
+   |                                           ^^^^ the trait `Leak` is not implemented for `Self`
+   |
+note: required by a bound in `size_of`
+  --> $DIR/maybe-bounds-in-traits.rs:80:22
+   |
+LL |     const fn size_of<T: ?Sized>() -> usize {
+   |                      ^ required by this bound in `size_of`
+help: consider further restricting `Self`
+   |
+LL |     trait Trait: Leak {
+   |                ++++++
+
+error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:109:18
+   |
+LL |         NonLeakS.leak_foo();
+   |                  ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS`
+   |
+note: required by a bound in `methods::Trait::leak_foo`
+  --> $DIR/maybe-bounds-in-traits.rs:95:9
+   |
+LL |         fn leak_foo(&self) {}
+   |         ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/incomplete-infer-via-sized-wc.current.stderr b/tests/ui/traits/incomplete-infer-via-sized-wc.current.stderr
new file mode 100644
index 00000000000..f4930bf890c
--- /dev/null
+++ b/tests/ui/traits/incomplete-infer-via-sized-wc.current.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/incomplete-infer-via-sized-wc.rs:15:5
+   |
+LL |     is_sized::<MaybeSized<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `is_sized`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/traits/incomplete-infer-via-sized-wc.next.stderr b/tests/ui/traits/incomplete-infer-via-sized-wc.next.stderr
new file mode 100644
index 00000000000..f4930bf890c
--- /dev/null
+++ b/tests/ui/traits/incomplete-infer-via-sized-wc.next.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/incomplete-infer-via-sized-wc.rs:15:5
+   |
+LL |     is_sized::<MaybeSized<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `is_sized`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/traits/incomplete-infer-via-sized-wc.rs b/tests/ui/traits/incomplete-infer-via-sized-wc.rs
new file mode 100644
index 00000000000..9dcddea3551
--- /dev/null
+++ b/tests/ui/traits/incomplete-infer-via-sized-wc.rs
@@ -0,0 +1,19 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Exercises change in <https://github.com/rust-lang/rust/pull/138176>.
+
+struct MaybeSized<T: ?Sized>(T);
+
+fn is_sized<T: Sized>() -> Box<T> { todo!() }
+
+fn foo<T: ?Sized>()
+where
+    MaybeSized<T>: Sized,
+{
+    is_sized::<MaybeSized<_>>();
+    //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc-2.rs b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc-2.rs
new file mode 100644
index 00000000000..8a8f7b933b5
--- /dev/null
+++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc-2.rs
@@ -0,0 +1,28 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Exercises change in <https://github.com/rust-lang/rust/pull/138176>.
+
+trait Trait<T>: Sized {}
+impl<T> Trait<T> for T {}
+
+fn is_sized<T: Sized>() {}
+
+fn normal_ref<'a, 'b, T>()
+where
+    &'a u32: Trait<T>,
+{
+    is_sized::<&'b u32>();
+}
+
+struct MyRef<'a, U: ?Sized = ()>(&'a u32, U);
+fn my_ref<'a, 'b, T>()
+where
+    MyRef<'a>: Trait<T>,
+{
+    is_sized::<MyRef<'b>>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr
new file mode 100644
index 00000000000..dd9393fae85
--- /dev/null
+++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr
@@ -0,0 +1,27 @@
+error[E0308]: mismatched types
+  --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23
+   |
+LL |     (MyType<'a, T>,): Sized,
+   |                       ^^^^^ lifetime mismatch
+   |
+   = note: expected trait `<MyType<'a, T> as Sized>`
+              found trait `<MyType<'static, T> as Sized>`
+note: the lifetime `'a` as defined here...
+  --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8
+   |
+LL | fn foo<'a, T: ?Sized>()
+   |        ^^
+   = note: ...does not necessarily outlive the static lifetime
+
+error: lifetime may not live long enough
+  --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5
+   |
+LL | fn foo<'a, T: ?Sized>()
+   |        -- lifetime `'a` defined here
+...
+LL |     is_sized::<(MyType<'a, T>,)>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr
new file mode 100644
index 00000000000..05861877d41
--- /dev/null
+++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr
@@ -0,0 +1,25 @@
+error[E0478]: lifetime bound not satisfied
+  --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23
+   |
+LL |     (MyType<'a, T>,): Sized,
+   |                       ^^^^^
+   |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+  --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8
+   |
+LL | fn foo<'a, T: ?Sized>()
+   |        ^^
+   = note: but lifetime parameter must outlive the static lifetime
+
+error: lifetime may not live long enough
+  --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5
+   |
+LL | fn foo<'a, T: ?Sized>()
+   |        -- lifetime `'a` defined here
+...
+LL |     is_sized::<(MyType<'a, T>,)>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs
new file mode 100644
index 00000000000..ae7a6c9bba3
--- /dev/null
+++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs
@@ -0,0 +1,26 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Exercises change in <https://github.com/rust-lang/rust/pull/138176>.
+
+struct MyType<'a, T: ?Sized>(&'a (), T);
+
+fn is_sized<T>() {}
+
+fn foo<'a, T: ?Sized>()
+where
+    (MyType<'a, T>,): Sized,
+    //[current]~^ ERROR mismatched types
+    //[next]~^^ ERROR lifetime bound not satisfied
+    MyType<'static, T>: Sized,
+{
+    // Preferring the builtin `Sized` impl of tuples
+    // requires proving `MyType<'a, T>: Sized` which
+    // can only be proven by using the where-clause,
+    // adding an unnecessary `'static` constraint.
+    is_sized::<(MyType<'a, T>,)>();
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/traits/mutual-recursion-issue-75860.stderr b/tests/ui/traits/mutual-recursion-issue-75860.stderr
index 272c56301bc..9e8eb1adb11 100644
--- a/tests/ui/traits/mutual-recursion-issue-75860.stderr
+++ b/tests/ui/traits/mutual-recursion-issue-75860.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow assigning `_` to `Option<_>`
   --> $DIR/mutual-recursion-issue-75860.rs:9:33
    |
 LL |     let left = |o_a: Option<_>| o_a.unwrap();
-   |                                 ^^^
+   |                                 ^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/crashes/132335.rs b/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs
index 2294539cfcf..e5208e3e47d 100644
--- a/tests/crashes/132335.rs
+++ b/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs
@@ -1,5 +1,8 @@
-//@ known-bug: #132335
+// Regression test for #132335. This previously ICE'd due to ambiguity
+// in MIR typeck.
+
 //@ compile-flags: -Znext-solver=globally --crate-type lib --edition=2018
+//@ check-pass
 use core::future::Future;
 use core::pin::Pin;
 
diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr
index 5625cb24d42..ff0afd319d9 100644
--- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr
+++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr
@@ -1,34 +1,54 @@
-error: unconstrained opaque type
+error: item does not constrain `ex1::Tait1::{opaque#0}`
+  --> $DIR/no-define-in-wf-check.rs:21:8
+   |
+LL |     fn foo(x: Tait1) -> impl Sized {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/no-define-in-wf-check.rs:19:18
    |
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
-   |
-   = note: `Tait1` must be used in combination with a concrete type within the same crate
 
-error: unconstrained opaque type
+error: item does not constrain `ex2::Tait1::{opaque#0}`
+  --> $DIR/no-define-in-wf-check.rs:31:8
+   |
+LL |     fn foo(x: Tait1) -> Tait2 {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/no-define-in-wf-check.rs:28:18
    |
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
-   |
-   = note: `Tait1` must be used in combination with a concrete type within the same crate
 
-error: unconstrained opaque type
+error: item does not constrain `ex3::Tait1::{opaque#0}`
+  --> $DIR/no-define-in-wf-check.rs:43:8
+   |
+LL |     fn foo(x: Tait1) -> Tait2 {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/no-define-in-wf-check.rs:38:18
    |
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
-   |
-   = note: `Tait1` must be used in combination with a concrete type within the same crate
 
-error: unconstrained opaque type
+error: item does not constrain `ex4::Tait1::{opaque#0}`
+  --> $DIR/no-define-in-wf-check.rs:64:8
+   |
+LL |     fn foo(x: Tait1) -> Tait2 {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/no-define-in-wf-check.rs:50:18
    |
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
-   |
-   = note: `Tait1` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs
index 31d07d89d8d..26c17edeb93 100644
--- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs
+++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs
@@ -17,38 +17,37 @@ mod ex0 {
 }
 mod ex1 {
     type Tait1 = impl Sized;
-    //[current]~^ ERROR unconstrained opaque type
     #[define_opaque(Tait1)]
     fn foo(x: Tait1) -> impl Sized {
+        //[current]~^ ERROR item does not constrain `ex1::Tait1::{opaque#0}`
         let () = x;
     }
 }
 
 mod ex2 {
     type Tait1 = impl Sized;
-    //[current]~^ ERROR unconstrained opaque type
     type Tait2 = impl Sized;
     #[define_opaque(Tait1, Tait2)]
     fn foo(x: Tait1) -> Tait2 {
+        //[current]~^ ERROR item does not constrain `ex2::Tait1::{opaque#0}`
         let () = x;
     }
 }
 
 mod ex3 {
     type Tait1 = impl Sized;
-    //[current]~^ ERROR unconstrained opaque type
     trait Something<T> {}
     impl<T, U> Something<U> for T {}
     type Tait2 = impl Something<Tait1>;
     #[define_opaque(Tait1, Tait2)]
     fn foo(x: Tait1) -> Tait2 {
+        //[current]~^ ERROR item does not constrain `ex3::Tait1::{opaque#0}`
         let () = x;
     }
 }
 
 mod ex4 {
     type Tait1 = impl Sized;
-    //[current]~^ ERROR unconstrained opaque type
     trait Trait<U> {
         type Assoc;
     }
@@ -63,6 +62,7 @@ mod ex4 {
     type Tait2 = impl Trait<(), Assoc = impl Trait<Tait1>>;
     #[define_opaque(Tait1, Tait2)]
     fn foo(x: Tait1) -> Tait2 {
+        //[current]~^ ERROR item does not constrain `ex4::Tait1::{opaque#0}`
         let () = x;
     }
 }
diff --git a/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs b/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs
new file mode 100644
index 00000000000..8388751fea6
--- /dev/null
+++ b/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs
@@ -0,0 +1,11 @@
+// Regression test for #137751. This previously ICE'd as
+// we did not provide the hidden type of the opaque inside
+// of the async block. This caused borrowck of the recursive
+// call to ICE.
+
+//@ compile-flags: --edition=2021
+//@ check-pass
+async fn test() {
+    Box::pin(test()).await;
+}
+fn main() {}
diff --git a/tests/ui/traits/object/suggestion-trait-object-issue-139174.rs b/tests/ui/traits/object/suggestion-trait-object-issue-139174.rs
new file mode 100644
index 00000000000..f8fa410b7d4
--- /dev/null
+++ b/tests/ui/traits/object/suggestion-trait-object-issue-139174.rs
@@ -0,0 +1,24 @@
+//@compile-flags: --edition 2021
+
+fn f<'a>(x: Box<dyn Fn() -> Option<usize + 'a>>) -> usize {
+    //~^ ERROR expected trait, found builtin type `usize`
+    //~| ERROR expected a type, found a trait [E0782]
+    0
+}
+
+fn create_adder<'a>(x: i32) -> usize + 'a {
+    //~^ ERROR expected trait, found builtin type `usize`
+    //~| ERROR expected a type, found a trait [E0782]
+    move |y| x + y
+}
+
+struct Struct<'a>{
+    x: usize + 'a,
+    //~^ ERROR expected trait, found builtin type `usize`
+    //~| ERROR expected a type, found a trait [E0782]
+}
+
+
+fn main() {
+
+}
diff --git a/tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr b/tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr
new file mode 100644
index 00000000000..0d1ce85fc28
--- /dev/null
+++ b/tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr
@@ -0,0 +1,40 @@
+error[E0404]: expected trait, found builtin type `usize`
+  --> $DIR/suggestion-trait-object-issue-139174.rs:3:36
+   |
+LL | fn f<'a>(x: Box<dyn Fn() -> Option<usize + 'a>>) -> usize {
+   |                                    ^^^^^ not a trait
+
+error[E0404]: expected trait, found builtin type `usize`
+  --> $DIR/suggestion-trait-object-issue-139174.rs:9:32
+   |
+LL | fn create_adder<'a>(x: i32) -> usize + 'a {
+   |                                ^^^^^ not a trait
+
+error[E0404]: expected trait, found builtin type `usize`
+  --> $DIR/suggestion-trait-object-issue-139174.rs:16:8
+   |
+LL |     x: usize + 'a,
+   |        ^^^^^ not a trait
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/suggestion-trait-object-issue-139174.rs:3:36
+   |
+LL | fn f<'a>(x: Box<dyn Fn() -> Option<usize + 'a>>) -> usize {
+   |                                    ^^^^^^^^^^
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/suggestion-trait-object-issue-139174.rs:9:32
+   |
+LL | fn create_adder<'a>(x: i32) -> usize + 'a {
+   |                                ^^^^^^^^^^
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/suggestion-trait-object-issue-139174.rs:16:8
+   |
+LL |     x: usize + 'a,
+   |        ^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0404, E0782.
+For more information about an error, try `rustc --explain E0404`.
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
index 1f5d0a772a2..723179302e3 100644
--- a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
+++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
@@ -4,7 +4,6 @@
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[unique_next] compile-flags: -Znext-solver
 //@[multiple_next] compile-flags: -Znext-solver
-//@ error-pattern: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc`
 
 trait Bound {}
 trait Normalize {
@@ -25,3 +24,5 @@ struct Hello {
 }
 
 fn main() {}
+
+//~? ERROR reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc`
diff --git a/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs b/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs
index 0b75bb23faf..cfb2d7c5218 100644
--- a/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs
+++ b/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs
@@ -6,5 +6,5 @@
 
 fn main() {
     #[deny(while_true)]
-    while true {}
+    while true {} //~ ERROR denote infinite loops with `loop { ... }`
 }
diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
index 296bdd7a12d..a242d11129f 100644
--- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
@@ -8,5 +8,5 @@
 
 #![feature(rustc_attrs)]
 
-#[rustc_error(delayed_bug_from_inside_query)]
-fn main() {}
+#[rustc_delayed_bug_from_inside_query]
+fn main() {} //~ ERROR delayed bug triggered by #[rustc_delayed_bug_from_inside_query]
diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.stderr b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
index aec1b89c766..1c8d279c14c 100644
--- a/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
@@ -1,4 +1,4 @@
-error: internal compiler error: delayed bug triggered by #[rustc_error(delayed_bug_from_inside_query)]
+error: internal compiler error: delayed bug triggered by #[rustc_delayed_bug_from_inside_query]
   --> $DIR/span_delayed_bug.rs:12:1
    |
 LL | fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
index b6870b16450..5c93bd14d32 100644
--- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
@@ -12,7 +12,6 @@ pub enum UninhabitedVariants {
 
 #[define_opaque(Alias)]
 fn uwu(x: UninhabitedVariants) {
-    //~^ ERROR item does not constrain
     match x {}
     //~^ ERROR non-exhaustive patterns
 }
diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
index 59909197e7b..72fae0173cb 100644
--- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
@@ -26,21 +26,8 @@ help: add missing generic argument
 LL |     Tuple(Alias<U>),
    |                +++
 
-error: item does not constrain `Alias::{opaque#0}`
-  --> $DIR/bad-tait-no-substs.rs:14:4
-   |
-LL | fn uwu(x: UninhabitedVariants) {
-   |    ^^^
-   |
-   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
-note: this opaque type is supposed to be constrained
-  --> $DIR/bad-tait-no-substs.rs:5:21
-   |
-LL | type Alias<'a, U> = impl Trait<U>;
-   |                     ^^^^^^^^^^^^^
-
 error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` not covered
-  --> $DIR/bad-tait-no-substs.rs:16:11
+  --> $DIR/bad-tait-no-substs.rs:15:11
    |
 LL |     match x {}
    |           ^ pattern `UninhabitedVariants::Tuple(_)` not covered
@@ -60,7 +47,7 @@ LL +         UninhabitedVariants::Tuple(_) => todo!(),
 LL ~     }
    |
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0004, E0106, E0107.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.rs b/tests/ui/type-alias-impl-trait/bound_reduction2.rs
index 78288caffef..fadc2beba71 100644
--- a/tests/ui/type-alias-impl-trait/bound_reduction2.rs
+++ b/tests/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -14,6 +14,6 @@ impl<W> Trait<W> for () {}
 
 #[define_opaque(Foo)]
 fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-    ()
     //~^ ERROR expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
+    ()
 }
diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
index 289826cc1d0..53b20d61025 100644
--- a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
+++ b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -1,11 +1,11 @@
 error[E0792]: expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
-  --> $DIR/bound_reduction2.rs:17:5
+  --> $DIR/bound_reduction2.rs:16:46
    |
 LL | type Foo<V> = impl Trait<V>;
    |          - this generic parameter must be used with a generic type parameter
 ...
-LL |     ()
-   |     ^^
+LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
+   |                                              ^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs
index e56f60a6693..b5a9bf4a59f 100644
--- a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs
+++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs
@@ -9,7 +9,7 @@ fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> {
 
 #[define_opaque(Opaque)]
 fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
-    //~^ ERROR:  item does not constrain
+    //~^ ERROR item does not constrain `Opaque::{opaque#0}`
     None::<Opaque<'static>>
 }
 
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_defining_uses.rs
index 246f255e8fc..547696b83da 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses.rs
@@ -12,6 +12,6 @@ fn foo() -> Foo {
 
 #[define_opaque(Foo)]
 fn bar() -> Foo {
+    //~^ ERROR concrete type differs
     42i32
-    //~^ ERROR concrete type differs from previous
 }
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr
index 9a7f4b416f4..36d7e33dca0 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses.rs:15:5
+  --> $DIR/different_defining_uses.rs:14:13
    |
-LL |     42i32
-   |     ^^^^^ expected `&'static str`, got `i32`
+LL | fn bar() -> Foo {
+   |             ^^^ expected `&str`, got `i32`
    |
 note: previous use here
-  --> $DIR/different_defining_uses.rs:10:5
+  --> $DIR/different_defining_uses.rs:9:13
    |
-LL |     ""
-   |     ^^
+LL | fn foo() -> Foo {
+   |             ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
index e8c40e8bf92..bbbc2086bdf 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
@@ -12,7 +12,6 @@ fn foo<'a, 'b>() -> Tait<'a> {
     }
     let x: Tait<'a> = ();
     x
-    //~^ ERROR concrete type differs from previous defining opaque type use
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
index d4bd3975924..4d7dd6b2ad5 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
@@ -1,26 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses_never_type-2.rs:14:5
-   |
-LL |     x
-   |     ^ expected `i32`, got `()`
-   |
-note: previous use here
-  --> $DIR/different_defining_uses_never_type-2.rs:9:31
-   |
-LL |             let y: Tait<'b> = 1i32;
-   |                               ^^^^
-
-error: concrete type differs from previous defining opaque type use
   --> $DIR/different_defining_uses_never_type-2.rs:9:31
    |
 LL |             let y: Tait<'b> = 1i32;
    |                               ^^^^ expected `()`, got `i32`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type-2.rs:8:14
+  --> $DIR/different_defining_uses_never_type-2.rs:14:5
    |
-LL |         if { return } {
-   |              ^^^^^^
+LL |     x
+   |     ^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
index cb12fddd9a0..eb9001cc624 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
@@ -5,10 +5,10 @@ LL |             let y: Tait<U> = 1i32;
    |                              ^^^^ expected `()`, got `i32`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type-3.rs:13:22
+  --> $DIR/different_defining_uses_never_type-3.rs:14:5
    |
-LL |     let x: Tait<T> = ();
-   |                      ^^
+LL |     x
+   |     ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
index 38afa3cbcd0..0914dd1c546 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
@@ -2,13 +2,13 @@ error: concrete type differs from previous defining opaque type use
   --> $DIR/different_defining_uses_never_type.rs:14:13
    |
 LL | fn bar() -> Foo {
-   |             ^^^ expected `&'static str`, got `()`
+   |             ^^^ expected `&str`, got `()`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type.rs:10:5
+  --> $DIR/different_defining_uses_never_type.rs:9:13
    |
-LL |     ""
-   |     ^^
+LL | fn foo() -> Foo {
+   |             ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
index 21fab818063..78a9f6b6365 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
@@ -5,10 +5,10 @@ LL | fn two() -> Tait { Two::<()>(todo!()) }
    |             ^^^^ expected `One`, got `Two<()>`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type3.rs:7:20
+  --> $DIR/different_defining_uses_never_type3.rs:7:13
    |
 LL | fn one() -> Tait { One }
-   |                    ^^^
+   |             ^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs
index 726820bbd5a..c2578297006 100644
--- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs
+++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs
@@ -31,7 +31,6 @@ impl<F: for<'a> Fn(&'a ()) -> StateWidget<'a>> Widget<()> for StatefulWidget<F>
 fn new_stateful_widget<F: for<'a> Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> {
     //~^ ERROR item does not constrain
     StatefulWidget(build)
-    //~^ ERROR expected generic lifetime parameter, found `'a`
 }
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr
index 4f5c65adab9..dee729e1f9f 100644
--- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr
+++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr
@@ -24,17 +24,8 @@ note: this opaque type is supposed to be constrained
 LL | type StateWidget<'a> = impl Widget<&'a ()>;
    |                        ^^^^^^^^^^^^^^^^^^^
 
-error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/failed-to-normalize-ice-99945.rs:33:5
-   |
-LL | type StateWidget<'a> = impl Widget<&'a ()>;
-   |                  -- this generic parameter must be used with a generic lifetime parameter
-...
-LL |     StatefulWidget(build)
-   |     ^^^^^^^^^^^^^^^^^^^^^
-
 error[E0308]: mismatched types
-  --> $DIR/failed-to-normalize-ice-99945.rs:38:29
+  --> $DIR/failed-to-normalize-ice-99945.rs:37:29
    |
 LL | type StateWidget<'a> = impl Widget<&'a ()>;
    |                        ------------------- the expected opaque type
@@ -45,7 +36,6 @@ LL |     new_stateful_widget(|_| ()).make_state();
    = note: expected opaque type `StateWidget<'_>`
                 found unit type `()`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0308, E0792.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs
index d55a9a376b9..41fb6fe8587 100644
--- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs
+++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs
@@ -11,6 +11,6 @@ fn my_iter<T>(t: T) -> MyIter<T> {
 
 #[define_opaque(MyIter)]
 fn my_iter2<T>(t: T) -> MyIter<T> {
-    Some(t).into_iter()
     //~^ ERROR concrete type differs from previous
+    Some(t).into_iter()
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
index 6d3279144d8..b4be8542163 100644
--- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_different_defining_uses.rs:14:5
+  --> $DIR/generic_different_defining_uses.rs:13:25
    |
-LL |     Some(t).into_iter()
-   |     ^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once<T>`, got `std::option::IntoIter<T>`
+LL | fn my_iter2<T>(t: T) -> MyIter<T> {
+   |                         ^^^^^^^^^ expected `std::iter::Once<T>`, got `std::option::IntoIter<T>`
    |
 note: previous use here
-  --> $DIR/generic_different_defining_uses.rs:9:5
+  --> $DIR/generic_different_defining_uses.rs:8:24
    |
-LL |     std::iter::once(t)
-   |     ^^^^^^^^^^^^^^^^^^
+LL | fn my_iter<T>(t: T) -> MyIter<T> {
+   |                        ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
index e8ed38a24ce..6e791a3bdb9 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
@@ -20,8 +20,8 @@ type TwoConsts<const X: usize, const Y: usize> = impl Debug;
 
 #[define_opaque(TwoTys)]
 fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
-    t
     //~^ ERROR non-defining opaque type use in defining scope
+    t
 }
 
 #[define_opaque(TwoLifetimes)]
@@ -32,6 +32,6 @@ fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
 
 #[define_opaque(TwoConsts)]
 fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
-    t
     //~^ ERROR non-defining opaque type use in defining scope
+    t
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
index 3e048c8138d..022e534df1a 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
@@ -1,8 +1,8 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use.rs:23:5
+  --> $DIR/generic_duplicate_param_use.rs:22:30
    |
-LL |     t
-   |     ^
+LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+   |                              ^^^^^^^^^^^^
    |
 note: type used multiple times
   --> $DIR/generic_duplicate_param_use.rs:15:13
@@ -23,10 +23,10 @@ LL | type TwoLifetimes<'a, 'b> = impl Debug;
    |                   ^^  ^^
 
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use.rs:35:5
+  --> $DIR/generic_duplicate_param_use.rs:34:50
    |
-LL |     t
-   |     ^
+LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+   |                                                  ^^^^^^^^^^^^^^^
    |
 note: constant used multiple times
   --> $DIR/generic_duplicate_param_use.rs:19:16
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
index f732b233396..873c7b614b6 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
@@ -14,6 +14,6 @@ fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
 
 #[define_opaque(Two)]
 fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
-    u
     //~^ ERROR concrete type differs
+    u
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
index b0a1bd77f85..3f5f2c93c59 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use3.rs:17:5
+  --> $DIR/generic_duplicate_param_use3.rs:16:38
    |
-LL |     u
-   |     ^ expected `T`, got `U`
+LL | fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
+   |                                      ^^^^^^^^^ expected `T`, got `U`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use3.rs:12:5
+  --> $DIR/generic_duplicate_param_use3.rs:11:36
    |
-LL |     t
-   |     ^
+LL | fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+   |                                    ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
index d450bef5758..1d4d3ab737f 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
@@ -14,6 +14,6 @@ fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
 
 #[define_opaque(Two)]
 fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
-    (u, t)
     //~^ ERROR concrete type differs
+    (u, t)
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
index b8a2a937416..59b37a8b792 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use5.rs:17:5
+  --> $DIR/generic_duplicate_param_use5.rs:16:45
    |
-LL |     (u, t)
-   |     ^^^^^^ expected `(T, U)`, got `(U, T)`
+LL | fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+   |                                             ^^^^^^^^^ expected `(T, U)`, got `(U, T)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use5.rs:12:5
+  --> $DIR/generic_duplicate_param_use5.rs:11:43
    |
-LL |     (t, u)
-   |     ^^^^^^
+LL | fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+   |                                           ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
index 24d03b9e60d..961e2910dbe 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
@@ -14,6 +14,6 @@ fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
 
 #[define_opaque(Two)]
 fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
-    (u, t)
     //~^ ERROR concrete type differs
+    (u, t)
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
index 983e58d3c70..0940d6f541f 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use6.rs:17:5
+  --> $DIR/generic_duplicate_param_use6.rs:16:52
    |
-LL |     (u, t)
-   |     ^^^^^^ expected `(T, T)`, got `(U, T)`
+LL | fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+   |                                                    ^^^^^^^^^ expected `(T, T)`, got `(U, T)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use6.rs:12:5
+  --> $DIR/generic_duplicate_param_use6.rs:11:50
    |
-LL |     (t, t)
-   |     ^^^^^^
+LL | fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+   |                                                  ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
index 03057c84782..d01cc7ff04e 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
@@ -13,6 +13,6 @@ fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
 
 #[define_opaque(Two)]
 fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
-    (u, 4u32)
     //~^ concrete type differs
+    (u, 4u32)
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
index 48c98c1e2b1..f9615d455d1 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use8.rs:16:5
+  --> $DIR/generic_duplicate_param_use8.rs:15:45
    |
-LL |     (u, 4u32)
-   |     ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)`
+LL | fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
+   |                                             ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use8.rs:11:5
+  --> $DIR/generic_duplicate_param_use8.rs:10:43
    |
-LL |     (t, 4u32)
-   |     ^^^^^^^^^
+LL | fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
+   |                                           ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
index 74176550ab2..ec03ff1675e 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
@@ -18,6 +18,6 @@ fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
 
 #[define_opaque(Two)]
 fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
-    (t, u, 42)
     //~^ ERROR concrete type differs
+    (t, u, 42)
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
index 542324c949f..df9984cd073 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use9.rs:21:5
+  --> $DIR/generic_duplicate_param_use9.rs:20:45
    |
-LL |     (t, u, 42)
-   |     ^^^^^^^^^^ expected `(A, B, <A as Foo>::Bar)`, got `(A, B, i32)`
+LL | fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+   |                                             ^^^^^^^^^ expected `(A, B, <A as Foo>::Bar)`, got `(A, B, i32)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use9.rs:16:5
+  --> $DIR/generic_duplicate_param_use9.rs:15:49
    |
-LL |     (t, u, T::BAR)
-   |     ^^^^^^^^^^^^^^
+LL | fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
+   |                                                 ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
index 7791410294c..cf38c93bd92 100644
--- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
@@ -14,8 +14,8 @@ type OneConst<const X: usize> = impl Debug;
 
 #[define_opaque(OneTy)]
 fn concrete_ty() -> OneTy<u32> {
-    5u32
     //~^ ERROR: expected generic type parameter, found `u32`
+    5u32
 }
 
 #[define_opaque(OneLifetime)]
@@ -26,6 +26,6 @@ fn concrete_lifetime() -> OneLifetime<'static> {
 
 #[define_opaque(OneConst)]
 fn concrete_const() -> OneConst<{ 123 }> {
-    7u32
     //~^ ERROR: expected generic constant parameter, found `123`
+    7u32
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
index 1b0ce7cc619..71e415271ee 100644
--- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
@@ -1,11 +1,11 @@
 error[E0792]: expected generic type parameter, found `u32`
-  --> $DIR/generic_nondefining_use.rs:17:5
+  --> $DIR/generic_nondefining_use.rs:16:21
    |
 LL | type OneTy<T> = impl Debug;
    |            - this generic parameter must be used with a generic type parameter
 ...
-LL |     5u32
-   |     ^^^^
+LL | fn concrete_ty() -> OneTy<u32> {
+   |                     ^^^^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'static`
   --> $DIR/generic_nondefining_use.rs:23:5
@@ -17,13 +17,13 @@ LL |     6u32
    |     ^^^^
 
 error[E0792]: expected generic constant parameter, found `123`
-  --> $DIR/generic_nondefining_use.rs:29:5
+  --> $DIR/generic_nondefining_use.rs:28:24
    |
 LL | type OneConst<const X: usize> = impl Debug;
    |               -------------- this generic parameter must be used with a generic constant parameter
 ...
-LL |     7u32
-   |     ^^^^
+LL | fn concrete_const() -> OneConst<{ 123 }> {
+   |                        ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.rs b/tests/ui/type-alias-impl-trait/generic_not_used.rs
index 6042cdd30a9..f270f65f43e 100644
--- a/tests/ui/type-alias-impl-trait/generic_not_used.rs
+++ b/tests/ui/type-alias-impl-trait/generic_not_used.rs
@@ -7,6 +7,6 @@ type WrongGeneric<T: 'static> = impl 'static;
 
 #[define_opaque(WrongGeneric)]
 fn wrong_generic<U: 'static, V: 'static>(_: U, v: V) -> WrongGeneric<U> {
-    v
     //~^ ERROR type parameter `V` is part of concrete type but not used in parameter list
+    v
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.stderr b/tests/ui/type-alias-impl-trait/generic_not_used.stderr
index 5fe2fefcecf..a480040006e 100644
--- a/tests/ui/type-alias-impl-trait/generic_not_used.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_not_used.stderr
@@ -5,10 +5,10 @@ LL | type WrongGeneric<T: 'static> = impl 'static;
    |                                 ^^^^^^^^^^^^
 
 error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/generic_not_used.rs:10:5
+  --> $DIR/generic_not_used.rs:9:57
    |
-LL |     v
-   |     ^
+LL | fn wrong_generic<U: 'static, V: 'static>(_: U, v: V) -> WrongGeneric<U> {
+   |                                                         ^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
index cbd8150d117..4b4db8ec2ed 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
@@ -10,18 +10,15 @@ use std::future::Future;
 type FutNothing<'a> = impl 'a + Future<Output = ()>;
 
 async fn operation(_: &mut ()) -> () {
-    //~^ ERROR: concrete type differs from previous
     call(operation).await
-    //~^ ERROR: expected generic lifetime parameter, found `'any`
+    //~^ ERROR: concrete type differs from previous
 }
 
 #[define_opaque(FutNothing)]
 async fn call<F>(_f: F)
-//~^ ERROR item does not constrain
+//~^ ERROR item does not constrain `FutNothing::{opaque#0}`
 where
     for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>,
-{
-    //~^ ERROR: expected generic lifetime parameter, found `'any`
-}
+{}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
index 2c0be0cbcdc..2aacf969837 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
@@ -1,5 +1,5 @@
 error: item does not constrain `FutNothing::{opaque#0}`
-  --> $DIR/hkl_forbidden4.rs:19:10
+  --> $DIR/hkl_forbidden4.rs:18:10
    |
 LL | async fn call<F>(_f: F)
    |          ^^^^
@@ -12,37 +12,16 @@ LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/hkl_forbidden4.rs:12:1
+  --> $DIR/hkl_forbidden4.rs:13:5
    |
-LL | async fn operation(_: &mut ()) -> () {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body of operation()}`
+LL |     call(operation).await
+   |     ^^^^^^^^^^^^^^^ expected `{async fn body of operation()}`, got `FutNothing<'_>`
    |
 note: previous use here
-  --> $DIR/hkl_forbidden4.rs:14:5
-   |
-LL |     call(operation).await
-   |     ^^^^^^^^^^^^^^^
-
-error[E0792]: expected generic lifetime parameter, found `'any`
-  --> $DIR/hkl_forbidden4.rs:14:5
+  --> $DIR/hkl_forbidden4.rs:12:1
    |
 LL | async fn operation(_: &mut ()) -> () {
-   |                       - this generic parameter must be used with a generic lifetime parameter
-LL |
-LL |     call(operation).await
-   |     ^^^^^^^^^^^^^^^
-
-error[E0792]: expected generic lifetime parameter, found `'any`
-  --> $DIR/hkl_forbidden4.rs:23:1
-   |
-LL |   type FutNothing<'a> = impl 'a + Future<Output = ()>;
-   |                   -- this generic parameter must be used with a generic lifetime parameter
-...
-LL | / {
-LL | |
-LL | | }
-   | |_^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
index 114cac64573..9fcb26c20a6 100644
--- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
@@ -20,6 +20,41 @@ error[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}`
 LL | type Bar = impl Sized;
    |            ^^^^^^^^^^
    |
+note: ...which requires borrow-checking `foo`...
+  --> $DIR/in-where-clause.rs:9:1
+   |
+LL | / fn foo() -> Bar
+LL | | where
+LL | |     Bar: Send,
+   | |______________^
+note: ...which requires promoting constants in MIR for `foo`...
+  --> $DIR/in-where-clause.rs:9:1
+   |
+LL | / fn foo() -> Bar
+LL | | where
+LL | |     Bar: Send,
+   | |______________^
+note: ...which requires checking if `foo` contains FFI-unwind calls...
+  --> $DIR/in-where-clause.rs:9:1
+   |
+LL | / fn foo() -> Bar
+LL | | where
+LL | |     Bar: Send,
+   | |______________^
+note: ...which requires building MIR for `foo`...
+  --> $DIR/in-where-clause.rs:9:1
+   |
+LL | / fn foo() -> Bar
+LL | | where
+LL | |     Bar: Send,
+   | |______________^
+note: ...which requires match-checking `foo`...
+  --> $DIR/in-where-clause.rs:9:1
+   |
+LL | / fn foo() -> Bar
+LL | | where
+LL | |     Bar: Send,
+   | |______________^
 note: ...which requires type-checking `foo`...
   --> $DIR/in-where-clause.rs:9:1
    |
diff --git a/tests/ui/type-alias-impl-trait/issue-109054.rs b/tests/ui/type-alias-impl-trait/issue-109054.rs
index 0c9304a42f3..a8bb5ee3301 100644
--- a/tests/ui/type-alias-impl-trait/issue-109054.rs
+++ b/tests/ui/type-alias-impl-trait/issue-109054.rs
@@ -18,7 +18,7 @@ impl std::ops::Deref for CallMe {
             async move { *val * 2 }
         }
 
-        &inner //~ ERROR: expected generic lifetime parameter, found `'_`
+        &inner
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/issue-109054.stderr b/tests/ui/type-alias-impl-trait/issue-109054.stderr
index 919b0a287c4..5ce6f54e5f9 100644
--- a/tests/ui/type-alias-impl-trait/issue-109054.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-109054.stderr
@@ -11,15 +11,5 @@ note: this opaque type is supposed to be constrained
 LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/issue-109054.rs:21:9
-   |
-LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
-   |                 -- this generic parameter must be used with a generic lifetime parameter
-...
-LL |         &inner
-   |         ^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
index 3062e55dc49..c8db9fdfc57 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
@@ -9,6 +9,31 @@ note: ...which requires computing type of opaque `Bug::{opaque#0}`...
    |
 LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
    |                  ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires borrow-checking `CONST_BUG`...
+  --> $DIR/issue-53092-2.rs:8:1
+   |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires promoting constants in MIR for `CONST_BUG`...
+  --> $DIR/issue-53092-2.rs:8:1
+   |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const checking `CONST_BUG`...
+  --> $DIR/issue-53092-2.rs:8:1
+   |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires building MIR for `CONST_BUG`...
+  --> $DIR/issue-53092-2.rs:8:1
+   |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires match-checking `CONST_BUG`...
+  --> $DIR/issue-53092-2.rs:8:1
+   |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `CONST_BUG`...
   --> $DIR/issue-53092-2.rs:8:1
    |
diff --git a/tests/ui/type-alias-impl-trait/issue-53096.rs b/tests/ui/type-alias-impl-trait/issue-53096.rs
index c24f1bf44fa..60e455a6a07 100644
--- a/tests/ui/type-alias-impl-trait/issue-53096.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53096.rs
@@ -1,4 +1,5 @@
-#![feature(rustc_attrs)]
+//@ check-pass
+
 #![feature(type_alias_impl_trait)]
 
 pub type Foo = impl Fn() -> usize;
@@ -8,5 +9,4 @@ pub const fn bar() -> Foo {
 }
 const BAZR: Foo = bar();
 
-#[rustc_error]
-fn main() {} //~ ERROR
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-53096.stderr b/tests/ui/type-alias-impl-trait/issue-53096.stderr
deleted file mode 100644
index 53490896af7..00000000000
--- a/tests/ui/type-alias-impl-trait/issue-53096.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-53096.rs:12:1
-   |
-LL | fn main() {}
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/type-alias-impl-trait/issue-53598.rs b/tests/ui/type-alias-impl-trait/issue-53598.rs
index e3e2787b66b..3262c69cf5a 100644
--- a/tests/ui/type-alias-impl-trait/issue-53598.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53598.rs
@@ -17,8 +17,8 @@ impl Foo for S2 {
     type Item = impl Debug;
 
     fn foo<T: Debug>(_: T) -> Self::Item {
-        S::<T>(Default::default())
         //~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+        S::<T>(Default::default())
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/issue-53598.stderr b/tests/ui/type-alias-impl-trait/issue-53598.stderr
index a31aabedba5..f1dd3c69443 100644
--- a/tests/ui/type-alias-impl-trait/issue-53598.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-53598.stderr
@@ -1,8 +1,8 @@
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-53598.rs:20:9
+  --> $DIR/issue-53598.rs:19:31
    |
-LL |         S::<T>(Default::default())
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn foo<T: Debug>(_: T) -> Self::Item {
+   |                               ^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/issue-60407.rs b/tests/ui/type-alias-impl-trait/issue-60407.rs
index 5b8ff6b74de..53280c28ecb 100644
--- a/tests/ui/type-alias-impl-trait/issue-60407.rs
+++ b/tests/ui/type-alias-impl-trait/issue-60407.rs
@@ -1,4 +1,6 @@
-#![feature(type_alias_impl_trait, rustc_attrs)]
+//@ check-pass
+
+#![feature(type_alias_impl_trait)]
 
 pub type Debuggable = impl core::fmt::Debug;
 
@@ -9,8 +11,6 @@ pub fn foo() -> Debuggable {
 
 static mut TEST: Option<Debuggable> = None;
 
-#[rustc_error]
 fn main() {
-    //~^ ERROR
     unsafe { TEST = Some(foo()) }
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-60407.stderr b/tests/ui/type-alias-impl-trait/issue-60407.stderr
deleted file mode 100644
index f517d5b65fa..00000000000
--- a/tests/ui/type-alias-impl-trait/issue-60407.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-60407.rs:13:1
-   |
-LL | fn main() {
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/type-alias-impl-trait/issue-60564.rs b/tests/ui/type-alias-impl-trait/issue-60564.rs
index f28258b3b22..ae9a4d02670 100644
--- a/tests/ui/type-alias-impl-trait/issue-60564.rs
+++ b/tests/ui/type-alias-impl-trait/issue-60564.rs
@@ -18,8 +18,8 @@ where
     type BitsIter = IterBitsIter<T, E, u8>;
     #[define_opaque(IterBitsIter)]
     fn iter_bits(self, n: u8) -> Self::BitsIter {
-        (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
         //~^ ERROR expected generic type parameter, found `u8`
+        (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/issue-60564.stderr b/tests/ui/type-alias-impl-trait/issue-60564.stderr
index 6aaed7d4296..bfe8d92fedd 100644
--- a/tests/ui/type-alias-impl-trait/issue-60564.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-60564.stderr
@@ -1,11 +1,11 @@
 error[E0792]: expected generic type parameter, found `u8`
-  --> $DIR/issue-60564.rs:21:9
+  --> $DIR/issue-60564.rs:20:34
    |
 LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
    |                         - this generic parameter must be used with a generic type parameter
 ...
-LL |         (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn iter_bits(self, n: u8) -> Self::BitsIter {
+   |                                  ^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
index 178aa5cf345..e58b2d4aa60 100644
--- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
@@ -1,11 +1,11 @@
 error[E0792]: expected generic type parameter, found `()`
-  --> $DIR/issue-68368-non-defining-use-2.rs:10:29
+  --> $DIR/issue-68368-non-defining-use-2.rs:10:15
    |
 LL | type Alias<'a, U> = impl Trait<U>;
    |                - this generic parameter must be used with a generic type parameter
 ...
 LL | fn f<'a>() -> Alias<'a, ()> {}
-   |                             ^^
+   |               ^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
index bfbd506a7a5..3ec19e20600 100644
--- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
@@ -1,11 +1,11 @@
 error[E0792]: expected generic type parameter, found `()`
-  --> $DIR/issue-68368-non-defining-use.rs:10:29
+  --> $DIR/issue-68368-non-defining-use.rs:10:15
    |
 LL | type Alias<'a, U> = impl Trait<U>;
    |                - this generic parameter must be used with a generic type parameter
 ...
 LL | fn f<'a>() -> Alias<'a, ()> {}
-   |                             ^^
+   |               ^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs
index 18afc54dbdc..9e0c8fbbd26 100644
--- a/tests/ui/type-alias-impl-trait/issue-77179.rs
+++ b/tests/ui/type-alias-impl-trait/issue-77179.rs
@@ -6,9 +6,9 @@ type Pointer<T> = impl std::ops::Deref<Target = T>;
 
 #[define_opaque(Pointer)]
 fn test() -> Pointer<_> {
-    //~^ ERROR: the placeholder `_` is not allowed within types
+    //~^ ERROR the placeholder `_` is not allowed within types
+    //~| ERROR expected generic type parameter, found `i32`
     Box::new(1)
-    //~^ ERROR: expected generic type parameter, found `i32`
 }
 
 fn main() {
@@ -17,5 +17,5 @@ fn main() {
 
 extern "Rust" {
     fn bar() -> Pointer<_>;
-    //~^ ERROR: the placeholder `_` is not allowed within types
+    //~^ ERROR the placeholder `_` is not allowed within types
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr
index bc11283f328..c0f197ec48c 100644
--- a/tests/ui/type-alias-impl-trait/issue-77179.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr
@@ -1,3 +1,12 @@
+error[E0792]: expected generic type parameter, found `i32`
+  --> $DIR/issue-77179.rs:8:14
+   |
+LL | type Pointer<T> = impl std::ops::Deref<Target = T>;
+   |              - this generic parameter must be used with a generic type parameter
+...
+LL | fn test() -> Pointer<_> {
+   |              ^^^^^^^^^^
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/issue-77179.rs:8:22
    |
@@ -13,15 +22,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     fn bar() -> Pointer<_>;
    |                         ^ not allowed in type signatures
 
-error[E0792]: expected generic type parameter, found `i32`
-  --> $DIR/issue-77179.rs:10:5
-   |
-LL | type Pointer<T> = impl std::ops::Deref<Target = T>;
-   |              - this generic parameter must be used with a generic type parameter
-...
-LL |     Box::new(1)
-   |     ^^^^^^^^^^^
-
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0121, E0792.
diff --git a/tests/ui/type-alias-impl-trait/multi-error.rs b/tests/ui/type-alias-impl-trait/multi-error.rs
index cb4ad4dc633..2f42f14d4cb 100644
--- a/tests/ui/type-alias-impl-trait/multi-error.rs
+++ b/tests/ui/type-alias-impl-trait/multi-error.rs
@@ -16,8 +16,8 @@ impl Foo for () {
     type Baz = impl Sized;
     fn foo() -> (Self::Bar<u32>, Self::Baz) {
         //~^ ERROR non-defining opaque type use
+        //~| ERROR expected generic type parameter, found `u32`
         ((), ())
-        //~^ ERROR expected generic type parameter
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/multi-error.stderr b/tests/ui/type-alias-impl-trait/multi-error.stderr
index 761f01b32ac..3cb267c7c26 100644
--- a/tests/ui/type-alias-impl-trait/multi-error.stderr
+++ b/tests/ui/type-alias-impl-trait/multi-error.stderr
@@ -11,13 +11,13 @@ LL |     type Bar<T> = impl Sized;
    |                   ^^^^^^^^^^
 
 error[E0792]: expected generic type parameter, found `u32`
-  --> $DIR/multi-error.rs:19:9
+  --> $DIR/multi-error.rs:17:17
    |
 LL |     type Bar<T> = impl Sized;
    |              - this generic parameter must be used with a generic type parameter
-...
-LL |         ((), ())
-   |         ^^^^^^^^
+LL |     type Baz = impl Sized;
+LL |     fn foo() -> (Self::Bar<u32>, Self::Baz) {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
index 3dd2d53fe3d..839ac471623 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
@@ -8,7 +8,8 @@ type Y<A, B> = impl std::fmt::Debug;
 
 #[define_opaque(Y)]
 fn g<A, B>() -> (Y<A, B>, Y<B, A>) {
-    (42_i64, 60) //~ ERROR concrete type differs from previous defining opaque type use
+    //~^ ERROR concrete type differs from previous defining opaque type use
+    (42_i64, 60)
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
index d6558576577..e044cbe819e 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-def-uses-in-one-fn-infer.rs:11:5
+  --> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:17
    |
-LL |     (42_i64, 60)
-   |     ^^^^^^^^^^^^
-   |     |
-   |     expected `i64`, got `i32`
-   |     this expression supplies two conflicting concrete types for the same opaque type
+LL | fn g<A, B>() -> (Y<A, B>, Y<B, A>) {
+   |                 ^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 expected `i64`, got `i32`
+   |                 this expression supplies two conflicting concrete types for the same opaque type
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
index 1357d772be1..aa31901fc5e 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
@@ -8,8 +8,8 @@ type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
 
 #[define_opaque(X)]
 fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
-    (a.clone(), a)
     //~^ ERROR concrete type differs from previous defining opaque type
+    (a.clone(), a)
 }
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
index 15e9b6fbf76..8d79b37f0f5 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-def-uses-in-one-fn2.rs:11:5
+  --> $DIR/multiple-def-uses-in-one-fn2.rs:10:63
    |
-LL |     (a.clone(), a)
-   |     ^^^^^^^^^^^^^^
-   |     |
-   |     expected `A`, got `B`
-   |     this expression supplies two conflicting concrete types for the same opaque type
+LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+   |                                                               ^^^^^^^^^^^^^^^^^^
+   |                                                               |
+   |                                                               expected `A`, got `B`
+   |                                                               this expression supplies two conflicting concrete types for the same opaque type
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
index 5adae476bfe..57fa86f5eb7 100644
--- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
+++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
@@ -12,7 +12,7 @@ pub fn get_foo() -> Foo {
 
 #[define_opaque(Foot, Foo)]
 pub fn get_foot(_: Foo) -> Foot {
-    //~^ ERROR: item does not constrain `Foo::{opaque#0}`
+    //~^ ERROR item does not constrain `Foo::{opaque#0}`
     get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type
 }
 
diff --git a/tests/ui/type-alias-impl-trait/non-defining-method.stderr b/tests/ui/type-alias-impl-trait/non-defining-method.stderr
index 49a393ca745..22f173b5be9 100644
--- a/tests/ui/type-alias-impl-trait/non-defining-method.stderr
+++ b/tests/ui/type-alias-impl-trait/non-defining-method.stderr
@@ -11,12 +11,12 @@ LL |     type Bar<T> = impl Sized;
    |                   ^^^^^^^^^^
 
 error[E0792]: expected generic type parameter, found `u32`
-  --> $DIR/non-defining-method.rs:16:32
+  --> $DIR/non-defining-method.rs:16:17
    |
 LL |     type Bar<T> = impl Sized;
    |              - this generic parameter must be used with a generic type parameter
 LL |     fn foo() -> Self::Bar<u32> {}
-   |                                ^^
+   |                 ^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr
index 75cc5948e93..53e312e3e64 100644
--- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr
+++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr
@@ -1,26 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/normalize-hidden-types.rs:27:20
+  --> $DIR/normalize-hidden-types.rs:38:22
    |
-LL |     fn define() -> Opaque {
-   |                    ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
+LL |     fn define_2() -> Opaque { dyn_hoops::<u8>(0) }
+   |                      ^^^^^^ expected `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`, got `*const dyn FnOnce(())`
    |
 note: previous use here
-  --> $DIR/normalize-hidden-types.rs:28:9
-   |
-LL |         dyn_hoops::<_>(0)
-   |         ^^^^^^^^^^^^^^^^^
-
-error: concrete type differs from previous defining opaque type use
   --> $DIR/normalize-hidden-types.rs:36:22
    |
 LL |     fn define_1() -> Opaque { dyn_hoops::<_>(0) }
-   |                      ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
-   |
-note: previous use here
-  --> $DIR/normalize-hidden-types.rs:36:31
-   |
-LL |     fn define_1() -> Opaque { dyn_hoops::<_>(0) }
-   |                               ^^^^^^^^^^^^^^^^^
+   |                      ^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/normalize-hidden-types.rs:47:25
@@ -38,18 +26,6 @@ LL |         let _: Opaque = dyn_hoops::<u8>(0);
    = help: consider constraining the associated type `<u8 as Trait>::Gat<'_>` to `()` or calling a method that returns `<u8 as Trait>::Gat<'_>`
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/normalize-hidden-types.rs:57:25
-   |
-LL |         let _: Opaque = dyn_hoops::<_>(0);
-   |                         ^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
-   |
-note: previous use here
-  --> $DIR/normalize-hidden-types.rs:58:9
-   |
-LL |         None
-   |         ^^^^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/not_a_defining_use.rs b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs
index d20622dc2e0..cfbbf9ce487 100644
--- a/tests/ui/type-alias-impl-trait/not_a_defining_use.rs
+++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs
@@ -23,8 +23,8 @@ impl Bar for u32 {
 
 #[define_opaque(Two)]
 fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
-    (t, <U as Bar>::FOO)
     //~^ ERROR concrete type differs
+    (t, <U as Bar>::FOO)
 }
 
 fn is_sync<T: Sync>() {}
diff --git a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr
index d90e4531879..37d28b3883c 100644
--- a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr
+++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/not_a_defining_use.rs:26:5
+  --> $DIR/not_a_defining_use.rs:25:36
    |
-LL |     (t, <U as Bar>::FOO)
-   |     ^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
+LL | fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
+   |                                    ^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
    |
 note: previous use here
-  --> $DIR/not_a_defining_use.rs:11:5
+  --> $DIR/not_a_defining_use.rs:10:32
    |
-LL |     (t, 5i8)
-   |     ^^^^^^^^
+LL | fn three<T: Debug, U>(t: T) -> Two<T, U> {
+   |                                ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
index cfd7e1bf382..94597adfed0 100644
--- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
@@ -13,7 +13,8 @@ pub fn add(
     n: Diff,
     m: Diff,
 ) -> Diff {
-    move |x: usize| m(n(x)) //~ ERROR: concrete type differs
+    //~^ ERROR concrete type differs
+    move |x: usize| m(n(x))
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
index 1a8ab219404..59ff9917612 100644
--- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/recursive-fn-tait.rs:16:5
+  --> $DIR/recursive-fn-tait.rs:15:6
    |
-LL |     move |x: usize| m(n(x))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:16:5: 16:20}`
+LL | ) -> Diff {
+   |      ^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:17:5: 17:20}`
    |
 note: previous use here
-  --> $DIR/recursive-fn-tait.rs:8:5
+  --> $DIR/recursive-fn-tait.rs:7:18
    |
-LL |     |_: usize |loop {}
-   |     ^^^^^^^^^^^^^^^^^^
+LL | pub fn lift() -> Diff {
+   |                  ^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
index 26ffd5c16a2..858f2a2feb6 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
@@ -13,8 +13,8 @@ fn transform<S>() -> impl std::fmt::Display {
 }
 #[define_opaque(Op)]
 fn bad() -> Op {
-    transform::<Op>()
     //~^ ERROR concrete type differs from previous defining opaque type use
+    transform::<Op>()
 }
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
index 259f3b2b9f3..e527b5bc7f8 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/recursive-tait-conflicting-defn-2.rs:16:5
+  --> $DIR/recursive-tait-conflicting-defn-2.rs:15:13
    |
-LL |     transform::<Op>()
-   |     ^^^^^^^^^^^^^^^^^ expected `&'static &'static str`, got `impl std::fmt::Display`
+LL | fn bad() -> Op {
+   |             ^^ expected `&&str`, got `impl std::fmt::Display`
    |
 note: previous use here
-  --> $DIR/recursive-tait-conflicting-defn-2.rs:8:5
+  --> $DIR/recursive-tait-conflicting-defn-2.rs:7:13
    |
-LL |     &"hello world"
-   |     ^^^^^^^^^^^^^^
+LL | fn foo() -> Op {
+   |             ^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
index c9e2773905d..90581a98a34 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
@@ -23,10 +23,9 @@ pub fn test() -> TestImpl {
 
 #[define_opaque(TestImpl)]
 fn make_option2() -> Option<TestImpl> {
+    //~^ ERROR concrete type differs from previous defining opaque type use
     let inner = make_option().unwrap();
-
     Some(B { inner })
-    //~^ ERROR concrete type differs from previous defining opaque type use
 }
 
 fn make_option() -> Option<TestImpl> {
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
index 47471c9728c..256f13b6221 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/recursive-tait-conflicting-defn.rs:28:5
+  --> $DIR/recursive-tait-conflicting-defn.rs:25:22
    |
-LL |     Some(B { inner })
-   |     ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
+LL | fn make_option2() -> Option<TestImpl> {
+   |                      ^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
    |
 note: previous use here
-  --> $DIR/recursive-tait-conflicting-defn.rs:21:5
+  --> $DIR/recursive-tait-conflicting-defn.rs:20:18
    |
-LL |     A
-   |     ^
+LL | pub fn test() -> TestImpl {
+   |                  ^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs
index 19986247d40..53b7667aa9f 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs
@@ -1,9 +1,10 @@
 #![feature(type_alias_impl_trait)]
-//@ known-bug: #109268
 
 type Foo = impl Fn() -> Foo;
 
+#[define_opaque(Foo)]
 fn crash(x: Foo) -> Foo {
+    //~^ ERROR overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
     x
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
index ad96a0eeb87..ee8922b673e 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:4:12
+error[E0275]: overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
+  --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:6:21
    |
-LL | type Foo = impl Fn() -> Foo;
-   |            ^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same crate
+LL | fn crash(x: Foo) -> Foo {
+   |                     ^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs
index 761cc83af51..d0c62d29069 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs
@@ -1,13 +1,13 @@
 #![feature(type_alias_impl_trait)]
-//@ known-bug: #109268
 
 pub trait Bar<T> {
     type Item;
 }
 
 type Foo = impl Bar<Foo, Item = Foo>;
-
+#[define_opaque(Foo)]
 fn crash(x: Foo) -> Foo {
+    //~^ ERROR overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
     x
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
index e5bb8163a81..40bd6517c06 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:8:12
+error[E0275]: overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
+  --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:9:21
    |
-LL | type Foo = impl Bar<Foo, Item = Foo>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same crate
+LL | fn crash(x: Foo) -> Foo {
+   |                     ^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs
index 52942afd639..de3d23b83a2 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs
@@ -1,9 +1,9 @@
 #![feature(type_alias_impl_trait)]
-//@ known-bug: #109268
 
 type Foo<'a> = impl Fn() -> Foo<'a>;
-
+#[define_opaque(Foo)]
 fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
+    //~^ ERROR overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
     x
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
index 157310bf623..f9e26fde1bd 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:4:16
+error[E0275]: overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
+  --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:5:40
    |
-LL | type Foo<'a> = impl Fn() -> Foo<'a>;
-   |                ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same crate
+LL | fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
+   |                                        ^^^^^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type/issue-91268.rs b/tests/ui/type/issue-91268.rs
index 16d5b241145..6297880702e 100644
--- a/tests/ui/type/issue-91268.rs
+++ b/tests/ui/type/issue-91268.rs
@@ -1,5 +1,6 @@
-//@ error-pattern: this file contains an unclosed delimiter
 // ignore-tidy-trailing-newlines
 // `ţ` must be the last character in this file, it cannot be followed by a newline
+
+//~vv ERROR this file contains an unclosed delimiter
 fn main() {
     0: u8(ţ
\ No newline at end of file
diff --git a/tests/ui/type/issue-91268.stderr b/tests/ui/type/issue-91268.stderr
index 395559442d1..db7b5a188cf 100644
--- a/tests/ui/type/issue-91268.stderr
+++ b/tests/ui/type/issue-91268.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-91268.rs:5:12
+  --> $DIR/issue-91268.rs:6:12
    |
 LL | fn main() {
    |           - unclosed delimiter
diff --git a/tests/ui/type/pattern_types/const_block.rs b/tests/ui/type/pattern_types/const_block.rs
deleted file mode 100644
index ed19b10671a..00000000000
--- a/tests/ui/type/pattern_types/const_block.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#![feature(pattern_types)]
-#![feature(pattern_type_macro)]
-#![feature(inline_const_pat)]
-//@ check-pass
-
-use std::pat::pattern_type;
-
-fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
-
-fn main() {}
diff --git a/tests/ui/type/type-arg-out-of-scope.rs b/tests/ui/type/type-arg-out-of-scope.rs
index 3f8a6ff1016..05ed54ec832 100644
--- a/tests/ui/type/type-arg-out-of-scope.rs
+++ b/tests/ui/type/type-arg-out-of-scope.rs
@@ -1,5 +1,6 @@
-//@ error-pattern:can't use generic parameters from outer item
 fn foo<T>(x: T) {
     fn bar(f: Box<dyn FnMut(T) -> T>) { }
+    //~^ ERROR can't use generic parameters from outer item
+    //~| ERROR can't use generic parameters from outer item
 }
 fn main() { foo(1); }
diff --git a/tests/ui/type/type-arg-out-of-scope.stderr b/tests/ui/type/type-arg-out-of-scope.stderr
index 8665001e243..fcaaca1770f 100644
--- a/tests/ui/type/type-arg-out-of-scope.stderr
+++ b/tests/ui/type/type-arg-out-of-scope.stderr
@@ -1,5 +1,5 @@
 error[E0401]: can't use generic parameters from outer item
-  --> $DIR/type-arg-out-of-scope.rs:3:29
+  --> $DIR/type-arg-out-of-scope.rs:2:29
    |
 LL | fn foo<T>(x: T) {
    |        - type parameter from outer item
@@ -9,7 +9,7 @@ LL |     fn bar(f: Box<dyn FnMut(T) -> T>) { }
    |           help: try introducing a local generic parameter here: `<T>`
 
 error[E0401]: can't use generic parameters from outer item
-  --> $DIR/type-arg-out-of-scope.rs:3:35
+  --> $DIR/type-arg-out-of-scope.rs:2:35
    |
 LL | fn foo<T>(x: T) {
    |        - type parameter from outer item
diff --git a/tests/ui/typeck/issue-91334.rs b/tests/ui/typeck/issue-91334.rs
index ec0d4ad70f1..c820014ff93 100644
--- a/tests/ui/typeck/issue-91334.rs
+++ b/tests/ui/typeck/issue-91334.rs
@@ -1,7 +1,7 @@
 // Regression test for the ICE described in issue #91334.
 
-//@ error-pattern: this file contains an unclosed delimiter
-
 #![feature(coroutines)]
 
+//~vv ERROR mismatched closing delimiter: `)`
+//~v ERROR this file contains an unclosed delimiter
 fn f(){||yield(((){),
diff --git a/tests/ui/typeck/output-type-mismatch.rs b/tests/ui/typeck/output-type-mismatch.rs
index d5691c9c353..0d7c7d1dfe1 100644
--- a/tests/ui/typeck/output-type-mismatch.rs
+++ b/tests/ui/typeck/output-type-mismatch.rs
@@ -1,5 +1,3 @@
-//@ error-pattern: mismatched types
-
 fn f() { }
 
-fn main() { let i: isize; i = f(); }
+fn main() { let i: isize; i = f(); } //~ ERROR mismatched types
diff --git a/tests/ui/typeck/output-type-mismatch.stderr b/tests/ui/typeck/output-type-mismatch.stderr
index c6df6650654..ba50cd4e6d7 100644
--- a/tests/ui/typeck/output-type-mismatch.stderr
+++ b/tests/ui/typeck/output-type-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/output-type-mismatch.rs:5:31
+  --> $DIR/output-type-mismatch.rs:3:31
    |
 LL | fn main() { let i: isize; i = f(); }
    |                    -----      ^^^ expected `isize`, found `()`
diff --git a/tests/ui/typeck/while-type-error.rs b/tests/ui/typeck/while-type-error.rs
index ca3b8921f54..abc607516e6 100644
--- a/tests/ui/typeck/while-type-error.rs
+++ b/tests/ui/typeck/while-type-error.rs
@@ -1,3 +1 @@
-//@ error-pattern: mismatched types
-
-fn main() { while main { } }
+fn main() { while main { } } //~ ERROR mismatched types
diff --git a/tests/ui/typeck/while-type-error.stderr b/tests/ui/typeck/while-type-error.stderr
index b67ec561531..4bd86aafc17 100644
--- a/tests/ui/typeck/while-type-error.stderr
+++ b/tests/ui/typeck/while-type-error.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/while-type-error.rs:3:19
+  --> $DIR/while-type-error.rs:1:19
    |
 LL | fn main() { while main { } }
    |                   ^^^^ expected `bool`, found fn item
diff --git a/tests/ui/typeck/wrong-ret-type.rs b/tests/ui/typeck/wrong-ret-type.rs
index b83aefad1e9..2d6751a823c 100644
--- a/tests/ui/typeck/wrong-ret-type.rs
+++ b/tests/ui/typeck/wrong-ret-type.rs
@@ -1,3 +1,2 @@
-//@ error-pattern: mismatched types
-fn mk_int() -> usize { let i: isize = 3; return i; }
+fn mk_int() -> usize { let i: isize = 3; return i; } //~ ERROR mismatched types
 fn main() { }
diff --git a/tests/ui/typeck/wrong-ret-type.stderr b/tests/ui/typeck/wrong-ret-type.stderr
index 33a094ce95d..918eb2d5c88 100644
--- a/tests/ui/typeck/wrong-ret-type.stderr
+++ b/tests/ui/typeck/wrong-ret-type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/wrong-ret-type.rs:2:49
+  --> $DIR/wrong-ret-type.rs:1:49
    |
 LL | fn mk_int() -> usize { let i: isize = 3; return i; }
    |                -----                            ^ expected `usize`, found `isize`
diff --git a/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.rs b/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.rs
index 7bd4df47220..9304e20b429 100644
--- a/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.rs
+++ b/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.rs
@@ -1,6 +1,6 @@
+//~ ERROR unknown lint: `test_unstable_lint`
 //@ check-fail
 //@ compile-flags: -Dunknown_lints -Atest_unstable_lint
-//@ error-pattern: unknown lint: `test_unstable_lint`
 //@ error-pattern: the `test_unstable_lint` lint is unstable
 
 fn main() {}
diff --git a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.rs b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.rs
index 995f65ef83d..76983419c68 100644
--- a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.rs
+++ b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.rs
@@ -1,6 +1,6 @@
+//~ WARN unknown lint: `test_unstable_lint`
 //@ check-pass
 //@ compile-flags: -Wunknown_lints -Atest_unstable_lint
-//@ error-pattern: unknown lint: `test_unstable_lint`
 //@ error-pattern: the `test_unstable_lint` lint is unstable
 
 fn main() {}
diff --git a/tests/ui/unresolved/unresolved-import.rs b/tests/ui/unresolved/unresolved-import.rs
index 763e9496734..b0fdcf97015 100644
--- a/tests/ui/unresolved/unresolved-import.rs
+++ b/tests/ui/unresolved/unresolved-import.rs
@@ -31,6 +31,8 @@ mod food {
 
     mod zug {
         pub mod baz {
+        //~^ NOTE module `food::zug::baz` exists but is inaccessible
+        //~| NOTE not accessible
             pub struct Foobar;
         }
     }
diff --git a/tests/ui/unresolved/unresolved-import.stderr b/tests/ui/unresolved/unresolved-import.stderr
index c65fe841001..4001695459a 100644
--- a/tests/ui/unresolved/unresolved-import.stderr
+++ b/tests/ui/unresolved/unresolved-import.stderr
@@ -26,6 +26,12 @@ LL | use food::baz;
    |     |     |
    |     |     help: a similar name exists in the module: `bag`
    |     no `baz` in `food`
+   |
+note: module `food::zug::baz` exists but is inaccessible
+  --> $DIR/unresolved-import.rs:33:9
+   |
+LL |         pub mod baz {
+   |         ^^^^^^^^^^^ not accessible
 
 error[E0432]: unresolved import `food::beens`
   --> $DIR/unresolved-import.rs:19:12
@@ -37,13 +43,13 @@ LL | use food::{beens as Foo};
    |            help: a similar name exists in the module: `beans`
 
 error[E0432]: unresolved import `MyEnum`
-  --> $DIR/unresolved-import.rs:44:9
+  --> $DIR/unresolved-import.rs:46:9
    |
 LL |     use MyEnum::*;
    |         ^^^^^^ help: a similar path exists: `self::MyEnum`
 
 error[E0432]: unresolved import `Enum`
-  --> $DIR/unresolved-import.rs:55:9
+  --> $DIR/unresolved-import.rs:57:9
    |
 LL |     use Enum::*;
    |         ^^^^ help: a similar path exists: `self::Enum`
diff --git a/tests/ui/unsafe/const_pat_in_layout_restricted.rs b/tests/ui/unsafe/const_pat_in_layout_restricted.rs
deleted file mode 100644
index 2ba173ee499..00000000000
--- a/tests/ui/unsafe/const_pat_in_layout_restricted.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Check that ref mut patterns within a const pattern don't get considered
-// unsafe because they're within a pattern for a layout constrained stuct.
-//@ check-pass
-
-#![feature(rustc_attrs)]
-#![feature(inline_const_pat)]
-
-#[rustc_layout_scalar_valid_range_start(3)]
-struct Gt2(i32);
-
-fn main() {
-    match unsafe { Gt2(5) } {
-        Gt2(
-            const {
-                || match () {
-                    ref mut y => (),
-                };
-                4
-            },
-        ) => (),
-        _ => (),
-    }
-}
diff --git a/tests/ui/use/use-meta-mismatch.rs b/tests/ui/use/use-meta-mismatch.rs
index 2c5ae9cd9a1..8d15e46375c 100644
--- a/tests/ui/use/use-meta-mismatch.rs
+++ b/tests/ui/use/use-meta-mismatch.rs
@@ -1,5 +1,3 @@
-//@ error-pattern:can't find crate for `fake_crate`
-
-extern crate fake_crate as extra;
+extern crate fake_crate as extra; //~ ERROR can't find crate for `fake_crate`
 
 fn main() { }
diff --git a/tests/ui/use/use-meta-mismatch.stderr b/tests/ui/use/use-meta-mismatch.stderr
index b793229e5fd..ffc471fa722 100644
--- a/tests/ui/use/use-meta-mismatch.stderr
+++ b/tests/ui/use/use-meta-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0463]: can't find crate for `fake_crate`
-  --> $DIR/use-meta-mismatch.rs:3:1
+  --> $DIR/use-meta-mismatch.rs:1:1
    |
 LL | extern crate fake_crate as extra;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
diff --git a/tests/ui/variance/variance-uniquearc.rs b/tests/ui/variance/variance-uniquearc.rs
new file mode 100644
index 00000000000..03589512388
--- /dev/null
+++ b/tests/ui/variance/variance-uniquearc.rs
@@ -0,0 +1,27 @@
+// regression test of https://github.com/rust-lang/rust/pull/133572#issuecomment-2543007164
+// see also the test for UniqueRc` in variance-uniquerc.rs
+//
+// inline comments explain how this code *would* compile if UniqueArc was still covariant
+
+#![feature(unique_rc_arc)]
+
+use std::sync::UniqueArc;
+
+fn extend_lifetime<'a, 'b>(x: &'a str) -> &'b str {
+    let r = UniqueArc::new(""); // UniqueArc<&'static str>
+    let w = UniqueArc::downgrade(&r); // Weak<&'static str>
+    let mut r = r; // [IF COVARIANT]: ==>> UniqueArc<&'a str>
+    *r = x; // assign the &'a str
+    let _r = UniqueArc::into_arc(r); // Arc<&'a str>, but we only care to activate the weak
+    let r = w.upgrade().unwrap(); // Arc<&'static str>
+    *r // &'static str, coerces to &'b str
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {
+    let s = String::from("Hello World!");
+    let r = extend_lifetime(&s);
+    println!("{r}");
+    drop(s);
+    println!("{r}");
+}
diff --git a/tests/ui/variance/variance-uniquearc.stderr b/tests/ui/variance/variance-uniquearc.stderr
new file mode 100644
index 00000000000..55076dae732
--- /dev/null
+++ b/tests/ui/variance/variance-uniquearc.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/variance-uniquearc.rs:17:5
+   |
+LL | fn extend_lifetime<'a, 'b>(x: &'a str) -> &'b str {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+...
+LL |     *r // &'static str, coerces to &'b str
+   |     ^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/variance/variance-uniquerc.rs b/tests/ui/variance/variance-uniquerc.rs
index 0c395ab06ea..2e9738f66dc 100644
--- a/tests/ui/variance/variance-uniquerc.rs
+++ b/tests/ui/variance/variance-uniquerc.rs
@@ -1,5 +1,5 @@
 // regression test of https://github.com/rust-lang/rust/pull/133572#issuecomment-2543007164
-// we should also test UniqueArc once implemented
+// see also the test for UniqueArc in variance-uniquearc.rs
 //
 // inline comments explain how this code *would* compile if UniqueRc was still covariant
 
diff --git a/tests/ui/windows-subsystem/windows-subsystem-invalid.rs b/tests/ui/windows-subsystem/windows-subsystem-invalid.rs
index c6a6dd00a92..4dadfc6fd5d 100644
--- a/tests/ui/windows-subsystem/windows-subsystem-invalid.rs
+++ b/tests/ui/windows-subsystem/windows-subsystem-invalid.rs
@@ -1,5 +1,5 @@
-//@ error-pattern: invalid windows subsystem `wrong`, only `windows` and `console` are allowed
-
 #![windows_subsystem = "wrong"]
 
 fn main() {}
+
+//~? ERROR invalid windows subsystem `wrong`
diff --git a/triagebot.toml b/triagebot.toml
index 91b487bb96d..756536dc2e7 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -254,6 +254,16 @@ trigger_files = [
     "compiler/rustc_attr_data_structures",
 ]
 
+[autolabel."F-autodiff"]
+trigger_files = [
+    "src/tools/enzyme",
+    "src/doc/unstable-book/src/compiler-flags/autodiff.md",
+    "compiler/rustc_ast/src/expand/autodiff_attrs.rs",
+    "compiler/rustc_monomorphize/src/partitioning/autodiff.rs",
+    "compiler/rustc_codegen_llvm/src/builder/autodiff.rs",
+    "compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs",
+]
+
 [autolabel."T-rustdoc-frontend"]
 trigger_labels = [
     "A-rustdoc-search",
@@ -992,7 +1002,7 @@ message = "Changes to the size of AST and/or HIR nodes."
 cc = ["@nnethercote"]
 
 [mentions."compiler/rustc_sanitizers"]
-cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
+cc = ["@rcvalle"]
 
 [mentions."src/doc/rustc/src/exploit-mitigations.md"]
 cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
@@ -1028,7 +1038,7 @@ cc = ["@Urgau"]
 cc = ["@Noratrieb"]
 
 [mentions."tests/codegen/sanitizer"]
-cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
+cc = ["@rcvalle"]
 
 [mentions."tests/codegen/split-lto-unit.rs"]
 cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
@@ -1040,7 +1050,7 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
 cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
 
 [mentions."tests/ui/sanitizer"]
-cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
+cc = ["@rcvalle"]
 
 [mentions."tests/ui/stack-protector"]
 cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
@@ -1092,13 +1102,30 @@ cc = ["@jdonszelmann"]
 [mentions."compiler/rustc_attr_data_structures"]
 cc = ["@jdonszelmann"]
 
+[mentions."src/tools/enzyme"]
+cc = ["@ZuseZ4"]
+[mentions."src/doc/unstable-book/src/compiler-flags/autodiff.md"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_ast/src/expand/autodiff_attrs.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_ast/src/expand/typetree.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_builtin_macros/src/autodiff.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_monomorphize/src/partitioning/autodiff.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_codegen_llvm/src/builder/autodiff.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs"]
+cc = ["@ZuseZ4"]
+
 [assign]
 warn_non_default_branch.enable = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
     "jyn514",
-    "ChrisDenton",
     "saethlin",
+    "Noratrieb",
 ]
 
 [[assign.warn_non_default_branch.exceptions]]
@@ -1116,7 +1143,6 @@ compiler_leads = [
 ]
 compiler = [
     "@BoxyUwU",
-    "@cjgillot",
     "@compiler-errors",
     "@davidtwco",
     "@estebank",
@@ -1134,7 +1160,6 @@ compiler = [
 ]
 libs = [
     "@Mark-Simulacrum",
-    "@Amanieu",
     "@Noratrieb",
     "@workingjubilee",
     "@joboet",
@@ -1166,13 +1191,13 @@ docs = [
     "@ehuss",
     "@GuillaumeGomez",
 ]
-
 codegen = [
+    "@dianqk",
     "@saethlin",
     "@workingjubilee",
 ]
 query-system = [
-    "@cjgillot",
+    "@oli-obk",
 ]
 incremental = [
     "@wesleywiser",
@@ -1253,11 +1278,13 @@ project-stable-mir = [
     "@oli-obk",
     "@scottmcm",
 ]
-
 project-exploit-mitigations = [
     "@cuviper",
     "@rcvalle",
 ]
+compiletest = [
+    "@jieyouxu",
+]
 
 [assign.owners]
 "/.github/workflows" =                                   ["infra-ci"]