about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap8
-rw-r--r--compiler/rustc_ast/src/ast.rs71
-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/util/parser.rs24
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs6
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs313
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs23
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs15
-rw-r--r--compiler/rustc_borrowck/messages.ftl7
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs13
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs38
-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/autodiff.rs339
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs49
-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/src/abi/mod.rs2
-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_gcc/src/consts.rs2
-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/autodiff.rs199
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs23
-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/mono_item.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/mod.rs2
-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.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs34
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs5
-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/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.rs17
-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_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs8
-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/compare_impl_item.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs61
-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.rs243
-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/mod.rs4
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs38
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs343
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs90
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs35
-rw-r--r--compiler/rustc_interface/src/interface.rs8
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs4
-rw-r--r--compiler/rustc_lint/src/context.rs15
-rw-r--r--compiler/rustc_lint/src/levels.rs111
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs9
-rw-r--r--compiler/rustc_lint/src/types.rs45
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs57
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp10
-rw-r--r--compiler/rustc_metadata/src/creader.rs2
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs6
-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/lint.rs68
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs36
-rw-r--r--compiler/rustc_middle/src/query/mod.rs17
-rw-r--r--compiler/rustc_middle/src/thir.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs48
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs43
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs36
-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/typeck_results.rs9
-rw-r--r--compiler/rustc_middle/src/ty/util.rs69
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_place.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/stmt.rs10
-rw-r--r--compiler/rustc_mir_build/src/builder/mod.rs12
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs19
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs2
-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/gvn.rs202
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs38
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs6
-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.rs36
-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.rs43
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs14
-rw-r--r--compiler/rustc_parse/src/parser/item.rs32
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs15
-rw-r--r--compiler/rustc_parse/src/parser/token_type.rs4
-rw-r--r--compiler/rustc_passes/src/dead.rs16
-rw-r--r--compiler/rustc_passes/src/stability.rs2
-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.rs10
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs3
-rw-r--r--compiler/rustc_session/src/config.rs18
-rw-r--r--compiler/rustc_session/src/options.rs9
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs8
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs15
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs60
-rw-r--r--compiler/rustc_span/src/symbol.rs10
-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/spec/base/apple/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/json.rs4
-rw-r--r--compiler/rustc_target/src/spec/mod.rs18
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs2
-rw-r--r--compiler/rustc_trait_selection/messages.ftl7
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs32
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs28
-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.rs1
-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.rs38
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs10
-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/src/compiler_interface.rs7
-rw-r--r--compiler/stable_mir/src/crate_def.rs16
-rw-r--r--compiler/stable_mir/src/lib.rs7
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs12
-rw-r--r--compiler/stable_mir/src/ty.rs67
-rw-r--r--library/alloc/Cargo.toml1
-rw-r--r--library/alloctests/tests/lib.rs1
-rw-r--r--library/alloctests/tests/num.rs69
-rw-r--r--library/core/src/cell.rs15
-rw-r--r--library/core/src/intrinsics/mod.rs10
-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.rs45
-rw-r--r--library/core/src/slice/iter.rs45
-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/std/src/io/buffered/bufreader/buffer.rs1
-rw-r--r--library/std/src/io/copy.rs5
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/net/socket_addr.rs2
-rw-r--r--library/std/src/sys/pal/windows/pipe.rs1
-rw-r--r--library/std/src/sys/thread_local/mod.rs1
-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--src/bootstrap/mk/Makefile.in4
-rw-r--r--src/bootstrap/src/utils/helpers.rs4
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh1
-rw-r--r--src/ci/github-actions/jobs.yml27
-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.md11
-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.md3
-rw-r--r--src/doc/rustc/src/platform-support.md10
-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/language-features/import-trait-associated-functions.md22
-rw-r--r--src/doc/unstable-book/src/language-features/type-alias-impl-trait.md159
-rw-r--r--src/librustdoc/doctest/runner.rs9
-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.ts14
-rw-r--r--src/librustdoc/html/static/js/settings.js127
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs7
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs6
m---------src/llvm-project0
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/duplicate_mod.rs8
-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/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/utils.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs38
-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/operators/arithmetic_side_effects.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs7
-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/suspicious_trait_impl.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs11
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/compiletest/src/common.rs6
-rw-r--r--src/tools/compiletest/src/executor.rs156
-rw-r--r--src/tools/compiletest/src/header.rs33
-rw-r--r--src/tools/compiletest/src/header/tests.rs13
-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/src/concurrency/data_race.rs2
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs8
-rw-r--r--src/tools/run-make-support/src/lib.rs1
-rw-r--r--src/tools/run-make-support/src/linker.rs36
-rw-r--r--src/tools/rustfmt/src/expr.rs2
-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--tests/codegen/autodiff.rs4
-rw-r--r--tests/codegen/autodiffv.rs116
-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/float/algebraic.rs149
-rw-r--r--tests/codegen/float_math.rs71
-rw-r--r--tests/codegen/slice-split-at.rs24
-rw-r--r--tests/codegen/try_question_mark_nop.rs38
-rw-r--r--tests/coverage/issue-84561.cov-map163
-rw-r--r--tests/crashes/112201.rs19
-rw-r--r--tests/crashes/137751.rs6
-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/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/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/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/target-specs/rmake.rs2
-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/no-run-flag-error.rs3
-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/track-diagnostics.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/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/associated-types/issue-36499.rs2
-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/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/mut-borrow-in-loop-2.stderr4
-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/cfg/cfg_false_no_std-2.rs7
-rw-r--r--tests/ui/cfg/raw-true-false.rs24
-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/codegen/mismatched-data-layouts.rs3
-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-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/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/miri_unleashed/drop.rs4
-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/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/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-super-let.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-super-let.stderr13
-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/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/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/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/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/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/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/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/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/force-warn/warnings-lint-group.rs5
-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/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/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/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/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/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-21146.rs3
-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/shebang/shebang-split.rs3
-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/print-request/print-lints-help.rs3
-rw-r--r--tests/ui/print-request/stability.rs11
-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/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/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/return/ret-non-nil.rs4
-rw-r--r--tests/ui/return/ret-non-nil.stderr2
-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/rmeta/rmeta_bin.rs3
-rw-r--r--tests/ui/rmeta/rmeta_lib.rs3
-rw-r--r--tests/ui/sanitizer/incompatible.rs3
-rw-r--r--tests/ui/sanitizer/unsupported-target.rs4
-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/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/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/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/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/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.rs2
-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-53598.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53598.stderr6
-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/issue-91268.rs3
-rw-r--r--tests/ui/type/issue-91268.stderr2
-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/use/use-meta-mismatch.rs4
-rw-r--r--tests/ui/use/use-meta-mismatch.stderr2
-rw-r--r--tests/ui/windows-subsystem/windows-subsystem-invalid.rs4
-rw-r--r--triagebot.toml7
827 files changed, 8492 insertions, 4792 deletions
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/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 33c20602dfd..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]`).
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/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_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_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 839d5d3bb95..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.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,
@@ -834,36 +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);
-                    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,
@@ -883,39 +900,36 @@ 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.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 {
@@ -928,6 +942,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     define_opaque: _,
                 },
             ) => {
+                self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
                 self.check_defaultness(item.span, *defaultness);
 
                 let is_intrinsic =
@@ -955,43 +970,38 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     });
                 }
 
-                self.visit_vis(&item.vis);
-                self.visit_ident(ident);
                 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, _) => {
                 for variant in &def.variants {
@@ -1006,34 +1016,31 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         );
                     }
                 }
+                visit::walk_item(self, item)
             }
             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, ident.span);
-                        this.deny_super_traits(bounds, ident.span);
-                        this.deny_where_clause(&generics.where_clause, ident.span);
-                        this.deny_items(items, 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(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, ident, mod_kind) => {
                 if let &Safety::Unsafe(span) = safety {
@@ -1045,18 +1052,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 {
                     self.check_mod_file_item_asciionly(*ident);
                 }
+                visit::walk_item(self, item)
             }
             ItemKind::Struct(ident, vdata, generics) => match vdata {
                 VariantData::Struct { fields, .. } => {
-                    self.visit_vis(&item.vis);
-                    self.visit_ident(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(ident, vdata, generics) => {
                 if vdata.fields().is_empty() {
@@ -1064,15 +1069,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
                 match vdata {
                     VariantData::Struct { fields, .. } => {
-                        self.visit_vis(&item.vis);
-                        self.visit_ident(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, .. }) => {
@@ -1083,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);
@@ -1096,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, .. },
@@ -1119,11 +1123,10 @@ 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) {
@@ -1488,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(&func.ident);
+                self.visit_attrs_vis_ident(&item.attrs, &item.vis, &func.ident);
                 let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.vis, &*func);
-                walk_list!(self, visit_attribute, &item.attrs);
                 self.visit_fn(kind, item.span, item.id);
             }
             AssocItemKind::Type(_) => {
@@ -1596,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() {
@@ -1606,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
                 };
@@ -1686,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 ea60e083c4c..e312f15f05b 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -332,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)
@@ -511,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_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/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 7cc42260906..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()));
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/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 7f0ee28531c..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,
@@ -171,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);
@@ -431,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 }
     }
@@ -478,29 +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,
-                )
-            });
-
-            let prev = self.register_hidden_type_in_storage(key, hidden_ty);
-            assert_eq!(prev, None);
-        }
-    }
 }
 
 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/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 8937d35d53a..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
@@ -195,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);
@@ -470,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();
@@ -497,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;
-            }
-            [arg] => {
-                ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![arg.clone()]);
+                exprs = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![default_call_expr]);
             }
-            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
     }
@@ -684,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.
@@ -783,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/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_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index 122b541fa35..eec89c026b2 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -99,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(
@@ -146,27 +174,6 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
             spawn_and_wait(build_cmd);
         }
     }),
-    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);
-
-        if runner.is_native {
-            let mut test_cmd = SYSROOT_TESTS.test(&runner.target_compiler, &runner.dirs);
-            test_cmd.args(["-p", "coretests", "-p", "alloctests", "--", "-q"]);
-            spawn_and_wait(test_cmd);
-        } else {
-            eprintln!("Cross-Compiling: Not running tests");
-            let mut build_cmd = SYSROOT_TESTS.build(&runner.target_compiler, &runner.dirs);
-            build_cmd.args(["-p", "coretests", "-p", "alloctests", "--tests"]);
-            spawn_and_wait(build_cmd);
-        }
-    }),
     TestCase::custom("test.regex", &|runner| {
         REGEX_REPO.patch(&runner.dirs);
 
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 714414fe8d6..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.sysroot
 test.regex
 test.portable-simd
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/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_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/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/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..3be8cd5f6ac 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
@@ -643,7 +644,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 +672,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()) }
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/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/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 7d411087241..1c885a2fd5f 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -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 {
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 ac9ac9bbb31..e2c009712d1 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);
         }
diff --git a/compiler/rustc_codegen_ssa/src/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs
index 64b5d4569ec..875fa6cfa57 100644
--- a/compiler/rustc_codegen_ssa/src/back/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/back/mod.rs
@@ -19,7 +19,7 @@ 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 {
+    if sess.target.is_like_darwin {
         apple::add_version_to_llvm_target(&sess.target.llvm_target, apple::deployment_target(sess))
             .into()
     } else {
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 ccc0273280f..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,
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index a85d032f36e..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 {
@@ -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/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index d26d6edf314..f36e42cc6b9 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -34,7 +34,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 +45,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 +340,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/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 f1dc4bb795e..6fb01bf415a 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -64,6 +64,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 +393,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
@@ -715,7 +712,7 @@ fn print_crate_info(
                         // lint is unstable and feature gate isn't active, don't print
                         continue;
                     }
-                    let level = lint_levels.lint_level(lint).0;
+                    let level = lint_levels.lint_level(lint).level;
                     println_info!("{}={}", lint.name_lower(), level.as_str());
                 }
             }
@@ -807,7 +804,7 @@ 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),
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_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 87b88bb4223..710e129b609 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -629,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/hir.rs b/compiler/rustc_hir/src/hir.rs
index f8af1b81ca9..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;
@@ -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/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index aec9518494c..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
@@ -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) {
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 177243b1b76..7c5d7b33a34 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -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());
                 }
             }
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/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 98da8449d5e..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,
                     &[],
@@ -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/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 302abc27324..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.
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/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 83925b5ec52..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
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 1c23761b2e5..8c0c17f7a7d 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1271,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.
@@ -1297,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);
     }
 
@@ -1451,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);
@@ -1572,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/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index a882ea27af6..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) => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 0097b6ea123..912098c4e2d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -3477,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/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 754d1e31446..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));
             }
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index b4ac143f513..8ab71e5220b 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -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 },
@@ -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 =
@@ -2323,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 d457133c703..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();
                     }
                 }
             }
@@ -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);
             }
         }
     }
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 d9297fb4194..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};
@@ -221,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`,
@@ -231,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
@@ -249,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/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 93013c8b3f6..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.
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index c56dbc2e1c4..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};
@@ -694,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;
         }
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/levels.rs b/compiler/rustc_lint/src/levels.rs
index 313d8f6ba8f..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
@@ -541,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() });
@@ -586,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 {
@@ -595,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 });
                 }
             }
         }
@@ -612,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
@@ -685,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;
@@ -693,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 }),
         };
     }
 
@@ -714,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;
             }
@@ -725,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")
@@ -745,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 };
@@ -795,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 {
@@ -933,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 });
                     }
                 }
 
@@ -942,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.
@@ -964,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;
                 }
@@ -1002,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);
@@ -1040,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]
@@ -1051,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/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/types.rs b/compiler/rustc_lint/src/types.rs
index fec5db64bf2..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
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/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 53df59930f4..32e6da446d7 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) {
@@ -636,6 +642,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,
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 16f87ab79be..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<_>>();
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_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/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/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/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 6d6e6a1f185..707c8d04d55 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1668,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/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 4b3236e4b84..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.
@@ -1607,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
@@ -1629,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
@@ -2517,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/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/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 618a65a0186..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]
@@ -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/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 255d464d265..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
     }
 }
 
@@ -1124,10 +1147,8 @@ pub struct Destructor {
 // 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/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/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 7743e202aae..e4863896fc8 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -414,6 +414,11 @@ impl<'tcx> TyCtxt<'tcx> {
                 continue;
             };
 
+            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")
@@ -450,26 +455,17 @@ impl<'tcx> TyCtxt<'tcx> {
                 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",
-                );
-                continue;
-            };
-
-            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
@@ -1556,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_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
index 90e27c85f74..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)
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 7396591e185..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> {
@@ -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/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 2a9bfb25b84..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,
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 ea8c7303c0a..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;
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/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/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index c372b77ad25..6429d3f67ec 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -529,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_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/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 82dae51b3d0..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
@@ -96,6 +96,42 @@ where
                 );
                 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,
+                    goal.param_env,
+                    expected,
+                );
+                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            }
             TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
                 let Some(def_id) = opaque_ty
                     .def_id
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..c46169a26c1 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,
         }
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index e1e6b93abf3..841d967d934 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -14,10 +14,10 @@ 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_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic};
@@ -359,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) => {
@@ -3914,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 a8208e4717b..9405b58ab3b 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2960,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) => {
@@ -2977,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/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/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_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index b62d94d65f1..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::{
@@ -696,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 {
@@ -915,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> {
@@ -959,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
@@ -1129,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/stability.rs b/compiler/rustc_passes/src/stability.rs
index 6dec96f9f50..d7baad69c78 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -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;
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 127dcd825da..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);
 }
 
@@ -140,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(
@@ -407,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.
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_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 1b01efda2a9..56b3fe2ab4c 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -237,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`.
@@ -1425,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();
+        }
     }
 }
 
@@ -1700,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;
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index cd5e2c4173e..5ed8cc17886 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."),
@@ -2187,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],
@@ -2553,6 +2557,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_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index ad38ea228bf..30e9b2e72f7 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -147,6 +147,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_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index aa1921fc8e7..322e86147c1 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -822,6 +822,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/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index aa0eac628dd..8309809d7b5 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -890,3 +890,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_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index bc853fe9079..31847ae3b46 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -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,
@@ -2040,6 +2049,7 @@ symbols! {
         sub_assign,
         sub_with_overflow,
         suggestion,
+        super_let,
         supertrait_item_shadowing,
         surface_async_drop_in_place,
         sym,
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/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index 66c85146c29..fd0e47b55aa 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -115,7 +115,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.
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..98db0af30c2 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -81,7 +81,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 +2406,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 +2700,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 +2804,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 +3070,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 +3098,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 +3516,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/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_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/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 73ae5177c48..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);
         }
@@ -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
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 efee6e2aa1d..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());
                 }
             }
         }
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 f2725411e13..e0b425fa739 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -195,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/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 d15c9afef3a..cf6d2bc151f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -692,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(..) => {
@@ -705,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, ..)
@@ -805,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);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 0679dbf1296..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
@@ -2299,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),
 
@@ -2308,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/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs
index e82c957c34e..46154da36ca 100644
--- a/compiler/stable_mir/src/compiler_interface.rs
+++ b/compiler/stable_mir/src/compiler_interface.rs
@@ -18,8 +18,8 @@ use crate::ty::{
     TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
 };
 use crate::{
-    Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind,
-    Symbol, TraitDecls, mir,
+    AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls,
+    ItemKind, Symbol, TraitDecls, mir,
 };
 
 /// This trait defines the interface between stable_mir and the Rust compiler.
@@ -251,6 +251,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/stable_mir/src/crate_def.rs
index 2577c281ca4..75228135e4c 100644
--- a/compiler/stable_mir/src/crate_def.rs
+++ b/compiler/stable_mir/src/crate_def.rs
@@ -4,7 +4,7 @@
 use serde::Serialize;
 
 use crate::ty::{GenericArgs, Span, Ty};
-use crate::{Crate, Symbol, with};
+use crate::{AssocItems, Crate, Symbol, with};
 
 /// A unique identification number for each item accessible for the current compilation unit.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
@@ -103,6 +103,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 +166,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/lib.rs b/compiler/stable_mir/src/lib.rs
index 70d42dfbfcb..df90d3e5a08 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -23,11 +23,11 @@ use std::{fmt, io};
 use serde::Serialize;
 
 use crate::compiler_interface::with;
-pub use crate::crate_def::{CrateDef, CrateDefType, DefId};
+pub use crate::crate_def::{CrateDef, CrateDefItems, 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};
+use crate::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
 
 pub mod abi;
 #[macro_use]
@@ -71,6 +71,9 @@ 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 {
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index 8278afb7a2f..65d9f20f0a3 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -9,7 +9,7 @@ use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, Ter
 use crate::mir::{
     Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
 };
-use crate::ty::{AdtKind, IndexedVal, MirConst, Ty, TyConst};
+use crate::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst};
 use crate::{Body, CrateDef, Mutability, with};
 
 impl Display for Ty {
@@ -18,6 +18,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/ty.rs b/compiler/stable_mir/src/ty.rs
index b857a735b72..25ec4a440d6 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -6,7 +6,7 @@ use serde::Serialize;
 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::crate_def::{CrateDef, CrateDefItems, CrateDefType};
 use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
 use crate::mir::mono::StaticDef;
 use crate::target::MachineInfo;
@@ -910,6 +910,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 +936,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 +1563,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/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/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/cell.rs b/library/core/src/cell.rs
index e789601a409..09117e4968d 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -544,7 +544,7 @@ impl<T: Copy> Cell<T> {
         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));
     }
 }
 
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/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 ba4c849837e..369bf18c2b9 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1313,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/slice/iter.rs b/library/core/src/slice/iter.rs
index a687ed7129d..d48248749c2 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 }
     }
 }
@@ -1487,7 +1487,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 }
     }
 }
@@ -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
@@ -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 }
     }
 }
@@ -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
     }
 }
@@ -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 5bb7243c449..e54840c8fcc 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/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/lib.rs b/library/std/src/lib.rs
index 9dcedaa13f6..5c381181218 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -341,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/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/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs
index 1ff13154b7b..b7ce6fcdc05 100644
--- a/library/std/src/sys/thread_local/mod.rs
+++ b/library/std/src/sys/thread_local/mod.rs
@@ -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/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/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 6cb0b19d763..605f54d1d7f 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -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/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/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-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..26ff17e423b 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -501,7 +501,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 +533,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 1190c2646af..407862d48af 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -335,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:
@@ -448,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 e1ba27c07da..9bb64adfa78 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -103,7 +103,6 @@
     - [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md)
     - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
     - [solaris](platform-support/solaris.md)
-    - [\*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
     - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
     - [\*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
     - [\*-unknown-hermit](platform-support/hermit.md)
@@ -122,6 +121,8 @@
     - [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)
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/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/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/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/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/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 91a58fab86e..0d2e19e019f 100644
--- a/src/librustdoc/html/static/js/rustdoc.d.ts
+++ b/src/librustdoc/html/static/js/rustdoc.d.ts
@@ -30,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),
         /**
@@ -78,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. */
@@ -477,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/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/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/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/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/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
index 243c99a19ce..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)]
@@ -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/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/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/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_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/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/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index 08fcd17e555..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);
             },
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/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/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/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 8dc28fa3077..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> {
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 065d48119a2..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()),
     }
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/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 f654bd9c90b..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;
@@ -1355,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;
@@ -1387,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());
@@ -1431,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 4d90f152ee2..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]
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/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/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/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index fd22ff6c8bc..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;
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/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 65120770edd..be6b483bfff 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -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/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/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/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/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/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/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index 3a3453b22b4..9430465a286 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -16,12 +16,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 +95,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 +174,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 +199,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/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map
index 3bd4e7d2a36..47e2922a805 100644
--- a/tests/coverage/issue-84561.cov-map
+++ b/tests/coverage/issue-84561.cov-map
@@ -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, 0f, 05, 04, 09, 01, 0f, 09, 02, 05, 04, 0f, 0d, 05, 05, 00, 0f, 11, 01, 05, 00, 0f, 15, 01, 09, 01, 0f, 19, 02, 05, 00, 0f, 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, 02, 0f, 35, 06, 05, 00, 0f, 39, 04, 05, 00, 0f, 3d, 04, 09, 01, 0f, 41, 05, 08, 00, 0f, 45, 01, 09, 00, 13, 1a, 05, 09, 00, 13, 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, 00, 17, 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, 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(3)) at (prev + 5, 5) to (start + 0, 15)
-- Code(Counter(4)) at (prev + 1, 5) to (start + 0, 15)
-- Code(Counter(5)) at (prev + 1, 9) to (start + 1, 15)
-- Code(Counter(6)) at (prev + 2, 5) to (start + 0, 15)
-- 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(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 + 2, 15)
-    = (c8 - (c9 + c11))
-- Code(Counter(13)) at (prev + 6, 5) to (start + 0, 15)
-- Code(Counter(14)) at (prev + 4, 5) to (start + 0, 15)
-- Code(Counter(15)) at (prev + 4, 9) to (start + 1, 15)
-- Code(Counter(16)) at (prev + 5, 8) to (start + 0, 15)
-- Code(Counter(17)) at (prev + 1, 9) to (start + 0, 19)
-- Code(Expression(6, Sub)) at (prev + 5, 9) to (start + 0, 19)
-    = (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 + 0, 23)
-- 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/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/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/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/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/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/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/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-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/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/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/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/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/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/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/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/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/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/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/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/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/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/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-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/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/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/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/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/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-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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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-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-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/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/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/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/stability.rs b/tests/ui/print-request/stability.rs
index 0ec0886e941..54142ce78ce 100644
--- a/tests/ui/print-request/stability.rs
+++ b/tests/ui/print-request/stability.rs
@@ -16,23 +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
-//@[crate_root_lint_levels] error-pattern: the `-Z unstable-options` flag must also be passed
 
 //@ 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
@@ -109,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/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/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/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/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-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/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/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/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/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/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/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/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/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/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 88a9d07c94c..a242d11129f 100644
--- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
@@ -9,4 +9,4 @@
 #![feature(rustc_attrs)]
 
 #[rustc_delayed_bug_from_inside_query]
-fn main() {}
+fn main() {} //~ ERROR delayed bug triggered by #[rustc_delayed_bug_from_inside_query]
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-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-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/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/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/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/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 db6109a671d..c2a0ea3068f 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1125,6 +1125,7 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
     "jyn514",
     "saethlin",
+    "Noratrieb",
 ]
 
 [[assign.warn_non_default_branch.exceptions]]
@@ -1190,8 +1191,8 @@ docs = [
     "@ehuss",
     "@GuillaumeGomez",
 ]
-
 codegen = [
+    "@dianqk",
     "@saethlin",
     "@workingjubilee",
 ]
@@ -1277,11 +1278,13 @@ project-stable-mir = [
     "@oli-obk",
     "@scottmcm",
 ]
-
 project-exploit-mitigations = [
     "@cuviper",
     "@rcvalle",
 ]
+compiletest = [
+    "@jieyouxu",
+]
 
 [assign.owners]
 "/.github/workflows" =                                   ["infra-ci"]